diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 21053bcc0f132..54d76b53cb6d6 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,6 +1,20 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.192.0/containers/dotnet/.devcontainer/base.Dockerfile -FROM mcr.microsoft.com/vscode/devcontainers/dotnet:8.0 +FROM mcr.microsoft.com/dotnet/sdk:8.0 + +ARG DOTNET_SDK_INSTALL_URL=https://dot.net/v1/dotnet-install.sh +# Install the correct Roslyn SDK into the same directory that the base image installs the SDK in. +ENV DOTNET_INSTALL_DIR=/usr/share/dotnet + +# Copy the global.json file so its available in the image before the repo is cloned +COPY global.json /tmp/ + +RUN cd /tmp \ + && curl --location --output dotnet-install.sh "${DOTNET_SDK_INSTALL_URL}" \ + && chmod +x dotnet-install.sh \ + && mkdir -p "${DOTNET_INSTALL_DIR}" \ + && ./dotnet-install.sh --jsonfile "./global.json" --install-dir "${DOTNET_INSTALL_DIR}" \ + && rm dotnet-install.sh # Set up machine requirements to build the repo RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ac4ec54913ec3..bfb8b63320b76 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,9 +1,11 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: // https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/dotnetcore { - "name": "C# (.NET 8)", + "name": "C# (.NET 9)", "build": { "dockerfile": "Dockerfile", + // Set the context to the workspace folder to allow us to copy files from it. + "context": ".." }, "customizations": { "vscode": { diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 68ba3a1d4e3e2..a242503d9cf6f 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -10,3 +10,9 @@ de42965cf9b64d71bccc549dd9940210cda5abf1 3f632c70e8e28a5ede881784600d0f3d06d3138d 27b50978f636ac0588ea7c19664fac4502e964a7 f125c2664d3bffb59536f4d3dfee7fa5323c7721 +# Converting to file scoped namespaces on 5/22/2024. https://github.com/dotnet/roslyn/pull/73634 +42e80231c1351d8b90d425446e8b9e8a50c1e1b6 +32e21b64138876a065081ab4bbe15b1fbea12316 +8ab847ca4cbe30baeb0e5d1cbd68ba40385b01ae +077012c5bc43649fc705698859143226e48686cf + diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 5352feb5461e7..7bdba491ceb3f 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -15,7 +15,7 @@ A minimal repro, with source-code provided, is ideal. Using [sharplab](https:// **Diagnostic Id**: -If this is a report about a bug in an analyzer, please include the diagnostic if possible (e.g. `"IDE0030"`). +If this is a report about a bug in an analyzer, please include the diagnostic ID and message if possible (e.g. `"IDE0030: Use coalesce expression"`). **Expected Behavior**: diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f85f5cc650b82..73dd695a2e492 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -67,6 +67,19 @@ "problemMatcher": "$msCompile", "group": "build" }, + { + "label": "build Roslyn.sln", + "command": "dotnet", + "type": "shell", + "args": [ + "build", + "-p:RunAnalyzersDuringBuild=false", + "-p:GenerateFullPaths=true", + "Roslyn.sln" + ], + "problemMatcher": "$msCompile", + "group": "build" + }, { "label": "build current project", "type": "shell", @@ -123,6 +136,30 @@ }, "problemMatcher": "$msCompile", "group": "build" + }, + { + "label": "build language server", + "command": "dotnet", + "type": "shell", + "args": [ + "build", + "-c", + "Debug", + "src/Features/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/Microsoft.CodeAnalysis.LanguageServer.csproj" + ], + "problemMatcher": "$msCompile", + "group": "build" + }, + { + "label": "launch vscode with language server", + "command": "${execPath}", + "type": "process", + "options": { + "env": { + "DOTNET_ROSLYN_SERVER_PATH": "${workspaceRoot}/artifacts/bin/Microsoft.CodeAnalysis.LanguageServer/Debug/net8.0/Microsoft.CodeAnalysis.LanguageServer.dll" + } + }, + "dependsOn": [ "build language server" ] } ] } diff --git a/Roslyn.sln b/Roslyn.sln index 848adc0f76206..894a41eefa9df 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -1698,6 +1698,8 @@ Global src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.projitems*{abdbac1e-350e-4dc3-bb45-3504404545ee}*SharedItemsImports = 5 src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.projitems*{ace53515-482c-4c6a-e2d2-4242a687dfee}*SharedItemsImports = 5 src\Compilers\CSharp\csc\CscCommandLine.projitems*{b021ccbc-b2af-4560-af28-ed055f0ed696}*SharedItemsImports = 13 + src\Dependencies\Collections\Microsoft.CodeAnalysis.Collections.projitems*{b1481d94-682e-46ec-adbe-a16eb46feee9}*SharedItemsImports = 5 + src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{b1481d94-682e-46ec-adbe-a16eb46feee9}*SharedItemsImports = 5 src\Compilers\CSharp\CSharpAnalyzerDriver\CSharpAnalyzerDriver.projitems*{b501a547-c911-4a05-ac6e-274a50dff30e}*SharedItemsImports = 5 src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.projitems*{bb3ca047-5d00-48d4-b7d3-233c1265c065}*SharedItemsImports = 13 src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{bf9dac1e-3a5e-4dc3-bb44-9a64e0d4e9d4}*SharedItemsImports = 5 diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 5f681633869f5..731a818a6f6c7 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -58,6 +58,7 @@ variables: - name: ArtifactServices.Drop.PAT value: $(dn-bot-devdiv-drop-rw-code-rw) - group: DotNet-Roslyn-Insertion-Variables + - group: AzureDevOps-Artifact-Feeds-Pats - name: BuildConfiguration value: release @@ -149,6 +150,7 @@ extends: dropFolder: 'artifacts\VSSetup\$(BuildConfiguration)\Insertion' dropName: $(VisualStudio.DropName) accessToken: $(_DevDivDropAccessToken) + dropRetentionDays: 90 # Publish insertion packages to CoreXT store. - output: nuget diff --git a/azure-pipelines-pr-validation.yml b/azure-pipelines-pr-validation.yml index d918f22289781..b47158c36063d 100644 --- a/azure-pipelines-pr-validation.yml +++ b/azure-pipelines-pr-validation.yml @@ -1,12 +1,12 @@ -resources: -- repo: self - clean: true +trigger: none +pr: none -# Variables defined in yml cannot be overridden at queue time instead overrideable variables must be defined in the web gui. -# Commenting out until AzDO supports something like the runtime parameters outlined here: https://github.com/Microsoft/azure-pipelines-yaml/pull/129 -#variables: -# SignType: test -# IbcDrop: 'default' +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release parameters: - name: PRNumber @@ -34,6 +34,10 @@ variables: value: .NETCoreValidation - group: DotNet-Roslyn-SDLValidation-Params - group: DotNet-Roslyn-Insertion-Variables + - name: Codeql.Enabled + value: false + - name: Codeql.SkipTaskAutoInjection + value: true # To retrieve OptProf data we need to authenticate to the VS drop storage. # If the pipeline is running in DevDiv, the account has access to the VS drop storage. @@ -42,238 +46,299 @@ variables: - name: _DevDivDropAccessToken value: $(System.AccessToken) - - name: Codeql.Enabled - value: false - - name: Codeql.SkipTaskAutoInjection - value: true - -stages: -- stage: build - displayName: Build and Test - - jobs: - - - job: PRValidationBuild - displayName: PR Validation Build - timeoutInMinutes: 360 - # Conditionally set build pool so we can share this YAML when building with different pipeline +extends: + template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + sdl: + enableAllTools: false pool: name: VSEngSS-MicroBuild2022-1ES demands: - msbuild - visualstudio - DotNetFramework - - steps: - - powershell: Write-Host "##vso[task.setvariable variable=SourceBranchName]$('$(Build.SourceBranch)'.Substring('refs/heads/'.Length))" - displayName: Setting SourceBranchName variable - condition: succeeded() - - - task: Powershell@2 - displayName: Tag PR validation build - inputs: - targetType: inline - script: | - Write-Host "##vso[build.addBuildTag]OfficialBuild" - Write-Host "##vso[build.addBuildTag]${{ parameters.CommitSHA }}" - Write-Host "##vso[build.addBuildTag]PRNumber${{ parameters.PRNumber }}" - condition: succeeded() - - - task: PowerShell@2 - displayName: Setup branch for insertion validation - inputs: - filePath: 'eng\setup-pr-validation.ps1' - arguments: '-sourceBranchName $(SourceBranchName) -prNumber ${{ parameters.PRNumber }} -commitSHA ${{ parameters.CommitSHA }}' - condition: succeeded() - - - powershell: Write-Host "##vso[task.setvariable variable=VisualStudio.DropName]Products/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(Build.BuildNumber)" - displayName: Setting VisualStudio.DropName variable - - - task: NuGetToolInstaller@0 - inputs: - versionSpec: '4.9.2' - - # Authenticate with service connections to be able to publish packages to external nuget feeds. - - task: NuGetAuthenticate@1 - inputs: - nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk - - # Needed because the build fails the NuGet Tools restore without it - - task: UseDotNet@2 - displayName: 'Use .NET Core sdk' - inputs: - packageType: sdk - useGlobalJson: true - workingDirectory: '$(Build.SourcesDirectory)' - - # Needed to restore the Microsoft.DevDiv.Optimization.Data.PowerShell package - - task: NuGetCommand@2 - displayName: Restore internal tools - inputs: - command: restore - feedsToUse: config - restoreSolution: 'eng\common\internal\Tools.csproj' - nugetConfigPath: 'NuGet.config' - restoreDirectory: '$(Build.SourcesDirectory)\.packages' - - - task: MicroBuildSigningPlugin@4 - inputs: - signType: $(SignType) - zipSources: false - condition: and(succeeded(), in(variables['SignType'], 'test', 'real')) - - - task: PowerShell@2 - displayName: Build - inputs: - filePath: eng/build.ps1 - arguments: -ci - -prepareMachine - -restore - -build - -pack - -sign - -publish - -bootstrap - -binaryLog - -configuration $(BuildConfiguration) - -officialBuildId $(Build.BuildNumber) - -officialSkipTests $(SkipTests) - -officialSkipApplyOptimizationData $(SkipApplyOptimizationData) - -officialSourceBranchName $(SourceBranchName) - -officialIbcDrop $(IbcDrop) - -officialVisualStudioDropAccessToken $(_DevDivDropAccessToken) - /p:RepositoryName=$(Build.Repository.Name) - /p:VisualStudioDropName=$(VisualStudio.DropName) - /p:DotNetSignType=$(SignType) - /p:DotNetPublishToBlobFeed=false - /p:PublishToSymbolServer=false - /p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat) - /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat) - /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory) - /p:DotnetPublishUsingPipelines=false - /p:IgnoreIbcMergeErrors=true - /p:PreReleaseVersionLabel=pr-validation - /p:IgnoreIbcMergeErrors=true - condition: succeeded() - - - template: eng\common\templates\steps\generate-sbom.yml - - - task: PowerShell@2 - displayName: Publish Assets - inputs: - filePath: 'eng\publish-assets.ps1' - arguments: '-configuration $(BuildConfiguration) -branchName "$(SourceBranchName)" -prValidation' - condition: succeeded() - - # Publish OptProf configuration files - - task: ms-vscs-artifact.build-tasks.artifactDropTask-1.artifactDropTask@0 - inputs: - dropServiceURI: 'https://devdiv.artifacts.visualstudio.com' - buildNumber: 'ProfilingInputs/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(Build.BuildNumber)' - sourcePath: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data' - toLowerCase: false - usePat: true - AccessToken: $(_DevDivDropAccessToken) - retentionDays: 90 - displayName: 'OptProf - Publish to Artifact Services - ProfilingInputs' - condition: succeeded() - - # Publish OptProf generated JSON files as a build artifact. This allows for easy inspection from - # a build execution. - - task: PublishBuildArtifacts@1 - displayName: Publish OptProf Data Files - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data' - ArtifactName: 'OptProf Data Files' - condition: succeeded() - - - task: PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)' - ArtifactName: 'Build Diagnostic Files' - publishLocation: Container - continueOnError: true - condition: succeededOrFailed() - - - task: PublishBuildArtifacts@1 - displayName: Publish Ngen Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)\ngen' - ArtifactName: 'NGen Logs' - publishLocation: Container - continueOnError: true - condition: succeeded() - - - task: PublishTestResults@2 - displayName: Publish xUnit Test Results - inputs: - testRunner: XUnit - testResultsFiles: '$(Build.SourcesDirectory)\artifacts\TestResults\$(BuildConfiguration)\*.xml' - mergeTestResults: true - testRunTitle: 'Unit Tests' - condition: and(succeededOrFailed(), ne(variables['SkipTests'], 'true')) - - # Publishes setup VSIXes to a drop. - # Note: The insertion tool looks for the display name of this task in the logs. - - task: ms-vseng.MicroBuildTasks.4305a8de-ba66-4d8b-b2d1-0dc4ecbbf5e8.MicroBuildUploadVstsDropFolder@1 - displayName: Upload VSTS Drop - inputs: - DropName: $(VisualStudio.DropName) - DropFolder: 'artifacts\VSSetup\$(BuildConfiguration)\Insertion' - AccessToken: $(_DevDivDropAccessToken) - condition: succeeded() - - # Publish insertion packages to CoreXT store. - - task: NuGetCommand@2 - displayName: Publish CoreXT Packages - inputs: - command: push - packagesToPush: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\DevDivPackages\**\*.nupkg' - allowPackageConflicts: true - feedsToUse: config - publishVstsFeed: '97a41293-2972-4f48-8c0e-05493ae82010' - condition: succeeded() - - # Publish an artifact that the RoslynInsertionTool is able to find by its name. - - task: PublishBuildArtifacts@1 - displayName: Publish Artifact VSSetup - inputs: - PathtoPublish: 'artifacts\VSSetup\$(BuildConfiguration)' - ArtifactName: 'VSSetup' - condition: succeeded() - - - task: ms-vseng.MicroBuildTasks.521a94ea-9e68-468a-8167-6dcf361ea776.MicroBuildCleanup@1 - displayName: Perform Cleanup Tasks - condition: succeededOrFailed() - -- stage: insert - displayName: Create Insertion - dependsOn: - - build - - jobs: - - job: insert - displayName: Insert to VS - pool: - vmImage: windows-2019 - steps: - - powershell: Write-Host "##vso[task.setvariable variable=SourceBranchName]$('$(Build.SourceBranch)'.Substring('refs/heads/'.Length))" - displayName: Setting SourceBranchName variable - condition: succeeded() - - - template: eng/pipelines/insert.yml + customBuildTags: + - ES365AIMigrationTooling + stages: + + - stage: build + displayName: Build and Test + + jobs: + - job: PRValidationBuild + displayName: PR Validation Build + timeoutInMinutes: 360 + templateContext: + outputs: + + # Publish OptProf configuration files to the artifact service + - output: artifactsDrop + displayName: 'OptProf - Publish to Artifact Services - ProfilingInputs' + condition: succeeded() + dropServiceURI: 'https://devdiv.artifacts.visualstudio.com' + buildNumber: 'ProfilingInputs/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(OriginalBuildNumber)' + sourcePath: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data' + toLowerCase: false + usePat: true + accessToken: $(_DevDivDropAccessToken) + retentionDays: 90 + + # Publish OptProf generated JSON files as a pipeline artifact. This allows for easy inspection from + # a build execution. + - output: pipelineArtifact + displayName: 'Publish OptProf Data Files' + condition: succeeded() + targetPath: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data' + artifactName: 'OptProf Data Files' + + - output: pipelineArtifact + displayName: 'Publish Logs' + condition: succeededOrFailed() + targetPath: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)' + artifactName: 'Build Diagnostic Files' + publishLocation: Container + + - output: pipelineArtifact + displayName: 'Publish Ngen Logs' + condition: succeeded() + targetPath: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)\ngen' + artifactName: 'NGen Logs' + publishLocation: Container + + # Publishes setup VSIXes to a drop. + # Note: The insertion tool looks for the display name of this task in the logs. + - output: microBuildVstsDrop + displayName: Upload VSTS Drop + condition: succeeded() + dropFolder: 'artifacts\VSSetup\$(BuildConfiguration)\Insertion' + dropName: $(VisualStudio.DropName) + accessToken: $(_DevDivDropAccessToken) + dropRetentionDays: 90 + + # Publish insertion packages to CoreXT store. + - output: nuget + displayName: 'Publish CoreXT Packages' + condition: succeeded() + packageParentPath: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\DevDivPackages' + packagesToPush: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\DevDivPackages\**\*.nupkg' + allowPackageConflicts: true + nuGetFeedType: internal + publishVstsFeed: '97a41293-2972-4f48-8c0e-05493ae82010' + + # Publish an artifact that the RoslynInsertionTool is able to find by its name. + - output: pipelineArtifact + displayName: 'Publish Artifact VSSetup' + condition: succeeded() + targetPath: 'artifacts\VSSetup\$(BuildConfiguration)' + artifactName: 'VSSetup' + + # Publish our NuPkgs as an artifact. The name of this artifact must be PackageArtifacts as the + # arcade templates depend on the name. + - output: buildArtifacts + displayName: 'Publish Artifact Packages' + condition: succeeded() + PathtoPublish: 'artifacts\packages\$(BuildConfiguration)' + ArtifactName: 'PackageArtifacts' + + # Publish Asset Manifests for Build Asset Registry job + - output: buildArtifacts + displayName: 'Publish Asset Manifests' + condition: succeeded() + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(BuildConfiguration)/AssetManifest' + ArtifactName: AssetManifests + + steps: + - powershell: Write-Host "##vso[task.setvariable variable=OriginalBuildNumber;isreadonly=true]$('$(Build.BuildNumber)')" + displayName: Setting OriginalBuildNumber variable + condition: succeeded() + + - powershell: Write-Host "##vso[task.setvariable variable=SourceBranchName;isreadonly=true]$('$(Build.SourceBranch)'.Substring('refs/heads/'.Length))" + displayName: Setting SourceBranchName variable + condition: succeeded() + + - task: Powershell@2 + name: FancyBuild + displayName: Setting FancyBuild.BuildNumber + inputs: + targetType: inline + script: | + $pull_request = Invoke-RestMethod -Uri "https://api.github.com/repos/dotnet/roslyn/pulls/${{ parameters.PRNumber }}" ` + -Headers @{ + "Accept" = "application/vnd.github+json"; + "X-GitHub-Api-Version" = "2022-11-28" + } + $buildNumberName = "$(OriginalBuildNumber) - $($pull_request.user.login) - '$($pull_request.title)'" + $buildNumberName = $buildNumberName -replace '["/:<>\|?@*]','_' + # Maximum buildnumber length is 255 chars and we are going to append to the end to ensure we have space. + if ($buildNumberName.Length -GT 253) { + $buildNumberName = $buildNumberName.Substring(0, 253) + } + # Avoid ever ending the BuildNumber with a `.` by always appending to it. + $buildNumberName += ' #' + Write-Host "##vso[task.setvariable variable=BuildNumber;isoutput=true;isreadonly=true]$buildNumberName" + Write-Host "##vso[build.updatebuildnumber]$buildNumberName" + + - task: Powershell@2 + displayName: Tag PR validation build + inputs: + targetType: inline + script: | + Write-Host "##vso[build.addBuildTag]OfficialBuild" + Write-Host "##vso[build.addBuildTag]${{ parameters.CommitSHA }}" + Write-Host "##vso[build.addBuildTag]PRNumber${{ parameters.PRNumber }}" + condition: succeeded() + + - task: PowerShell@2 + displayName: Setup branch for insertion validation + inputs: + filePath: 'eng\setup-pr-validation.ps1' + arguments: '-sourceBranchName $(SourceBranchName) -prNumber ${{ parameters.PRNumber }} -commitSHA ${{ parameters.CommitSHA }}' + condition: succeeded() + + - powershell: Write-Host "##vso[task.setvariable variable=VisualStudio.DropName]Products/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(OriginalBuildNumber)" + displayName: Setting VisualStudio.DropName variable + + - task: NuGetToolInstaller@0 + inputs: + versionSpec: '4.9.2' + + # Authenticate with service connections to be able to publish packages to external nuget feeds. + - task: NuGetAuthenticate@1 + inputs: + nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk + + # Needed because the build fails the NuGet Tools restore without it + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + packageType: sdk + useGlobalJson: true + workingDirectory: '$(Build.SourcesDirectory)' + + # Needed to restore the Microsoft.DevDiv.Optimization.Data.PowerShell package + - task: NuGetCommand@2 + displayName: Restore internal tools + inputs: + command: restore + feedsToUse: config + restoreSolution: 'eng\common\internal\Tools.csproj' + nugetConfigPath: 'NuGet.config' + restoreDirectory: '$(Build.SourcesDirectory)\.packages' + + - task: MicroBuildSigningPlugin@4 + inputs: + signType: $(SignType) + zipSources: false + condition: and(succeeded(), in(variables['SignType'], 'test', 'real')) + + - task: PowerShell@2 + displayName: Build + inputs: + filePath: eng/build.ps1 + arguments: -ci + -prepareMachine + -restore + -build + -pack + -sign + -publish + -binaryLog + -configuration $(BuildConfiguration) + -officialBuildId $(OriginalBuildNumber) + -officialSkipTests $(SkipTests) + -officialSkipApplyOptimizationData $(SkipApplyOptimizationData) + -officialSourceBranchName $(SourceBranchName) + -officialIbcDrop $(IbcDrop) + -officialVisualStudioDropAccessToken $(_DevDivDropAccessToken) + /p:RepositoryName=$(Build.Repository.Name) + /p:VisualStudioDropName=$(VisualStudio.DropName) + /p:DotNetSignType=$(SignType) + /p:PublishToSymbolServer=true + /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory) + /p:DotnetPublishUsingPipelines=true + /p:IgnoreIbcMergeErrors=true + /p:GenerateSbom=true + /p:PreReleaseVersionLabel=pr-validation + condition: succeeded() + + - template: /eng/common/templates-official/steps/generate-sbom.yml@self + + - task: PowerShell@2 + displayName: Publish Assets + inputs: + filePath: 'eng\publish-assets.ps1' + arguments: '-configuration $(BuildConfiguration) -branchName "$(SourceBranchName)" -prValidation' + condition: succeeded() + + - task: PublishTestResults@2 + displayName: Publish xUnit Test Results + inputs: + testRunner: XUnit + testResultsFiles: '$(Build.SourcesDirectory)\artifacts\TestResults\$(BuildConfiguration)\*.xml' + mergeTestResults: true + testRunTitle: 'Unit Tests' + condition: and(succeededOrFailed(), ne(variables['SkipTests'], 'true')) + + # We need to reset the BuildNumber before we pass off to Arcade + - powershell: Write-Host "##vso[build.updatebuildnumber]$(OriginalBuildNumber)" + displayName: Reset BuildNumber + condition: succeeded() + + # Publish to Build Asset Registry + - template: /eng/common/templates-official/job/publish-build-assets.yml@self + parameters: + publishUsingPipelines: true + dependsOn: + - PRValidationBuild + pool: + name: VSEngSS-MicroBuild2022-1ES + + - stage: insert + dependsOn: + - build + - publish_using_darc + displayName: Insert to VS + + jobs: + - job: insert + variables: + FancyBuildNumber: $[stageDependencies.build.PRValidationBuild.outputs['FancyBuild.BuildNumber']] + displayName: Insert to VS + pool: + name: VSEngSS-MicroBuild2022-1ES + steps: + - download: current + artifact: VSSetup + - powershell: | + $branchName = "$(Build.SourceBranch)".Substring("refs/heads/".Length) + Write-Host "##vso[task.setvariable variable=ComponentBranchName]$branchName" + displayName: Get Branch Name + - template: /eng/pipelines/insert.yml@self + parameters: + createDraftPR: true + autoComplete: false + insertToolset: ${{ parameters.InsertToolset }} + buildUserName: "dn-bot@microsoft.com" + buildPassword: $(dn-bot-devdiv-build-e-code-full-release-e-packaging-r) + componentUserName: "dn-bot@microsoft.com" + componentPassword: $(dn-bot-dnceng-build-e-code-full-release-e-packaging-r) + vsBranchName: ${{ parameters.VisualStudioBranchName }} + titlePrefix: ${{ parameters.OptionalTitlePrefix }} + sourceBranch: $(ComponentBranchName) + publishDataURI: "https://raw.githubusercontent.com/dotnet/roslyn/main/eng/config/PublishData.json" + queueSpeedometerValidation: true + dropPath: '$(Pipeline.Workspace)\VSSetup' + # Arcade is done so we can set BuildNumber back + - powershell: Write-Host "##vso[build.updatebuildnumber]$(FancyBuildNumber)" + displayName: Reset BuildNumber + condition: succeeded() + + # Use post-build to publish symbol packages. + - template: /eng/common/templates-official/post-build/post-build.yml@self parameters: - createDraftPR: true - autoComplete: false - insertToolset: ${{ parameters.InsertToolset }} - buildUserName: "dn-bot@microsoft.com" - buildPassword: $(dn-bot-devdiv-build-e-code-full-release-e-packaging-r) - componentUserName: "dn-bot@microsoft.com" - componentPassword: $(dn-bot-dnceng-build-e-code-full-release-e-packaging-r) - vsBranchName: ${{ parameters.VisualStudioBranchName }} - titlePrefix: ${{ parameters.OptionalTitlePrefix }} - sourceBranch: $(SourceBranchName) - publishDataURI: "https://raw.githubusercontent.com/dotnet/roslyn/main/eng/config/PublishData.json" - queueSpeedometerValidation: true - + publishingInfraVersion: 3 + # Symbol validation is not entirely reliable as of yet, so should be turned off until + # https://github.com/dotnet/arcade/issues/2871 is resolved. + enableSymbolValidation: false + enableSourceLinkValidation: false + SDLValidationParameters: false diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7ea4ad03c07e3..177845e3afeb1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -388,9 +388,22 @@ stages: - powershell: eng/build.ps1 -configuration Release -prepareMachine -ci -restore -binaryLogName Restore.binlog displayName: Restore - - powershell: eng/build.ps1 -configuration Release -prepareMachine -ci -build -pack -publish -sign -binaryLogName Build.binlog + - powershell: eng/build.ps1 -configuration Release -prepareMachine -ci -build -pack -publish -sign -binaryLogName Build.binlog /p:DotnetPublishUsingPipelines=true displayName: Build + - task: PowerShell@2 + displayName: Publish Symbols Dry-Run + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishToSymbolServers /p:DryRun="true" -restore -msbuildEngine dotnet + /p:DotNetSymbolServerTokenMsdl=DryRunPTA + /p:DotNetSymbolServerTokenSymWeb=DryRunPTA + /p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/' + /p:BlobBasePath='$(Build.SourcesDirectory)/artifacts/tmp/Release/SymbolPackages/' + /p:SymbolPublishingExclusionsFile='$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' + /p:Configuration=Release + /p:PublishToMSDL=false + - script: $(Build.SourcesDirectory)\artifacts\bin\BuildBoss\Release\net472\BuildBoss.exe -r "$(Build.SourcesDirectory)/" -c Release -p Roslyn.sln displayName: Validate Build Artifacts diff --git a/docs/Language Feature Status.md b/docs/Language Feature Status.md index 6a36d6df37b25..1f50d848e90ca 100644 --- a/docs/Language Feature Status.md +++ b/docs/Language Feature Status.md @@ -10,17 +10,18 @@ efforts behind them. | Feature | Branch | State | Developer | Reviewer | IDE Buddy | LDM Champ | | ------- | ------ | ----- | --------- | -------- | --------- | --------- | -| [Partial properties](https://github.com/dotnet/csharplang/issues/6420) | [partial-properties](https://github.com/dotnet/roslyn/tree/features/partial-properties) | [In Progress](https://github.com/dotnet/roslyn/issues/73090) | [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv), [333fred](https://github.com/333fred) | TBD | [333fred](https://github.com/333fred), [RikkiGibson](https://github.com/RikkiGibson) | -| Ref/unsafe in iterators/async | [RefInAsync](https://github.com/dotnet/roslyn/tree/features/RefInAsync) | [In Progress](https://github.com/dotnet/roslyn/issues/72662) | [jjonescz](https://github.com/jjonescz) | [AlekseyTs](https://github.com/AlekseyTs), [cston](https://github.com/cston) | [ToddGrun](https://github.com/ToddGrun) | | -| [Ref Struct Interfaces](https://github.com/dotnet/csharplang/issues/7608) | [RefStructInterfaces](https://github.com/dotnet/roslyn/tree/features/RefStructInterfaces) | [In Progress](https://github.com/dotnet/roslyn/issues/72124) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [jjonescz](https://github.com/jjonescz) | [ToddGrun](https://github.com/ToddGrun) | [agocke](https://github.com/agocke), [jaredpar](https://github.com/jaredpar) | -| [Semi-auto-properties](https://github.com/dotnet/csharplang/issues/140) | [semi-auto-props](https://github.com/dotnet/roslyn/tree/features/semi-auto-props) | [In Progress](https://github.com/dotnet/roslyn/issues/57012) | [Youssef1313](https://github.com/Youssef1313) | [333fred](https://github.com/333fred), [RikkiGibson](https://github.com/RikkiGibson) | | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | +| [First-class Span Types](https://github.com/dotnet/csharplang/issues/7905) | [FirstClassSpan](https://github.com/dotnet/roslyn/tree/features/FirstClassSpan) | [In Progress](https://github.com/dotnet/roslyn/issues/73445) | [jjonescz](https://github.com/jjonescz) | [cston](https://github.com/cston), [333fred](https://github.com/333fred) | | [333fred](https://github.com/333fred), [stephentoub](https://github.com/stephentoub) | +| [Partial properties](https://github.com/dotnet/csharplang/issues/6420) | [partial-properties](https://github.com/dotnet/roslyn/tree/features/partial-properties) | [In Progress](https://github.com/dotnet/roslyn/issues/73090) | [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv), [333fred](https://github.com/333fred) | [Cosifne](https://github.com/Cosifne) | [333fred](https://github.com/333fred), [RikkiGibson](https://github.com/RikkiGibson) | +| [Semi-auto-properties](https://github.com/dotnet/csharplang/issues/140) | [semi-auto-props](https://github.com/dotnet/roslyn/tree/features/semi-auto-props) | [In Progress](https://github.com/dotnet/roslyn/issues/57012) | [Youssef1313](https://github.com/Youssef1313) | [333fred](https://github.com/333fred), [RikkiGibson](https://github.com/RikkiGibson) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | | [Default in deconstruction](https://github.com/dotnet/roslyn/pull/25562) | [decon-default](https://github.com/dotnet/roslyn/tree/features/decon-default) | [In Progress](https://github.com/dotnet/roslyn/issues/25559) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | | [jcouv](https://github.com/jcouv) | | [Roles/Extensions](https://github.com/dotnet/csharplang/issues/5497) | [roles](https://github.com/dotnet/roslyn/tree/features/roles) | [In Progress](https://github.com/dotnet/roslyn/issues/66722) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [jjonescz](https://github.com/jjonescz) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | [MadsTorgersen](https://github.com/MadsTorgersen) | -| [Escape character](https://github.com/dotnet/csharplang/issues/7400) | N/A | [Merged into 17.9p1](https://github.com/dotnet/roslyn/pull/70497) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | [jcouv](https://github.com/jcouv), [RikkiGibson](https://github.com/RikkiGibson) | | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | -| [Method group natural type improvements](https://github.com/dotnet/csharplang/blob/main/proposals/method-group-natural-type-improvements.md) | main | [Merged into 17.9p2](https://github.com/dotnet/roslyn/issues/69432) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [cston](https://github.com/cston) | | [jcouv](https://github.com/jcouv) | -| [`Lock` object](https://github.com/dotnet/csharplang/issues/7104) | [LockObject](https://github.com/dotnet/roslyn/tree/features/LockObject) | [Merged into 17.10p2](https://github.com/dotnet/roslyn/issues/71888) | [jjonescz](https://github.com/jjonescz) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | | [stephentoub](https://github.com/stephentoub) | -| Implicit indexer access in object initializers | main | [Merged into 17.9p3](https://github.com/dotnet/roslyn/pull/70649) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [cston](https://github.com/cston) | | | -| [Params-collections](https://github.com/dotnet/csharplang/issues/7700) | main | [Merged to 17.10p3](https://github.com/dotnet/roslyn/issues/71137) | [AlekseyTs](https://github.com/AlekseyTs) | [RikkiGibson](https://github.com/RikkiGibson), [333fred](https://github.com/333fred) | [akhera99](https://github.com/akhera99) | [MadsTorgersen](https://github.com/MadsTorgersen), [AlekseyTs](https://github.com/AlekseyTs) | +| [Escape character](https://github.com/dotnet/csharplang/issues/7400) | N/A | [Merged into 17.9p1](https://github.com/dotnet/roslyn/pull/70497) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | [jcouv](https://github.com/jcouv), [RikkiGibson](https://github.com/RikkiGibson) | (no IDE impact) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | +| [Method group natural type improvements](https://github.com/dotnet/csharplang/blob/main/proposals/method-group-natural-type-improvements.md) | main | [Merged into 17.9p2](https://github.com/dotnet/roslyn/issues/69432) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [cston](https://github.com/cston) | (no IDE impact) | [jcouv](https://github.com/jcouv) | +| [`Lock` object](https://github.com/dotnet/csharplang/issues/7104) | [LockObject](https://github.com/dotnet/roslyn/tree/features/LockObject) | [Merged into 17.10p2](https://github.com/dotnet/roslyn/issues/71888) | [jjonescz](https://github.com/jjonescz) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) (needs IDE fixer) | [stephentoub](https://github.com/stephentoub) | +| Implicit indexer access in object initializers | main | [Merged into 17.9p3](https://github.com/dotnet/roslyn/pull/70649) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [cston](https://github.com/cston) | (no IDE impact) | | +| [Params-collections](https://github.com/dotnet/csharplang/issues/7700) | main | [Merged to 17.10p3](https://github.com/dotnet/roslyn/issues/71137) | [AlekseyTs](https://github.com/AlekseyTs) | [RikkiGibson](https://github.com/RikkiGibson), [333fred](https://github.com/333fred) | [akhera99](https://github.com/akhera99) (needs IDE fixer) | [MadsTorgersen](https://github.com/MadsTorgersen), [AlekseyTs](https://github.com/AlekseyTs) | +| [Ref/unsafe in iterators/async](https://github.com/dotnet/csharplang/blob/main/proposals/ref-unsafe-in-iterators-async.md) | [RefInAsync](https://github.com/dotnet/roslyn/tree/features/RefInAsync) | [Merged into 17.11p2](https://github.com/dotnet/roslyn/issues/72662) | [jjonescz](https://github.com/jjonescz) | [AlekseyTs](https://github.com/AlekseyTs), [cston](https://github.com/cston) | (no IDE impact) | | +| [Ref Struct Interfaces](https://github.com/dotnet/csharplang/issues/7608) | [RefStructInterfaces](https://github.com/dotnet/roslyn/tree/features/RefStructInterfaces) | [Merged into 17.11p2](https://github.com/dotnet/roslyn/issues/72124) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [jjonescz](https://github.com/jjonescz) | [ToddGrun](https://github.com/ToddGrun) | [agocke](https://github.com/agocke), [jaredpar](https://github.com/jaredpar) | # C# 12.0 diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md index 76b8741267d6e..351e636ac80db 100644 --- a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md @@ -28,6 +28,34 @@ public class C } ``` +## Collection expression for type implementing `IEnumerable` must have elements implicitly convertible to `object` + +***Introduced in Visual Studio 2022 version 17.10*** + +*Conversion* of a collection expression to a `struct` or `class` that implements `System.Collections.IEnumerable` and *does not* have a strongly-typed `GetEnumerator()` +requires the elements in the collection expression are implicitly convertible to the `object`. +Previously, the elements of a collection expression targeting an `IEnumerable` implementation were assumed to be convertible to `object`, and converted only when binding to the applicable `Add` method. + +This additional requirement means that collection expression conversions to `IEnumerable` implementations are treated consistently with other target types where the elements in the collection expression must be implicitly convertible to the *iteration type* of the target type. + +This change affects collection expressions targeting `IEnumerable` implementations where the elements rely on target-typing to a strongly-typed `Add` method parameter type. +In the example below, an error is reported that `_ => { }` cannot be implicitly converted to `object`. +```csharp +class Actions : IEnumerable +{ + public void Add(Action action); + // ... +} + +Actions a = [_ => { }]; // error CS8917: The delegate type could not be inferred. +``` + +To resolve the error, the element expression could be explicitly typed. +```csharp +a = [(int _) => { }]; // ok +a = [(Action)(_ => { })]; // ok +``` + ## Collection expression target type must have constructor and `Add` method ***Introduced in Visual Studio 2022 version 17.10*** diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md new file mode 100644 index 0000000000000..0b9cd956cdf28 --- /dev/null +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 9.md @@ -0,0 +1,27 @@ +# This document lists known breaking changes in Roslyn after .NET 8 all the way to .NET 9. + +## Iterators introduce safe context in C# 13 and newer + +***Introduced in Visual Studio 2022 version 17.11*** + +Although the language spec states that iterators introduce a safe context, Roslyn does not implement that in C# 12 and lower. +This will change in C# 13 as part of [a feature which allows unsafe code in iterators](https://github.com/dotnet/roslyn/issues/72662). +The change does not break normal scenarios as it was disallowed to use unsafe constructs directly in iterators anyway. +However, it can break scenarios where an unsafe context was previously inherited into nested local functions, for example: + +```cs +unsafe class C // unsafe context +{ + System.Collections.Generic.IEnumerable M() // an iterator + { + yield return 1; + local(); + void local() + { + int* p = null; // allowed in C# 12; error in C# 13 + } + } +} +``` + +You can work around the break simply by adding the `unsafe` modifier to the local function. diff --git a/docs/compilers/CSharp/Warnversion Warning Waves.md b/docs/compilers/CSharp/Warnversion Warning Waves.md index 65d25e8b1b528..f80c80e658838 100644 --- a/docs/compilers/CSharp/Warnversion Warning Waves.md +++ b/docs/compilers/CSharp/Warnversion Warning Waves.md @@ -13,6 +13,14 @@ In a typical project, this setting is controlled by the `AnalysisLevel` property which determines the `WarningLevel` property (passed to the `Csc` task). For more information on `AnalysisLevel`, see https://devblogs.microsoft.com/dotnet/automatically-find-latent-bugs-in-your-code-with-net-5/ +## Warning level 9 + +The compiler shipped with .NET 9 (the C# 13 compiler) contains the following warnings which are reported only under `/warn:9` or higher. + +| Warning ID | Description | +|------------|-------------| +| CS9237 | ['yield return' should not be used in the body of a lock statement](https://github.com/dotnet/roslyn/issues/72443) | + ## Warning level 8 The compiler shipped with .NET 8 (the C# 12 compiler) contains the following warnings which are reported only under `/warn:8` or higher. diff --git a/docs/contributing/Building, Debugging, and Testing on Unix.md b/docs/contributing/Building, Debugging, and Testing on Unix.md index d71853057f74e..0690730630dd6 100644 --- a/docs/contributing/Building, Debugging, and Testing on Unix.md +++ b/docs/contributing/Building, Debugging, and Testing on Unix.md @@ -15,6 +15,7 @@ Particularly for developers who aren't experienced with .NET Core development on 1. Install the [.NET 8.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) which matches the `sdk.version` property in [global.json](../../global.json#L3) 3. You can build from VS Code by running the *Run Build Task* command, then selecting an appropriate task such as *build* or *build current project* (the latter builds the containing project for the current file you're viewing in the editor). 4. You can run tests from VS Code by opening a test class in the editor, then using the *Run Tests in Context* and *Debug Tests in Context* editor commands. You may want to bind these commands to keyboard shortcuts that match their Visual Studio equivalents (**Ctrl+R, T** for *Run Tests in Context* and **Ctrl+R, Ctrl+T** for *Debug Tests in Context*). +5. You can launch a new VS Code instance with the language server from your current code by running the "launch vscode with language server" task. ## Running Tests The unit tests can be executed by running `./build.sh --test`. diff --git a/docs/contributing/Building, Debugging, and Testing on Windows.md b/docs/contributing/Building, Debugging, and Testing on Windows.md index 43408387bddba..0482960a9d56c 100644 --- a/docs/contributing/Building, Debugging, and Testing on Windows.md +++ b/docs/contributing/Building, Debugging, and Testing on Windows.md @@ -86,7 +86,7 @@ give it a try. ### Deploying with command-line (recommended method) You can build and deploy with the following command: -`.\Build.cmd -Configuration Release -deployExtensions -launch`. +`.\Build.cmd -Restore -Configuration Release -deployExtensions -launch`. Then you can launch the `RoslynDev` hive with `devenv /rootSuffix RoslynDev`. diff --git a/docs/contributing/Target Framework Strategy.md b/docs/contributing/Target Framework Strategy.md index a6545072f1920..7395188691ce2 100644 --- a/docs/contributing/Target Framework Strategy.md +++ b/docs/contributing/Target Framework Strategy.md @@ -26,6 +26,7 @@ Projects in our repository should include the following values in `` setting. Instead our repo uses the above values and when inside source build or VMR our properties are initialized with arcade properties. @@ -58,7 +59,7 @@ This problem primarily comes from our use of polyfill APIs. To avoid this we emp This comes up in two forms: -### Pattern for types +### Pattern for types When creating a polyfill for a type use the `#if !NET...` to declare the type and in the `#else` use a `TypeForwardedTo` for the actual type. @@ -99,6 +100,13 @@ When creating a polyfill for an extension use the `#if NET...` to declare the ex #endif ``` +## Transitioning to new .NET SDK +As the .NET team approaches releasing a new .NET SDK the Roslyn team will begin using preview versions of that SDK in our build. This will often lead to test failures in our CI system due to underlying behavior changes in the runtime. These failures will often not show up when running in Visual Studio due to the way the runtime for the test runner is chosen. +To ensure we have a simple developer environment such project should be moved to to the `$(NetRoslynNext)` target framework. That ensures the new runtime is loaded when running tests locally. + +When the .NET SDK RTMs and Roslyn adopts it all occurrences of `$(NetRoslynNext)` will be moved to simply `$(NetRoslyn)`. + +**DO NOT** include both `$(NetRoslyn)` and `$(NetRoslynNext)` in the same project unless there is a very specific reason that both tests are adding value. The most common case is that the runtime has changed behavior and we simply need to update our baselines to match it. Adding extra TFMs for this just increases test time for very little gain. diff --git a/docs/wiki/EnC-Supported-Edits.md b/docs/wiki/EnC-Supported-Edits.md index c05d40b1121ce..39e7f453d42c2 100644 --- a/docs/wiki/EnC-Supported-Edits.md +++ b/docs/wiki/EnC-Supported-Edits.md @@ -50,3 +50,24 @@ This document captures the current state. Potential future improvements in this | Edit a member referencing an embedded interop type | - | | Edit a member with On Error or Resume statements | Specific to Visual Basic | | Edit a member containing an Aggregate, Group By, Simple Join, or Group Join LINQ query clause | Specific to Visual Basic | +| Edit in a solution containing projects that specify `*` in `AssemblyVersionAttribute`, e.g. `[assembly: AssemblyVersion("1.0.*")`]. | See [workaround](#projects-with-variable-assembly-versions) below. | + +### Projects with variable assembly versions + +Hot Reload and Edit & Continue are not compatible with using `*` in `AssemblyVersionAttribute` value. Presence of `*` in the version means that the compiler generates a new version +every build based on the current time. The build then produces non-reproducible, non-deterministic outputs (see [Reproducible Builds](https://reproducible-builds.org)). + +It is thus highly recommended to use alternative versioning methods, such as [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning), that derive the assembly version +from the HEAD commit SHA (for git repositories). + +> To enable generating commit SHA based assembly versions using `Nerdbank.GitVersioning` package, specify `{ "assemblyVersion" : {"precision": "revision"} }` setting in `version.json`. + +If you prefer to keep using `*` in `AssemblyVersionAttribute` it is recommended to use conditional compilation directive to only apply such version to Release builds like so: + +```C# +#if DEBUG +[assembly: AssemblyVersion("1.0.0.0")] +#else +[assembly: AssemblyVersion("1.0.*")] +#endif +``` diff --git a/eng/Directory.Packages.props b/eng/Directory.Packages.props index d9970c400f1f0..8e79bade88c9e 100644 --- a/eng/Directory.Packages.props +++ b/eng/Directory.Packages.props @@ -5,6 +5,7 @@ 8.0.0-preview.23468.1 1.1.2-beta1.24121.1 0.1.187-beta + <_BasicReferenceAssembliesVersion>1.7.2 4.8.0-3.final 17.10.72-preview @@ -56,7 +57,7 @@ Visual Studio --> - + @@ -99,7 +100,7 @@ - + @@ -138,11 +139,11 @@ - + - + + + + + <_NuGetPackagesToPush Include="@(ItemsToPushToBlobFeed)" + Condition=" '%(Extension)' == '.nupkg' " /> + + + <_SymbolPackagesToPush Include="@(_NuGetPackagesToPush)" + Condition="$([System.String]::Copy(%(FullPath)).EndsWith('.symbols.nupkg'))" /> + + + + + + + + \ No newline at end of file diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index 592d3954059e8..8451ebe80c273 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -13,13 +13,15 @@ - + - + diff --git a/eng/SymbolPublishingExclusionsFile.txt b/eng/SymbolPublishingExclusionsFile.txt new file mode 100644 index 0000000000000..58e11a1e6b135 --- /dev/null +++ b/eng/SymbolPublishingExclusionsFile.txt @@ -0,0 +1,8 @@ +content/LanguageServer/linux-musl-arm64/libe_sqlite3.so +content/LanguageServer/linux-musl-x64/libe_sqlite3.so +content/LanguageServer/neutral/runtimes/linux-musl-arm64/native/libe_sqlite3.so +content/LanguageServer/neutral/runtimes/linux-musl-arm/native/libe_sqlite3.so +content/LanguageServer/neutral/runtimes/linux-musl-x64/native/libe_sqlite3.so +content/LanguageServer/neutral/runtimes/alpine-arm64/native/libe_sqlite3.so +content/LanguageServer/neutral/runtimes/alpine-arm/native/libe_sqlite3.so +content/LanguageServer/neutral/runtimes/alpine-x64/native/libe_sqlite3.so diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4963ae650436c..5edbe6326345e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -2,9 +2,9 @@ - + https://github.com/dotnet/source-build-externals - f4e750201aaf6bad67391a52e8138bbd7abe3019 + 59204e5b14e6e197b3c942f992f6e3ec9196e50b @@ -110,14 +110,14 @@ - + https://github.com/dotnet/arcade - 67d23f4ba1813b315e7e33c71d18b63475f5c5f8 + 1cf3eaa1f6ada43ab988145a3f3efddb1ffa3b10 - + https://github.com/dotnet/arcade - 67d23f4ba1813b315e7e33c71d18b63475f5c5f8 + 1cf3eaa1f6ada43ab988145a3f3efddb1ffa3b10 @@ -144,9 +144,9 @@ https://github.com/dotnet/roslyn 5d10d428050c0d6afef30a072c4ae68776621877 - + https://github.com/dotnet/arcade - 67d23f4ba1813b315e7e33c71d18b63475f5c5f8 + 1cf3eaa1f6ada43ab988145a3f3efddb1ffa3b10 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/Versions.props b/eng/Versions.props index 78eb11bdac83d..e9fc305f8814b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,7 +8,7 @@ 4 11 0 - 1 + 2 $(MajorVersion).$(MinorVersion).$(PatchVersion) diff --git a/eng/common/internal/Directory.Build.props b/eng/common/internal/Directory.Build.props index dbf99d82a5c2e..f1d041c33da51 100644 --- a/eng/common/internal/Directory.Build.props +++ b/eng/common/internal/Directory.Build.props @@ -1,4 +1,11 @@ + + + false + false + + + diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj index 7f5ce6d608133..e925952d56664 100644 --- a/eng/common/internal/Tools.csproj +++ b/eng/common/internal/Tools.csproj @@ -1,8 +1,8 @@ + net472 - false false @@ -27,4 +27,5 @@ + diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index 2d5660642b8d4..ccd3a17268e24 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -64,7 +64,7 @@ if [ -z "$CLR_CC" ]; then if [ -z "$majorVersion" ]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. if [ "$compiler" = "clang" ]; then versions="18 17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" - elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi + elif [ "$compiler" = "gcc" ]; then versions="14 13 12 11 10 9 8 7 6 5 4.9"; fi for version in $versions; do _major="${version%%.*}" @@ -125,8 +125,8 @@ if [ -z "$CC" ]; then exit 1 fi -# Only lld version >= 9 can be considered stable. lld doesn't support s390x. -if [ "$compiler" = "clang" ] && [ -n "$majorVersion" ] && [ "$majorVersion" -ge 9 ] && [ "$build_arch" != "s390x" ]; then +# Only lld version >= 9 can be considered stable. lld supports s390x starting from 18.0. +if [ "$compiler" = "clang" ] && [ -n "$majorVersion" ] && [ "$majorVersion" -ge 9 ] && ([ "$build_arch" != "s390x" ] || [ "$majorVersion" -ge 18 ]); then if "$CC" -fuse-ld=lld -Wl,--version >/dev/null 2>&1; then LDFLAGS="-fuse-ld=lld" fi diff --git a/eng/common/native/init-distro-rid.sh b/eng/common/native/init-distro-rid.sh index de1687b2ccbe7..83ea7aab0e081 100644 --- a/eng/common/native/init-distro-rid.sh +++ b/eng/common/native/init-distro-rid.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # getNonPortableDistroRid # @@ -11,21 +11,16 @@ # non-portable rid getNonPortableDistroRid() { - local targetOs="$1" - local targetArch="$2" - local rootfsDir="$3" - local nonPortableRid="" + targetOs="$1" + targetArch="$2" + rootfsDir="$3" + nonPortableRid="" if [ "$targetOs" = "linux" ]; then + # shellcheck disable=SC1091 if [ -e "${rootfsDir}/etc/os-release" ]; then - source "${rootfsDir}/etc/os-release" - - if [[ "${ID}" == "rhel" || "${ID}" == "rocky" || "${ID}" == "alpine" ]]; then - # remove the last version digit - VERSION_ID="${VERSION_ID%.*}" - fi - - if [[ "${VERSION_ID:-}" =~ ^([[:digit:]]|\.)+$ ]]; then + . "${rootfsDir}/etc/os-release" + if echo "${VERSION_ID:-}" | grep -qE '^([[:digit:]]|\.)+$'; then nonPortableRid="${ID}.${VERSION_ID}-${targetArch}" else # Rolling release distros either do not set VERSION_ID, set it as blank or @@ -33,45 +28,33 @@ getNonPortableDistroRid() # so omit it here to be consistent with everything else. nonPortableRid="${ID}-${targetArch}" fi - elif [ -e "${rootfsDir}/android_platform" ]; then - source "$rootfsDir"/android_platform + # shellcheck disable=SC1091 + . "${rootfsDir}/android_platform" nonPortableRid="$RID" fi fi if [ "$targetOs" = "freebsd" ]; then - # $rootfsDir can be empty. freebsd-version is shell script and it should always work. - __freebsd_major_version=$($rootfsDir/bin/freebsd-version | { read v; echo "${v%%.*}"; }) + # $rootfsDir can be empty. freebsd-version is a shell script and should always work. + __freebsd_major_version=$("$rootfsDir"/bin/freebsd-version | cut -d'.' -f1) nonPortableRid="freebsd.$__freebsd_major_version-${targetArch}" - elif command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then + elif command -v getprop >/dev/null && getprop ro.product.system.model | grep -qi android; then __android_sdk_version=$(getprop ro.build.version.sdk) nonPortableRid="android.$__android_sdk_version-${targetArch}" elif [ "$targetOs" = "illumos" ]; then __uname_version=$(uname -v) - case "$__uname_version" in - omnios-*) - __omnios_major_version=$(echo "${__uname_version:8:2}") - nonPortableRid=omnios."$__omnios_major_version"-"$targetArch" - ;; - joyent_*) - __smartos_major_version=$(echo "${__uname_version:7:4}") - nonPortableRid=smartos."$__smartos_major_version"-"$targetArch" - ;; - illumos_*) - nonPortableRid=openindiana-"$targetArch" - ;; - esac + nonPortableRid="illumos-${targetArch}" elif [ "$targetOs" = "solaris" ]; then __uname_version=$(uname -v) - __solaris_major_version=$(echo "${__uname_version%.*}") - nonPortableRid=solaris."$__solaris_major_version"-"$targetArch" + __solaris_major_version=$(echo "$__uname_version" | cut -d'.' -f1) + nonPortableRid="solaris.$__solaris_major_version-${targetArch}" elif [ "$targetOs" = "haiku" ]; then - __uname_release=$(uname -r) + __uname_release="$(uname -r)" nonPortableRid=haiku.r"$__uname_release"-"$targetArch" fi - echo "$(echo $nonPortableRid | tr '[:upper:]' '[:lower:]')" + echo "$nonPortableRid" | tr '[:upper:]' '[:lower:]' } # initDistroRidGlobal @@ -85,26 +68,23 @@ getNonPortableDistroRid() # None # # Notes: -# -# It is important to note that the function does not return anything, but it -# exports the following variables on success: -# -# __DistroRid : Non-portable rid of the target platform. -# __PortableTargetOS : OS-part of the portable rid that corresponds to the target platform. -# +# It is important to note that the function does not return anything, but it +# exports the following variables on success: +# __DistroRid : Non-portable rid of the target platform. +# __PortableTargetOS : OS-part of the portable rid that corresponds to the target platform. initDistroRidGlobal() { - local targetOs="$1" - local targetArch="$2" - local rootfsDir="" - if [ "$#" -ge 3 ]; then + targetOs="$1" + targetArch="$2" + rootfsDir="" + if [ $# -ge 3 ]; then rootfsDir="$3" fi if [ -n "${rootfsDir}" ]; then # We may have a cross build. Check for the existence of the rootfsDir if [ ! -e "${rootfsDir}" ]; then - echo "Error rootfsDir has been passed, but the location is not valid." + echo "Error: rootfsDir has been passed, but the location is not valid." exit 1 fi fi @@ -119,7 +99,7 @@ initDistroRidGlobal() STRINGS="$(command -v llvm-strings || true)" fi - # Check for musl-based distros (e.g Alpine Linux, Void Linux). + # Check for musl-based distros (e.g. Alpine Linux, Void Linux). if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl || ( [ -n "$STRINGS" ] && "$STRINGS" "${rootfsDir}/usr/bin/ldd" 2>&1 | grep -q musl ); then __PortableTargetOS="linux-musl" diff --git a/eng/common/native/init-os-and-arch.sh b/eng/common/native/init-os-and-arch.sh index e693617a6c2b6..38921d4338f74 100644 --- a/eng/common/native/init-os-and-arch.sh +++ b/eng/common/native/init-os-and-arch.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # Use uname to determine what the OS is. OSName=$(uname -s | tr '[:upper:]' '[:lower:]') @@ -35,6 +35,10 @@ fi case "$CPUName" in arm64|aarch64) arch=arm64 + if [ "$(getconf LONG_BIT)" -lt 64 ]; then + # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS) + arch=arm + fi ;; loongarch64) @@ -50,6 +54,7 @@ case "$CPUName" in ;; armv7l|armv8l) + # shellcheck disable=SC1091 if (NAME=""; . /etc/os-release; test "$NAME" = "Tizen"); then arch=armel else diff --git a/eng/common/post-build/check-channel-consistency.ps1 b/eng/common/post-build/check-channel-consistency.ps1 index 63f3464c986a7..1728f035a93ed 100644 --- a/eng/common/post-build/check-channel-consistency.ps1 +++ b/eng/common/post-build/check-channel-consistency.ps1 @@ -7,7 +7,7 @@ try { . $PSScriptRoot\post-build-utils.ps1 if ($PromoteToChannels -eq "") { - Write-PipelineTaskError -Type 'warning' -Message "This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/master/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info." + Write-PipelineTaskError -Type 'warning' -Message "This build won't publish assets as it's not configured to any Maestro channel. If that wasn't intended use Darc to configure a default channel using add-default-channel for this branch or to promote it to a channel using add-build-to-channel. See https://github.com/dotnet/arcade/blob/main/Documentation/Darc.md#assigning-an-individual-build-to-a-channel for more info." ExitWithExitCode 0 } diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1 new file mode 100644 index 0000000000000..82d91f6fd0226 --- /dev/null +++ b/eng/common/post-build/redact-logs.ps1 @@ -0,0 +1,81 @@ +[CmdletBinding(PositionalBinding=$False)] +param( + [Parameter(Mandatory=$true, Position=0)][string] $InputPath, + [Parameter(Mandatory=$true)][string] $BinlogToolVersion, + [Parameter(Mandatory=$false)][string] $DotnetPath, + [Parameter(Mandatory=$false)][string] $PackageFeed = 'https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json', + # File with strings to redact - separated by newlines. + # For comments start the line with '# ' - such lines are ignored + [Parameter(Mandatory=$false)][string] $TokensFilePath, + [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact +) + +try { + . $PSScriptRoot\post-build-utils.ps1 + + $packageName = 'binlogtool' + + $dotnet = $DotnetPath + + if (!$dotnet) { + $dotnetRoot = InitializeDotNetCli -install:$true + $dotnet = "$dotnetRoot\dotnet.exe" + } + + $toolList = & "$dotnet" tool list -g + + if ($toolList -like "*$packageName*") { + & "$dotnet" tool uninstall $packageName -g + } + + $toolPath = "$PSScriptRoot\..\..\..\.tools" + $verbosity = 'minimal' + + New-Item -ItemType Directory -Force -Path $toolPath + + Push-Location -Path $toolPath + + try { + Write-Host "Installing Binlog redactor CLI..." + Write-Host "'$dotnet' new tool-manifest" + & "$dotnet" new tool-manifest + Write-Host "'$dotnet' tool install $packageName --local --add-source '$PackageFeed' -v $verbosity --version $BinlogToolVersion" + & "$dotnet" tool install $packageName --local --add-source "$PackageFeed" -v $verbosity --version $BinlogToolVersion + + if (Test-Path $TokensFilePath) { + Write-Host "Adding additional sensitive data for redaction from file: " $TokensFilePath + $TokensToRedact += Get-Content -Path $TokensFilePath | Foreach {$_.Trim()} | Where { $_ -notmatch "^# " } + } + + $optionalParams = [System.Collections.ArrayList]::new() + + Foreach ($p in $TokensToRedact) + { + if($p -match '^\$\(.*\)$') + { + Write-Host ("Ignoring token {0} as it is probably unexpanded AzDO variable" -f $p) + } + elseif($p) + { + $optionalParams.Add("-p:" + $p) | Out-Null + } + } + + & $dotnet binlogtool redact --input:$InputPath --recurse --in-place ` + @optionalParams + + if ($LastExitCode -ne 0) { + Write-PipelineTelemetryError -Category 'Redactor' -Type 'warning' -Message "Problems using Redactor tool (exit code: $LastExitCode). But ignoring them now." + } + } + finally { + Pop-Location + } + + Write-Host 'done.' +} +catch { + Write-Host $_ + Write-PipelineTelemetryError -Category 'Redactor' -Message "There was an error while trying to redact logs. Error: $_" + ExitWithExitCode 1 +} diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index 73828dd30d317..aab40de3fd9ac 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,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.8.1-2" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/sdl/trim-assets-version.ps1 b/eng/common/sdl/trim-assets-version.ps1 index a2e0048770452..0daa2a9e94628 100644 --- a/eng/common/sdl/trim-assets-version.ps1 +++ b/eng/common/sdl/trim-assets-version.ps1 @@ -72,4 +72,4 @@ catch { Write-Host $_ Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_ ExitWithExitCode 1 -} \ No newline at end of file +} diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md new file mode 100644 index 0000000000000..c114bc28dcb95 --- /dev/null +++ b/eng/common/template-guidance.md @@ -0,0 +1,137 @@ +# Overview + +Arcade provides templates for public (`/templates`) and 1ES pipeline templates (`/templates-official`) scenarios. Pipelines which are required to be managed by 1ES pipeline templates should reference `/templates-offical`, all other pipelines may reference `/templates`. + +## How to use + +Basic guidance is: + +- 1ES Pipeline Template or 1ES Microbuild template runs should reference `eng/common/templates-official`. Any internal production-graded pipeline should use these templates. + +- All other runs should reference `eng/common/templates`. + +See [azure-pipelines.yml](../../azure-pipelines.yml) (templates-official example) or [azure-pipelines-pr.yml](../../azure-pipelines-pr.yml) (templates example) for examples. + +#### The `templateIs1ESManaged` parameter + +The `templateIs1ESManaged` is available on most templates and affects which of the variants is used for nested templates. See [Development Notes](#development-notes) below for more information on the `templateIs1ESManaged1 parameter. + +- For templates under `job/`, `jobs/`, `steps`, or `post-build/`, this parameter must be explicitly set. + +## Multiple outputs + +1ES pipeline templates impose a policy where every publish artifact execution results in additional security scans being injected into your pipeline. When using `templates-official/jobs/jobs.yml`, Arcade reduces the number of additional security injections by gathering all publishing outputs into the [Build.ArtifactStagingDirectory](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#build-variables-devops-services), and utilizing the [outputParentDirectory](https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/1es-pipeline-templates/features/outputs#multiple-outputs) feature of 1ES pipeline templates. When implementing your pipeline, if you ensure publish artifacts are located in the `$(Build.ArtifactStagingDirectory)`, and utilize the 1ES provided template context, then you can reduce the number of security scans for your pipeline. + +Example: +``` yaml +# azure-pipelines.yml +extends: + template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate + parameters: + stages: + - stage: build + jobs: + - template: /eng/common/templates-official/jobs/jobs.yml@self + parameters: + # 1ES makes use of outputs to reduce security task injection overhead + templateContext: + outputs: + - output: pipelineArtifact + displayName: 'Publish logs from source' + continueOnError: true + condition: always() + targetPath: $(Build.ArtifactStagingDirectory)/artifacts/log + artifactName: Logs + jobs: + - job: Windows + steps: + - script: echo "friendly neighborhood" > artifacts/marvel/spiderman.txt + # copy build outputs to artifact staging directory for publishing + - task: CopyFiles@2 + displayName: Gather build output + inputs: + SourceFolder: '$(Build.SourcesDirectory)/artifacts/marvel' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/marvel' +``` + +Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`). + +# Development notes + +**Folder / file structure** + +``` text +eng\common\ + [templates || templates-official]\ + job\ + job.yml (shim + artifact publishing logic) + onelocbuild.yml (shim) + publish-build-assets.yml (shim) + source-build.yml (shim) + source-index-stage1.yml (shim) + jobs\ + codeql-build.yml (shim) + jobs.yml (shim) + source-build.yml (shim) + post-build\ + post-build.yml (shim) + trigger-subscription.yml (shim) + common-variabls.yml (shim) + setup-maestro-vars.yml (shim) + steps\ + publish-build-artifacts.yml (logic) + publish-pipeline-artifacts.yml (logic) + add-build-channel.yml (shim) + component-governance.yml (shim) + generate-sbom.yml (shim) + publish-logs.yml (shim) + retain-build.yml (shim) + send-to-helix.yml (shim) + source-build.yml (shim) + variables\ + pool-providers.yml (logic + redirect) # templates/variables/pool-providers.yml will redirect to templates-official/variables/pool-providers.yml if you are running in the internal project + sdl-variables.yml (logic) + core-templates\ + job\ + job.yml (logic) + onelocbuild.yml (logic) + publish-build-assets.yml (logic) + source-build.yml (logic) + source-index-stage1.yml (logic) + jobs\ + codeql-build.yml (logic) + jobs.yml (logic) + source-build.yml (logic) + post-build\ + common-variabls.yml (logic) + post-build.yml (logic) + setup-maestro-vars.yml (logic) + trigger-subscription.yml (logic) + steps\ + add-build-to-channel.yml (logic) + component-governance.yml (logic) + generate-sbom.yml (logic) + publish-build-artifacts.yml (redirect) + publish-logs.yml (logic) + publish-pipeline-artifacts.yml (redirect) + retain-build.yml (logic) + send-to-helix.yml (logic) + source-build.yml (logic) + variables\ + pool-providers.yml (redirect) +``` + +In the table above, a file is designated as "shim", "logic", or "redirect". + +- shim - represents a yaml file which is an intermediate step between pipeline logic and .Net Core Engineering's templates (`core-templates`) and defines the `is1ESPipeline` parameter value. + +- logic - represents actual base template logic. + +- redirect- represents a file in `core-templates` which redirects to the "logic" file in either `templates` or `templates-official`. + +Logic for Arcade's templates live **primarily** in the `core-templates` folder. The exceptions to the location of the logic files are around artifact publishing, which is handled differently between 1es pipeline templates and standard templates. `templates` and `templates-official` provide shim entry points which redirect to `core-templates` while also defining the `is1ESPipeline` parameter. If a shim is referenced in `templates`, then `is1ESPipeline` is set to `false`. If a shim is referenced in `templates-official`, then `is1ESPipeline` is set to `true`. + +Within `templates` and `templates-official`, the templates at the "stages", and "jobs" / "job" level have been replaced with shims. Templates at the "steps" and "variables" level are typically too granular to be replaced with shims and instead persist logic which is directly applicable to either scenario. + +Within `core-templates`, there are a handful of places where logic is dependent on which shim entry point was used. In those places, we redirect back to the respective logic file in `templates` or `templates-official`. diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 1f035fee73f4a..4724e9aaa8091 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -1,264 +1,62 @@ -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - -parameters: -# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - cancelTimeoutInMinutes: '' - condition: '' - container: '' - continueOnError: false - dependsOn: '' - displayName: '' - pool: '' - steps: [] - strategy: '' - timeoutInMinutes: '' - variables: [] - workspace: '' - templateContext: '' - -# Job base template specific parameters - # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md - artifacts: '' - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishBuildAssets: false - enablePublishTestResults: false - enablePublishUsingPipelines: false - enableBuildRetry: false - disableComponentGovernance: '' - componentGovernanceIgnoreDirectories: '' - mergeTestResults: false - testRunTitle: '' - testResultsFormat: '' - name: '' - preSteps: [] - runAsPublic: false -# Sbom related params - enableSbom: true - PackageVersion: 7.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - jobs: -- job: ${{ parameters.name }} - - ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: - cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} - - ${{ if ne(parameters.condition, '') }}: - condition: ${{ parameters.condition }} - - ${{ if ne(parameters.container, '') }}: - container: ${{ parameters.container }} - - ${{ if ne(parameters.continueOnError, '') }}: - continueOnError: ${{ parameters.continueOnError }} - - ${{ if ne(parameters.dependsOn, '') }}: - dependsOn: ${{ parameters.dependsOn }} - - ${{ if ne(parameters.displayName, '') }}: - displayName: ${{ parameters.displayName }} - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - - ${{ if ne(parameters.strategy, '') }}: - strategy: ${{ parameters.strategy }} - - ${{ if ne(parameters.timeoutInMinutes, '') }}: - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - - ${{ if ne(parameters.templateContext, '') }}: - templateContext: ${{ parameters.templateContext }} - - variables: - - ${{ 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 - value: 3,2000 - - ${{ each variable in parameters.variables }}: - # handle name-value variable syntax - # example: - # - name: [key] - # value: [value] - - ${{ if ne(variable.name, '') }}: - - name: ${{ variable.name }} - value: ${{ variable.value }} - - # handle variable groups - - ${{ if ne(variable.group, '') }}: - - group: ${{ variable.group }} - - # handle template variable syntax - # example: - # - template: path/to/template.yml - # parameters: - # [key]: [value] - - ${{ if ne(variable.template, '') }}: - - template: ${{ variable.template }} - ${{ if ne(variable.parameters, '') }}: - parameters: ${{ variable.parameters }} - - # handle key-value variable syntax. - # example: - # - [key]: [value] - - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: - - ${{ each pair in variable }}: - - name: ${{ pair.key }} - value: ${{ pair.value }} - - # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds - - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: DotNet-HelixApi-Access - - ${{ if ne(parameters.workspace, '') }}: - workspace: ${{ parameters.workspace }} - - steps: - - ${{ if ne(parameters.preSteps, '') }}: - - ${{ each preStep in parameters.preSteps }}: - - ${{ 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)' - 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 - - - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: - - task: DownloadPipelineArtifact@2 - inputs: - buildType: current - artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} - targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} - itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} - - - ${{ 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, 'production') }} - richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin - uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} - continueOnError: true - - - template: /eng/common/templates-official/steps/component-governance.yml - parameters: - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true - ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ 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')) - continueOnError: ${{ parameters.continueOnError }} - env: - TeamName: $(_TeamName) - - - ${{ if ne(parameters.artifacts.publish, '') }}: - - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - - task: CopyFiles@2 - displayName: Gather binaries for publish to artifacts - inputs: - SourceFolder: 'artifacts/bin' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' - - task: CopyFiles@2 - displayName: Gather packages for publish to artifacts - inputs: - SourceFolder: 'artifacts/packages' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish pipeline artifacts - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} - continueOnError: true - condition: always() - - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - task: 1ES.PublishPipelineArtifact@1 - inputs: - targetPath: 'artifacts/log' - artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: 'Publish logs' - continueOnError: true - condition: always() - - - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} - continueOnError: true - condition: always() - - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: - - task: PublishTestResults@2 - displayName: Publish XUnit Test Results - inputs: - testResultsFormat: 'xUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: - - task: PublishTestResults@2 - displayName: Publish TRX Test Results - inputs: - testResultsFormat: 'VSTest' - testResultsFiles: '*.trx' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/templates-official/steps/generate-sbom.yml - parameters: - PackageVersion: ${{ parameters.packageVersion}} - BuildDropPath: ${{ parameters.buildDropPath }} - IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if eq(parameters.enableBuildRetry, 'true') }}: - - task: 1ES.PublishPipelineArtifact@1 - inputs: - targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' - artifactName: 'BuildConfiguration' - displayName: 'Publish build retry configuration' - continueOnError: true \ No newline at end of file +- template: /eng/common/core-templates/job/job.yml + parameters: + is1ESPipeline: true + + # publish artifacts + # for 1ES managed templates, use the templateContext.output to handle multiple outputs. + templateContext: + outputParentDirectory: $(Build.ArtifactStagingDirectory) + outputs: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - output: buildArtifacts + displayName: Publish pipeline artifacts + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + condition: always() + continueOnError: true + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - output: pipelineArtifact + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)_Attempt$(System.JobAttempt)') }} + displayName: 'Publish logs' + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}: + - output: buildArtifacts + displayName: Publish Logs + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + publishLocation: Container + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - output: pipelineArtifact + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/eng/common/BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - output: pipelineArtifact + displayName: Publish SBOM manifest + continueOnError: true + targetPath: $(Build.ArtifactStagingDirectory)/sbom + artifactName: $(ARTIFACT_NAME) + + # add any outputs provided via root yaml + - ${{ if ne(parameters.templateContext.outputs, '') }}: + - ${{ each output in parameters.templateContext.outputs }}: + - ${{ output }} + + # add any remaining templateContext properties + ${{ each context in parameters.templateContext }}: + ${{ if and(ne(context.key, 'outputParentDirectory'), ne(context.key, 'outputs')) }}: + ${{ context.key }}: ${{ context.value }} + + ${{ each parameter in parameters }}: + ${{ if and(ne(parameter.key, 'templateContext'), ne(parameter.key, 'is1ESPipeline')) }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml index 52b4d05d3f8dd..0f0c514b912df 100644 --- a/eng/common/templates-official/job/onelocbuild.yml +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -1,112 +1,7 @@ -parameters: - # Optional: dependencies of the job - dependsOn: '' - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: '' - - CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex - GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - - SourcesDirectory: $(Build.SourcesDirectory) - CreatePr: true - AutoCompletePr: false - ReusePr: true - UseLfLineEndings: true - UseCheckedInLocProjectJson: false - SkipLocProjectJsonGeneration: false - LanguageSet: VS_Main_Languages - LclSource: lclFilesInRepo - LclPackageId: '' - RepoType: gitHub - GitHubOrg: dotnet - MirrorRepo: '' - MirrorBranch: main - condition: '' - JobNameSuffix: '' - jobs: -- job: OneLocBuild${{ parameters.JobNameSuffix }} - - dependsOn: ${{ parameters.dependsOn }} - - displayName: OneLocBuild${{ parameters.JobNameSuffix }} - - variables: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - - name: _GenerateLocProjectArguments - value: -SourcesDirectory ${{ parameters.SourcesDirectory }} - -LanguageSet "${{ parameters.LanguageSet }}" - -CreateNeutralXlfs - - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: - - name: _GenerateLocProjectArguments - value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson - - template: /eng/common/templates-official/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - - steps: - - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - - task: Powershell@2 - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 - arguments: $(_GenerateLocProjectArguments) - displayName: Generate LocProject.json - condition: ${{ parameters.condition }} - - - task: OneLocBuild@2 - displayName: OneLocBuild - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - inputs: - locProj: eng/Localize/LocProject.json - outDir: $(Build.ArtifactStagingDirectory) - lclSource: ${{ parameters.LclSource }} - lclPackageId: ${{ parameters.LclPackageId }} - isCreatePrSelected: ${{ parameters.CreatePr }} - isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} - ${{ if eq(parameters.CreatePr, true) }}: - isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - isShouldReusePrSelected: ${{ parameters.ReusePr }} - packageSourceAuth: patAuth - patVariable: ${{ parameters.CeapexPat }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - repoType: ${{ parameters.RepoType }} - gitHubPatVariable: "${{ parameters.GithubPat }}" - ${{ if ne(parameters.MirrorRepo, '') }}: - isMirrorRepoSelected: true - gitHubOrganization: ${{ parameters.GitHubOrg }} - mirrorRepo: ${{ parameters.MirrorRepo }} - mirrorBranch: ${{ parameters.MirrorBranch }} - condition: ${{ parameters.condition }} - - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish Localization Files - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} +- template: /eng/common/core-templates/job/onelocbuild.yml + parameters: + is1ESPipeline: true - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish LocProject.json - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} \ No newline at end of file + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml index 589ac80a18b74..d667a70e8de74 100644 --- a/eng/common/templates-official/job/publish-build-assets.yml +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -1,155 +1,7 @@ -parameters: - configuration: 'Debug' - - # Optional: condition for the job to run - condition: '' - - # Optional: 'true' if future jobs should run even if this job fails - continueOnError: false - - # Optional: dependencies of the job - dependsOn: '' - - # Optional: Include PublishBuildArtifacts task - enablePublishBuildArtifacts: false - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: {} - - # Optional: should run as a public build even in the internal project - # 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 - - artifactsPublishingAdditionalParameters: '' - - signingValidationAdditionalParameters: '' - jobs: -- job: Asset_Registry_Publish - - dependsOn: ${{ parameters.dependsOn }} - timeoutInMinutes: 150 - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - displayName: Publish Assets - ${{ else }}: - displayName: Publish to Build Asset Registry - - variables: - - template: /eng/common/templates-official/variables/pool-providers.yml - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: Publish-Build-Assets - - group: AzureDevOps-Artifact-Feeds-Pats - - name: runCodesignValidationInjection - value: false - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - - template: /eng/common/templates-official/post-build/common-variables.yml - - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: NetCore1ESPool-Publishing-Internal - image: windows.vs2019.amd64 - os: windows - steps: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download artifact - inputs: - artifactName: AssetManifests - downloadPath: '$(Build.StagingDirectory)/Download' - checkDownloadedFiles: true - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: NuGetAuthenticate@1 - - - task: PowerShell@2 - displayName: Publish Build Assets - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet - /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' - /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com - /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} - /p:OfficialBuildId=$(Build.BuildNumber) - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: powershell@2 - displayName: Create ReleaseConfigs Artifact - inputs: - targetType: inline - script: | - New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force - $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" - Add-Content -Path $filePath -Value $(BARBuildId) - Add-Content -Path $filePath -Value "$(DefaultChannels)" - Add-Content -Path $filePath -Value $(IsStableBuild) - - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish ReleaseConfigs Artifact - inputs: - PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - task: powershell@2 - displayName: Check if SymbolPublishingExclusionsFile.txt exists - inputs: - targetType: inline - script: | - $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" - if(Test-Path -Path $symbolExclusionfile) - { - Write-Host "SymbolExclusionFile exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" - } - else{ - Write-Host "Symbols Exclusion file does not exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" - } - - - task: 1ES.PublishBuildArtifacts@1 - displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion 3 - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' +- template: /eng/common/core-templates/job/publish-build-assets.yml + parameters: + is1ESPipeline: true - - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - - template: /eng/common/templates-official/steps/publish-logs.yml - parameters: - JobLabel: 'Publish_Artifacts_Logs' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml index f193dfbe23668..1a480034b678e 100644 --- a/eng/common/templates-official/job/source-build.yml +++ b/eng/common/templates-official/job/source-build.yml @@ -1,67 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. The template produces a server job with a - # default ID 'Source_Build_Complete' to put in a dependency list if necessary. - - # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. - jobNamePrefix: 'Source_Build' - - # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for - # managed-only repositories. This is an object with these properties: - # - # name: '' - # 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 - # 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. - # skipPublishValidation: false - # Disables publishing validation. By default, a check is performed to ensure no packages are - # published by source-build. - # container: '' - # A container to use. Runs in docker. - # pool: {} - # A pool to use. Runs directly on an agent. - # buildScript: '' - # Specifies the build script to invoke to perform the build in the repo. The default - # './build.sh' should work for typical Arcade repositories, but this is customizable for - # difficult situations. - # jobProperties: {} - # A list of job properties to inject at the top level, for potential extensibility beyond - # container and pool. - platform: {} - jobs: -- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} - displayName: Source-Build (${{ parameters.platform.name }}) - - ${{ each property in parameters.platform.jobProperties }}: - ${{ property.key }}: ${{ property.value }} - - ${{ if ne(parameters.platform.container, '') }}: - container: ${{ parameters.platform.container }} - - ${{ if eq(parameters.platform.pool, '') }}: - # The default VM host AzDO pool. This should be capable of running Docker containers: almost all - # source-build builds run in Docker, including the default managed platform. - # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] - demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open - - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - image: 1es-mariner-2 - os: linux - - ${{ if ne(parameters.platform.pool, '') }}: - pool: ${{ parameters.platform.pool }} - - workspace: - clean: all +- template: /eng/common/core-templates/job/source-build.yml + parameters: + is1ESPipeline: true - steps: - - template: /eng/common/templates-official/steps/source-build.yml - parameters: - platform: ${{ parameters.platform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml index f0513aee5b0da..6d5ead316f92b 100644 --- a/eng/common/templates-official/job/source-index-stage1.yml +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -1,68 +1,7 @@ -parameters: - runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20230228.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 - condition: '' - dependsOn: '' - pool: '' - jobs: -- job: SourceIndexStage1 - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - variables: - - name: SourceIndexPackageVersion - value: ${{ parameters.sourceIndexPackageVersion }} - - name: SourceIndexPackageSource - value: ${{ parameters.sourceIndexPackageSource }} - - name: BinlogPath - value: ${{ parameters.binlogPath }} - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: source-dot-net stage1 variables - - template: /eng/common/templates-official/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64.open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $(DncEngInternalBuildPool) - image: windows.vs2022.amd64 - os: windows - - steps: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - task: UseDotNet@2 - displayName: Use .NET Core SDK 6 - inputs: - packageType: sdk - version: 6.0.x - installationPath: $(Agent.TempDirectory)/dotnet - workingDirectory: $(Agent.TempDirectory) - - - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --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 +- template: /eng/common/core-templates/job/source-index-stage1.yml + parameters: + is1ESPipeline: true - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) - displayName: Upload stage1 artifacts to source index - env: - BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml index b68d3c2f31990..a726322ecfe01 100644 --- a/eng/common/templates-official/jobs/codeql-build.yml +++ b/eng/common/templates-official/jobs/codeql-build.yml @@ -1,31 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - jobs: -- template: /eng/common/templates-official/jobs/jobs.yml +- template: /eng/common/core-templates/jobs/codeql-build.yml parameters: - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishTestResults: false - enablePublishBuildAssets: false - enablePublishUsingPipelines: false - enableTelemetry: true + is1ESPipeline: true - variables: - - group: Publish-Build-Assets - # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in - # sync with the packages.config file. - - name: DefaultGuardianVersion - value: 0.109.0 - - name: GuardianPackagesConfigFile - value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config - - name: GuardianVersion - value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} - - jobs: ${{ parameters.jobs }} - + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml index 857a0f8ba43e8..007deddaea0f5 100644 --- a/eng/common/templates-official/jobs/jobs.yml +++ b/eng/common/templates-official/jobs/jobs.yml @@ -1,97 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - - # 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 - - # Optional: Parameters for source-build template. - # See /eng/common/templates-official/jobs/source-build.yml for options - sourceBuildParameters: [] - - graphFileGeneration: - # Optional: Enable generating the graph files at the end of the build - enabled: false - # Optional: Include toolset dependencies in the generated graph files - includeToolset: false - - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - - # Optional: Override automatically derived dependsOn value for "publish build assets" job - publishBuildAssetsDependsOn: '' - - # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. - publishAssetsImmediately: 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: '' - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - enableSourceIndex: false - sourceIndexParams: {} - -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - jobs: -- ${{ each job in parameters.jobs }}: - - template: ../job/job.yml - parameters: - # pass along parameters - ${{ each parameter in parameters }}: - ${{ if ne(parameter.key, 'jobs') }}: - ${{ parameter.key }}: ${{ parameter.value }} - - # pass along job properties - ${{ each property in job }}: - ${{ if ne(property.key, 'job') }}: - ${{ property.key }}: ${{ property.value }} - - name: ${{ job.job }} - -- ${{ if eq(parameters.enableSourceBuild, true) }}: - - template: /eng/common/templates-official/jobs/source-build.yml - parameters: - allCompletedJobId: Source_Build_Complete - ${{ each parameter in parameters.sourceBuildParameters }}: - ${{ parameter.key }}: ${{ parameter.value }} - -- ${{ if eq(parameters.enableSourceIndex, 'true') }}: - - template: ../job/source-index-stage1.yml - parameters: - runAsPublic: ${{ parameters.runAsPublic }} - ${{ each parameter in parameters.sourceIndexParams }}: - ${{ 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, '')) }}: - - template: ../job/publish-build-assets.yml - parameters: - continueOnError: ${{ parameters.continueOnError }} - dependsOn: - - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.publishBuildAssetsDependsOn }}: - - ${{ job.job }} - - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.jobs }}: - - ${{ job.job }} - - ${{ if eq(parameters.enableSourceBuild, true) }}: - - Source_Build_Complete +- template: /eng/common/core-templates/jobs/jobs.yml + parameters: + is1ESPipeline: true - runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} - enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml index 08e5db9bb1161..483e7b611f346 100644 --- a/eng/common/templates-official/jobs/source-build.yml +++ b/eng/common/templates-official/jobs/source-build.yml @@ -1,46 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. A job is created for each platform, as - # well as an optional server job that completes when all platform jobs complete. - - # The name of the "join" job for all source-build platforms. If set to empty string, the job is - # not included. Existing repo pipelines can use this job depend on all source-build jobs - # completing without maintaining a separate list of every single job ID: just depend on this one - # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. - allCompletedJobId: '' - - # See /eng/common/templates-official/job/source-build.yml - jobNamePrefix: 'Source_Build' - - # 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-stream8' - - # 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, - # one job runs on 'defaultManagedPlatform'. - platforms: [] - jobs: +- template: /eng/common/core-templates/jobs/source-build.yml + parameters: + is1ESPipeline: true -- ${{ if ne(parameters.allCompletedJobId, '') }}: - - job: ${{ parameters.allCompletedJobId }} - displayName: Source-Build Complete - pool: server - dependsOn: - - ${{ each platform in parameters.platforms }}: - - ${{ parameters.jobNamePrefix }}_${{ platform.name }} - - ${{ if eq(length(parameters.platforms), 0) }}: - - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} - -- ${{ each platform in parameters.platforms }}: - - template: /eng/common/templates-official/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ platform }} - -- ${{ if eq(length(parameters.platforms), 0) }}: - - template: /eng/common/templates-official/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ parameters.defaultManagedPlatform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml index c24193acfc981..c32fc49233f8f 100644 --- a/eng/common/templates-official/post-build/common-variables.yml +++ b/eng/common/templates-official/post-build/common-variables.yml @@ -1,22 +1,8 @@ variables: - - group: Publish-Build-Assets +- template: /eng/common/core-templates/post-build/common-variables.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: true - # Whether the build is internal or not - - name: IsInternalBuild - value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} - - # Default Maestro++ API Endpoint and API Version - - name: MaestroApiEndPoint - value: "https://maestro-prod.westus2.cloudapp.azure.com" - - name: MaestroApiAccessToken - value: $(MaestroAccessToken) - - name: MaestroApiVersion - value: "2020-02-20" - - - name: SourceLinkCLIVersion - value: 3.0.0 - - name: SymbolToolVersion - value: 1.0.1 - - - name: runCodesignValidationInjection - value: false + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml index da1f40958b450..2364c0fd4a527 100644 --- a/eng/common/templates-official/post-build/post-build.yml +++ b/eng/common/templates-official/post-build/post-build.yml @@ -1,285 +1,8 @@ -parameters: - # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. - # Publishing V1 is no longer supported - # Publishing V2 is no longer supported - # Publishing V3 is the default - - name: publishingInfraVersion - displayName: Which version of publishing should be used to promote the build definition? - type: number - default: 3 - values: - - 3 - - - name: BARBuildId - displayName: BAR Build Id - type: number - default: 0 - - - name: PromoteToChannelIds - displayName: Channel to promote BARBuildId to - type: string - default: '' - - - name: enableSourceLinkValidation - displayName: Enable SourceLink validation - type: boolean - default: false - - - name: enableSigningValidation - displayName: Enable signing validation - type: boolean - default: true - - - name: enableSymbolValidation - displayName: Enable symbol validation - type: boolean - default: false - - - name: enableNugetValidation - displayName: Enable NuGet validation - type: boolean - default: true - - - name: publishInstallersAndChecksums - displayName: Publish installers and checksums - type: boolean - default: true - - - name: SDLValidationParameters - type: object - default: - enable: false - publishGdn: false - continueOnError: false - params: '' - artifactNames: '' - downloadArtifacts: true - - # 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 - displayName: Symbol publishing additional parameters - type: string - default: '' - - - name: artifactsPublishingAdditionalParameters - displayName: Artifact publishing additional parameters - type: string - default: '' - - - name: signingValidationAdditionalParameters - displayName: Signing validation additional parameters - type: string - default: '' - - # Which stages should finish execution before post-build stages start - - name: validateDependsOn - type: object - default: - - build - - - name: publishDependsOn - type: object - default: - - Validate - - # Optional: Call asset publishing rather than running in a separate stage - - name: publishAssetsImmediately - type: boolean - default: false - stages: -- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - - stage: Validate - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Validate Build Assets - variables: - - template: common-variables.yml - - template: /eng/common/templates-official/variables/pool-providers.yml - jobs: - - job: - displayName: NuGet Validation - condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - - - job: - displayName: Signing Validation - condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - 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 - # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@1 - displayName: 'Authenticate to AzDO Feeds' - - # Signing validation will optionally work with the buildmanifest file which is downloaded from - # Azure DevOps above. - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task SigningValidation -restore -msbuildEngine vs - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' - /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' - ${{ parameters.signingValidationAdditionalParameters }} - - - template: ../steps/publish-logs.yml - parameters: - StageLabel: 'Validation' - JobLabel: 'Signing' - BinlogToolVersion: $(BinlogToolVersion) - - - job: - displayName: SourceLink Validation - condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022 - os: windows - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: BlobArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) - -GHCommit $(Build.SourceVersion) - -SourcelinkCliVersion $(SourceLinkCLIVersion) - continueOnError: true - -- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: - - stage: publish_using_darc - ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - dependsOn: ${{ parameters.publishDependsOn }} - ${{ else }}: - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Publish using Darc - variables: - - template: common-variables.yml - - template: /eng/common/templates-official/variables/pool-providers.yml - jobs: - - job: - displayName: Publish Using Darc - timeoutInMinutes: 120 - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: AzurePipelines-EO - image: 1ESPT-Windows2022 - demands: Cmd - os: windows - # If it's not devdiv, it's dnceng - ${{ else }}: - name: NetCore1ESPool-Publishing-Internal - image: windows.vs2019.amd64 - os: windows - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: NuGetAuthenticate@1 +- template: /eng/common/core-templates/post-build/post-build.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: true - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml index 0c87f149a4ad7..024397d878645 100644 --- a/eng/common/templates-official/post-build/setup-maestro-vars.yml +++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml @@ -1,70 +1,8 @@ -parameters: - BARBuildId: '' - PromoteToChannelIds: '' - steps: - - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Release Configs - inputs: - buildType: current - artifactName: ReleaseConfigs - checkDownloadedFiles: true - - - task: PowerShell@2 - name: setReleaseVars - displayName: Set Release Configs Vars - inputs: - targetType: inline - pwsh: true - script: | - try { - if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { - $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt - - $BarId = $Content | Select -Index 0 - $Channels = $Content | Select -Index 1 - $IsStableBuild = $Content | Select -Index 2 - - $AzureDevOpsProject = $Env:System_TeamProject - $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId - $AzureDevOpsBuildId = $Env:Build_BuildId - } - else { - $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" - - $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' - $apiHeaders.Add('Accept', 'application/json') - $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") - - $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - - $BarId = $Env:BARBuildId - $Channels = $Env:PromoteToMaestroChannels -split "," - $Channels = $Channels -join "][" - $Channels = "[$Channels]" - - $IsStableBuild = $buildInfo.stable - $AzureDevOpsProject = $buildInfo.azureDevOpsProject - $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId - $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId - } - - Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" - Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" - Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" +- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: true - Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" - Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" - Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" - } - catch { - Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace - exit 1 - } - env: - MAESTRO_API_TOKEN: $(MaestroApiAccessToken) - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml index f67a210d62f3e..543dea8c6969a 100644 --- a/eng/common/templates-official/steps/add-build-to-channel.yml +++ b/eng/common/templates-official/steps/add-build-to-channel.yml @@ -1,13 +1,7 @@ -parameters: - ChannelId: 0 - steps: -- task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) +- template: /eng/common/core-templates/steps/add-build-to-channel.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/build-reason.yml b/eng/common/templates-official/steps/build-reason.yml deleted file mode 100644 index eba58109b52c9..0000000000000 --- a/eng/common/templates-official/steps/build-reason.yml +++ /dev/null @@ -1,12 +0,0 @@ -# build-reason.yml -# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons -# to include steps (',' separated). -parameters: - conditions: '' - steps: [] - -steps: - - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: - - ${{ parameters.steps }} - - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml index cbba0596709da..30bb3985ca2bf 100644 --- a/eng/common/templates-official/steps/component-governance.yml +++ b/eng/common/templates-official/steps/component-governance.yml @@ -1,13 +1,7 @@ -parameters: - disableComponentGovernance: false - componentGovernanceIgnoreDirectories: '' - steps: -- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" - displayName: Set skipComponentGovernanceDetection variable -- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - - task: ComponentGovernanceComponentDetection@0 - continueOnError: true - inputs: - ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file +- template: /eng/common/core-templates/steps/component-governance.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/execute-codeql.yml b/eng/common/templates-official/steps/execute-codeql.yml deleted file mode 100644 index 9b4a5ffa30a78..0000000000000 --- a/eng/common/templates-official/steps/execute-codeql.yml +++ /dev/null @@ -1,32 +0,0 @@ -parameters: - # Language that should be analyzed. Defaults to csharp - language: csharp - # Build Commands - buildCommands: '' - overrideParameters: '' # Optional: to override values for parameters. - additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth - # diagnosis of problems with specific tool configurations. - publishGuardianDirectoryToPipeline: false - # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL - # parameters rather than relying on YAML. It may be better to use a local script, because you can - # reproduce results locally without piecing together a command based on the YAML. - executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' - # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named - # 'continueOnError', the parameter value is not correctly picked up. - # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter - # optional: determines whether to continue the build if the step errors; - sdlContinueOnError: false - -steps: -- template: /eng/common/templates-official/steps/execute-sdl.yml - parameters: - overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} - executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} - overrideParameters: ${{ parameters.overrideParameters }} - additionalParameters: '${{ parameters.additionalParameters }} - -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")' - publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} - sdlContinueOnError: ${{ parameters.sdlContinueOnError }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml deleted file mode 100644 index 07426fde05d82..0000000000000 --- a/eng/common/templates-official/steps/execute-sdl.yml +++ /dev/null @@ -1,88 +0,0 @@ -parameters: - overrideGuardianVersion: '' - executeAllSdlToolsScript: '' - overrideParameters: '' - additionalParameters: '' - publishGuardianDirectoryToPipeline: false - sdlContinueOnError: false - condition: '' - -steps: -- task: NuGetAuthenticate@1 - inputs: - nuGetServiceConnections: GuardianConnect - -- task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - -- ${{ if ne(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian (Overridden) - -- ${{ if eq(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian - -- ${{ if ne(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} - displayName: Execute SDL (Overridden) - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if eq(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} - -GuardianCliLocation $(GuardianCliLocation) - -NugetPackageDirectory $(Build.SourcesDirectory)\.packages - -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) - ${{ parameters.additionalParameters }} - displayName: Execute SDL - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: - # We want to publish the Guardian results and configuration for easy diagnosis. However, the - # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default - # tooling files. Some of these files are large and aren't useful during an investigation, so - # exclude them by simply deleting them before publishing. (As of writing, there is no documented - # way to selectively exclude a dir from the pipeline artifact publish task.) - - task: DeleteFiles@1 - displayName: Delete Guardian dependencies to avoid uploading - inputs: - SourceFolder: $(Agent.BuildDirectory)/.gdn - Contents: | - c - i - condition: succeededOrFailed() - - - publish: $(Agent.BuildDirectory)/.gdn - artifact: GuardianConfiguration - displayName: Publish GuardianConfiguration - condition: succeededOrFailed() - - # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration - # with the "SARIF SAST Scans Tab" Azure DevOps extension - - task: CopyFiles@2 - displayName: Copy SARIF files - inputs: - flattenFolders: true - sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ - contents: '**/*.sarif' - targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs - condition: succeededOrFailed() - - # Use PublishBuildArtifacts because the SARIF extension only checks this case - # see microsoft/sarif-azuredevops-extension#4 - - task: PublishBuildArtifacts@1 - displayName: Publish SARIF files to CodeAnalysisLogs container - inputs: - pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs - artifactName: CodeAnalysisLogs - condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml index 1bf43bf807af3..9a89a4706d94e 100644 --- a/eng/common/templates-official/steps/generate-sbom.yml +++ b/eng/common/templates-official/steps/generate-sbom.yml @@ -1,48 +1,7 @@ -# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. -# PackageName - The name of the package this SBOM represents. -# PackageVersion - The version of the package this SBOM represents. -# ManifestDirPath - The path of the directory where the generated manifest files will be placed -# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. - -parameters: - PackageVersion: 8.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - PackageName: '.NET' - ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom - IgnoreDirectories: '' - sbomContinueOnError: true - steps: -- task: PowerShell@2 - displayName: Prep for SBOM generation in (Non-linux) - condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) - inputs: - filePath: ./eng/common/generate-sbom-prep.ps1 - arguments: ${{parameters.manifestDirPath}} - -# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 -- script: | - chmod +x ./eng/common/generate-sbom-prep.sh - ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} - displayName: Prep for SBOM generation in (Linux) - condition: eq(variables['Agent.Os'], 'Linux') - continueOnError: ${{ parameters.sbomContinueOnError }} - -- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: 'Generate SBOM manifest' - continueOnError: ${{ parameters.sbomContinueOnError }} - inputs: - PackageName: ${{ parameters.packageName }} - BuildDropPath: ${{ parameters.buildDropPath }} - PackageVersion: ${{ parameters.packageVersion }} - ManifestDirPath: ${{ parameters.manifestDirPath }} - ${{ if ne(parameters.IgnoreDirectories, '') }}: - AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' - -- task: 1ES.PublishPipelineArtifact@1 - displayName: Publish SBOM manifest - continueOnError: ${{parameters.sbomContinueOnError}} - inputs: - targetPath: '${{parameters.manifestDirPath}}' - artifactName: $(ARTIFACT_NAME) +- template: /eng/common/core-templates/steps/generate-sbom.yml + parameters: + is1ESPipeline: true + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/publish-build-artifacts.yml b/eng/common/templates-official/steps/publish-build-artifacts.yml new file mode 100644 index 0000000000000..100a3fc98493c --- /dev/null +++ b/eng/common/templates-official/steps/publish-build-artifacts.yml @@ -0,0 +1,41 @@ +parameters: +- name: displayName + type: string + default: 'Publish to Build Artifact' + +- name: condition + type: string + default: succeeded() + +- name: artifactName + type: string + +- name: pathToPublish + type: string + +- name: continueOnError + type: boolean + default: false + +- name: publishLocation + type: string + default: 'Container' + +- name: is1ESPipeline + type: boolean + default: true + +steps: +- ${{ if ne(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error +- task: 1ES.PublishBuildArtifacts@1 + displayName: ${{ parameters.displayName }} + condition: ${{ parameters.condition }} + ${{ if parameters.continueOnError }}: + continueOnError: ${{ parameters.continueOnError }} + inputs: + PublishLocation: ${{ parameters.publishLocation }} + PathtoPublish: ${{ parameters.pathToPublish }} + ${{ if parameters.artifactName }}: + ArtifactName: ${{ parameters.artifactName }} + diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml index 04012fed182a1..579fd531e94c3 100644 --- a/eng/common/templates-official/steps/publish-logs.yml +++ b/eng/common/templates-official/steps/publish-logs.yml @@ -1,23 +1,7 @@ -parameters: - StageLabel: '' - JobLabel: '' - steps: -- task: Powershell@2 - displayName: Prepare Binlogs to Upload - inputs: - targetType: inline - script: | - New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - continueOnError: true - condition: always() +- template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: true -- task: 1ES.PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' - PublishLocation: Container - ArtifactName: PostBuildLogs - continueOnError: true - condition: always() + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml new file mode 100644 index 0000000000000..d71eb0c743986 --- /dev/null +++ b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml @@ -0,0 +1,26 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: true + +- name: args + type: object + default: {} + +steps: +- ${{ if ne(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error +- task: 1ES.PublishPipelineArtifact@1 + displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }} + ${{ if parameters.args.condition }}: + condition: ${{ parameters.args.condition }} + ${{ else }}: + condition: succeeded() + ${{ if parameters.args.continueOnError }}: + continueOnError: ${{ parameters.args.continueOnError }} + inputs: + targetPath: ${{ parameters.args.targetPath }} + ${{ if parameters.args.artifactName }}: + artifactName: ${{ parameters.args.artifactName }} + ${{ if parameters.args.properties }}: + properties: ${{ parameters.args.properties }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml index 83d97a26a01ff..5594551508a3c 100644 --- a/eng/common/templates-official/steps/retain-build.yml +++ b/eng/common/templates-official/steps/retain-build.yml @@ -1,28 +1,7 @@ -parameters: - # Optional azure devops PAT with build execute permissions for the build's organization, - # only needed if the build that should be retained ran on a different organization than - # the pipeline where this template is executing from - Token: '' - # Optional BuildId to retain, defaults to the current running build - BuildId: '' - # Azure devops Organization URI for the build in the https://dev.azure.com/ format. - # Defaults to the organization the current pipeline is running on - AzdoOrgUri: '$(System.CollectionUri)' - # Azure devops project for the build. Defaults to the project the current pipeline is running on - AzdoProject: '$(System.TeamProject)' - steps: - - task: powershell@2 - inputs: - targetType: 'filePath' - filePath: eng/common/retain-build.ps1 - pwsh: true - arguments: > - -AzdoOrgUri: ${{parameters.AzdoOrgUri}} - -AzdoProject ${{parameters.AzdoProject}} - -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} - -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} - displayName: Enable permanent build retention - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - BUILD_ID: $(Build.BuildId) \ No newline at end of file +- template: /eng/common/core-templates/steps/retain-build.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml index 3eb7e2d5f840c..6500f21bf845c 100644 --- a/eng/common/templates-official/steps/send-to-helix.yml +++ b/eng/common/templates-official/steps/send-to-helix.yml @@ -1,91 +1,7 @@ -# Please remember to update the documentation if you make changes to these parameters! -parameters: - HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ - HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' - HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group - HelixConfiguration: '' # optional -- additional property attached to a job - HelixPreCommands: '' # optional -- commands to run before Helix work item execution - HelixPostCommands: '' # optional -- commands to run after Helix work item execution - WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects - WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects - WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects - CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload - XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true - XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects - XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects - XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner - XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects - IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion - DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." - IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set - HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) - Creator: '' # optional -- if the build is external, use this to specify who is sending the job - DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO - condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() - continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false - steps: - - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' - displayName: ${{ parameters.DisplayNamePrefix }} (Windows) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Unix) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} +- template: /eng/common/core-templates/steps/send-to-helix.yml + parameters: + is1ESPipeline: true + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml index 829f17c34d118..8f92c49e7b06f 100644 --- a/eng/common/templates-official/steps/source-build.yml +++ b/eng/common/templates-official/steps/source-build.yml @@ -1,129 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. - - # This is a 'steps' template, and is intended for advanced scenarios where the existing build - # infra has a careful build methodology that must be followed. For example, a repo - # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline - # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to - # GitHub. Using this steps template leaves room for that infra to be included. - - # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml' - # for details. The entire object is described in the 'job' template for simplicity, even though - # the usage of the properties on this object is split between the 'job' and 'steps' templates. - platform: {} - steps: -# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) -- script: | - set -x - df -h - - # If building on the internal project, the artifact feeds variable may be available (usually only if needed) - # In that case, call the feed setup script to add internal feeds corresponding to public ones. - # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. - # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those - # changes. - internalRestoreArgs= - if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then - # Temporarily work around https://github.com/dotnet/arcade/issues/7709 - chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh - $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) - 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)' - fi - - buildConfig=Release - # Check if AzDO substitutes in a build config from a variable, and use it if so. - if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then - 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 - fi - - ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ - --configuration $buildConfig \ - --restore --build --pack $publishArgs -bl \ - $officialBuildArgs \ - $internalRuntimeDownloadArgs \ - $internalRestoreArgs \ - $targetRidArgs \ - $runtimeOsArgs \ - $baseOsArgs \ - /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ - /p:ArcadeBuildFromSource=true \ - /p:AssetManifestFileName=$assetManifestFileName - displayName: Build - -# Upload build logs for diagnosis. -- task: CopyFiles@2 - displayName: Prepare BuildLogs staging directory - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - **/*.log - **/*.binlog - artifacts/source-build/self/prebuilt-report/** - TargetFolder: '$(Build.StagingDirectory)/BuildLogs' - CleanTargetFolder: true - continueOnError: true - condition: succeededOrFailed() - -- task: 1ES.PublishPipelineArtifact@1 - displayName: Publish BuildLogs - inputs: - targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) - continueOnError: true - condition: succeededOrFailed() +- template: /eng/common/core-templates/steps/source-build.yml + parameters: + is1ESPipeline: true -# 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 -- task: ComponentGovernanceComponentDetection@0 - displayName: Component Detection (Exclude upstream cache) - inputs: - ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/execute-sdl.yml b/eng/common/templates/job/execute-sdl.yml deleted file mode 100644 index 7870f93bc1765..0000000000000 --- a/eng/common/templates/job/execute-sdl.yml +++ /dev/null @@ -1,139 +0,0 @@ -parameters: - enable: 'false' # Whether the SDL validation job should execute or not - overrideParameters: '' # Optional: to override values for parameters. - additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth - # diagnosis of problems with specific tool configurations. - publishGuardianDirectoryToPipeline: false - # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL - # parameters rather than relying on YAML. It may be better to use a local script, because you can - # reproduce results locally without piecing together a command based on the YAML. - executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' - # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named - # 'continueOnError', the parameter value is not correctly picked up. - # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter - sdlContinueOnError: false # optional: determines whether to continue the build if the step errors; - # optional: determines if build artifacts should be downloaded. - downloadArtifacts: true - # optional: determines if this job should search the directory of downloaded artifacts for - # 'tar.gz' and 'zip' archive files and extract them before running SDL validation tasks. - extractArchiveArtifacts: false - dependsOn: '' # Optional: dependencies of the job - artifactNames: '' # Optional: patterns supplied to DownloadBuildArtifacts - # Usage: - # artifactNames: - # - 'BlobArtifacts' - # - 'Artifacts_Windows_NT_Release' - # Optional: download a list of pipeline artifacts. 'downloadArtifacts' controls build artifacts, - # not pipeline artifacts, so doesn't affect the use of this parameter. - pipelineArtifactNames: [] - -jobs: -- job: Run_SDL - dependsOn: ${{ parameters.dependsOn }} - displayName: Run SDL tool - condition: and(succeededOrFailed(), eq( ${{ parameters.enable }}, 'true')) - variables: - - group: DotNet-VSTS-Bot - - name: AzDOProjectName - value: ${{ parameters.AzDOProjectName }} - - name: AzDOPipelineId - value: ${{ parameters.AzDOPipelineId }} - - name: AzDOBuildId - value: ${{ parameters.AzDOBuildId }} - - template: /eng/common/templates/variables/sdl-variables.yml - - name: GuardianVersion - value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} - - template: /eng/common/templates/variables/pool-providers.yml - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - checkout: self - clean: true - - # If the template caller didn't provide an AzDO parameter, set them all up as Maestro vars. - - ${{ if not(and(parameters.AzDOProjectName, parameters.AzDOPipelineId, parameters.AzDOBuildId)) }}: - - template: /eng/common/templates/post-build/setup-maestro-vars.yml - - - ${{ if ne(parameters.downloadArtifacts, 'false')}}: - - ${{ if ne(parameters.artifactNames, '') }}: - - ${{ each artifactName in parameters.artifactNames }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Build Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: ${{ artifactName }} - downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - checkDownloadedFiles: true - - ${{ if eq(parameters.artifactNames, '') }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Build Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - downloadType: specific files - itemPattern: "**" - downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - checkDownloadedFiles: true - - - ${{ each artifactName in parameters.pipelineArtifactNames }}: - - task: DownloadPipelineArtifact@2 - displayName: Download Pipeline Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: ${{ artifactName }} - downloadPath: $(Build.ArtifactStagingDirectory)\artifacts - checkDownloadedFiles: true - - - powershell: eng/common/sdl/trim-assets-version.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts - displayName: Trim the version from the NuGet packages - continueOnError: ${{ parameters.sdlContinueOnError }} - - - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts - -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\BlobArtifacts - displayName: Extract Blob Artifacts - continueOnError: ${{ parameters.sdlContinueOnError }} - - - powershell: eng/common/sdl/extract-artifact-packages.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts - -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts\PackageArtifacts - displayName: Extract Package Artifacts - continueOnError: ${{ parameters.sdlContinueOnError }} - - - ${{ if ne(parameters.extractArchiveArtifacts, 'false') }}: - - powershell: eng/common/sdl/extract-artifact-archives.ps1 - -InputPath $(Build.ArtifactStagingDirectory)\artifacts - -ExtractPath $(Build.ArtifactStagingDirectory)\artifacts - displayName: Extract Archive Artifacts - continueOnError: ${{ parameters.sdlContinueOnError }} - - - template: /eng/common/templates/steps/execute-sdl.yml - parameters: - overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} - executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} - overrideParameters: ${{ parameters.overrideParameters }} - additionalParameters: ${{ parameters.additionalParameters }} - publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} - sdlContinueOnError: ${{ parameters.sdlContinueOnError }} diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 8ec5c4f2d9f91..1cf9a6d48127b 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -1,259 +1,61 @@ -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - -parameters: -# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - cancelTimeoutInMinutes: '' - condition: '' - container: '' - continueOnError: false - dependsOn: '' - displayName: '' - pool: '' - steps: [] - strategy: '' - timeoutInMinutes: '' - variables: [] - workspace: '' - templateContext: '' - -# Job base template specific parameters - # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md - artifacts: '' - enableMicrobuild: false +parameters: enablePublishBuildArtifacts: false - enablePublishBuildAssets: false - enablePublishTestResults: false - enablePublishUsingPipelines: false - enableBuildRetry: false - disableComponentGovernance: '' - componentGovernanceIgnoreDirectories: '' - mergeTestResults: false - testRunTitle: '' - testResultsFormat: '' - name: '' - preSteps: [] - runAsPublic: false -# Sbom related params - enableSbom: true - PackageVersion: 7.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' jobs: -- job: ${{ parameters.name }} - - ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: - cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} - - ${{ if ne(parameters.condition, '') }}: - condition: ${{ parameters.condition }} - - ${{ if ne(parameters.container, '') }}: - container: ${{ parameters.container }} - - ${{ if ne(parameters.continueOnError, '') }}: - continueOnError: ${{ parameters.continueOnError }} - - ${{ if ne(parameters.dependsOn, '') }}: - dependsOn: ${{ parameters.dependsOn }} - - ${{ if ne(parameters.displayName, '') }}: - displayName: ${{ parameters.displayName }} - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - - ${{ if ne(parameters.strategy, '') }}: - strategy: ${{ parameters.strategy }} - - ${{ if ne(parameters.timeoutInMinutes, '') }}: - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - - ${{ if ne(parameters.templateContext, '') }}: - templateContext: ${{ parameters.templateContext }} - - variables: - - ${{ 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 - value: 3,2000 - - ${{ each variable in parameters.variables }}: - # handle name-value variable syntax - # example: - # - name: [key] - # value: [value] - - ${{ if ne(variable.name, '') }}: - - name: ${{ variable.name }} - value: ${{ variable.value }} - - # handle variable groups - - ${{ if ne(variable.group, '') }}: - - group: ${{ variable.group }} - - # handle template variable syntax - # example: - # - template: path/to/template.yml - # parameters: - # [key]: [value] - - ${{ if ne(variable.template, '') }}: - - template: ${{ variable.template }} - ${{ if ne(variable.parameters, '') }}: - parameters: ${{ variable.parameters }} - - # handle key-value variable syntax. - # example: - # - [key]: [value] - - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: - - ${{ each pair in variable }}: - - name: ${{ pair.key }} - value: ${{ pair.value }} - - # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds - - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: DotNet-HelixApi-Access - - ${{ if ne(parameters.workspace, '') }}: - workspace: ${{ parameters.workspace }} - - steps: - - ${{ if ne(parameters.preSteps, '') }}: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - task: MicroBuildSigningPlugin@3 - displayName: Install MicroBuild plugin - inputs: - signType: $(_SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - env: - TeamName: $(_TeamName) - 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 - - - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: - - task: DownloadPipelineArtifact@2 - inputs: - buildType: current - artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} - targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} - itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} - - - ${{ 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, 'production') }} - richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin - uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} - continueOnError: true - - - template: /eng/common/templates/steps/component-governance.yml - parameters: - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true - ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ 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')) - continueOnError: ${{ parameters.continueOnError }} - env: - TeamName: $(_TeamName) - - - ${{ if ne(parameters.artifacts.publish, '') }}: - - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - - task: CopyFiles@2 - displayName: Gather binaries for publish to artifacts - inputs: - SourceFolder: 'artifacts/bin' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' - - task: CopyFiles@2 - displayName: Gather packages for publish to artifacts - inputs: - SourceFolder: 'artifacts/packages' - Contents: '**' - TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' - - task: PublishBuildArtifacts@1 - displayName: Publish pipeline artifacts - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} - continueOnError: true - condition: always() - - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - publish: artifacts/log - artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: Publish logs - continueOnError: true - condition: always() - - - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: - - task: PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' - PublishLocation: Container - ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} - continueOnError: true - condition: always() - - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: - - task: PublishTestResults@2 - displayName: Publish XUnit Test Results - inputs: - testResultsFormat: 'xUnit' - testResultsFiles: '*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: - - task: PublishTestResults@2 - displayName: Publish TRX Test Results - inputs: - testResultsFormat: 'VSTest' - testResultsFiles: '*.trx' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx - mergeTestResults: ${{ parameters.mergeTestResults }} - continueOnError: true - condition: always() - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/templates/steps/generate-sbom.yml - parameters: - PackageVersion: ${{ parameters.packageVersion}} - BuildDropPath: ${{ parameters.buildDropPath }} - IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if eq(parameters.enableBuildRetry, 'true') }}: - - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration - artifact: BuildConfiguration - displayName: Publish build retry configuration - continueOnError: true +- template: /eng/common/core-templates/job/job.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ if and(ne(parameter.key, 'steps'), ne(parameter.key, 'is1ESPipeline')) }}: + ${{ parameter.key }}: ${{ parameter.value }} + + steps: + - ${{ each step in parameters.steps }}: + - ${{ step }} + + artifactPublishSteps: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: false + args: + displayName: Publish pipeline artifacts + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + publishLocation: Container + artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: false + args: + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' + continueOnError: true + condition: always() + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: false + args: + displayName: Publish Logs + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + publishLocation: Container + artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: false + args: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml index 60ab00c4de3ac..ff829dc4c700c 100644 --- a/eng/common/templates/job/onelocbuild.yml +++ b/eng/common/templates/job/onelocbuild.yml @@ -1,109 +1,7 @@ -parameters: - # Optional: dependencies of the job - dependsOn: '' - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: '' - - CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex - GithubPat: $(BotAccount-dotnet-bot-repo-PAT) - - SourcesDirectory: $(Build.SourcesDirectory) - CreatePr: true - AutoCompletePr: false - ReusePr: true - UseLfLineEndings: true - UseCheckedInLocProjectJson: false - SkipLocProjectJsonGeneration: false - LanguageSet: VS_Main_Languages - LclSource: lclFilesInRepo - LclPackageId: '' - RepoType: gitHub - GitHubOrg: dotnet - MirrorRepo: '' - MirrorBranch: main - condition: '' - JobNameSuffix: '' - jobs: -- job: OneLocBuild${{ parameters.JobNameSuffix }} - - dependsOn: ${{ parameters.dependsOn }} - - displayName: OneLocBuild${{ parameters.JobNameSuffix }} - - variables: - - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat - - name: _GenerateLocProjectArguments - value: -SourcesDirectory ${{ parameters.SourcesDirectory }} - -LanguageSet "${{ parameters.LanguageSet }}" - -CreateNeutralXlfs - - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: - - name: _GenerateLocProjectArguments - value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson - - template: /eng/common/templates/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: - - task: Powershell@2 - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 - arguments: $(_GenerateLocProjectArguments) - displayName: Generate LocProject.json - condition: ${{ parameters.condition }} - - - task: OneLocBuild@2 - displayName: OneLocBuild - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - inputs: - locProj: eng/Localize/LocProject.json - outDir: $(Build.ArtifactStagingDirectory) - lclSource: ${{ parameters.LclSource }} - lclPackageId: ${{ parameters.LclPackageId }} - isCreatePrSelected: ${{ parameters.CreatePr }} - isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} - ${{ if eq(parameters.CreatePr, true) }}: - isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - isShouldReusePrSelected: ${{ parameters.ReusePr }} - packageSourceAuth: patAuth - patVariable: ${{ parameters.CeapexPat }} - ${{ if eq(parameters.RepoType, 'gitHub') }}: - repoType: ${{ parameters.RepoType }} - gitHubPatVariable: "${{ parameters.GithubPat }}" - ${{ if ne(parameters.MirrorRepo, '') }}: - isMirrorRepoSelected: true - gitHubOrganization: ${{ parameters.GitHubOrg }} - mirrorRepo: ${{ parameters.MirrorRepo }} - mirrorBranch: ${{ parameters.MirrorBranch }} - condition: ${{ parameters.condition }} - - - task: PublishBuildArtifacts@1 - displayName: Publish Localization Files - inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} +- template: /eng/common/core-templates/job/onelocbuild.yml + parameters: + is1ESPipeline: false - - task: PublishBuildArtifacts@1 - displayName: Publish LocProject.json - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' - PublishLocation: Container - ArtifactName: Loc - condition: ${{ parameters.condition }} \ No newline at end of file + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index 8ec0151def21a..ab2edec2adb54 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -1,151 +1,7 @@ -parameters: - configuration: 'Debug' - - # Optional: condition for the job to run - condition: '' - - # Optional: 'true' if future jobs should run even if this job fails - continueOnError: false - - # Optional: dependencies of the job - dependsOn: '' - - # Optional: Include PublishBuildArtifacts task - enablePublishBuildArtifacts: false - - # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool - pool: {} - - # Optional: should run as a public build even in the internal project - # 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 - - artifactsPublishingAdditionalParameters: '' - - signingValidationAdditionalParameters: '' - jobs: -- job: Asset_Registry_Publish - - dependsOn: ${{ parameters.dependsOn }} - timeoutInMinutes: 150 - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - displayName: Publish Assets - ${{ else }}: - displayName: Publish to Build Asset Registry - - variables: - - template: /eng/common/templates/variables/pool-providers.yml - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: Publish-Build-Assets - - group: AzureDevOps-Artifact-Feeds-Pats - - name: runCodesignValidationInjection - value: false - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - - template: /eng/common/templates/post-build/common-variables.yml - - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: NetCore1ESPool-Publishing-Internal - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download artifact - inputs: - artifactName: AssetManifests - downloadPath: '$(Build.StagingDirectory)/Download' - checkDownloadedFiles: true - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: NuGetAuthenticate@1 - - - task: PowerShell@2 - displayName: Publish Build Assets - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet - /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' - /p:BuildAssetRegistryToken=$(MaestroAccessToken) - /p:MaestroApiEndpoint=https://maestro.dot.net - /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} - /p:OfficialBuildId=$(Build.BuildNumber) - condition: ${{ parameters.condition }} - continueOnError: ${{ parameters.continueOnError }} - - - task: powershell@2 - displayName: Create ReleaseConfigs Artifact - inputs: - targetType: inline - script: | - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) - - - task: PublishBuildArtifacts@1 - displayName: Publish ReleaseConfigs Artifact - inputs: - PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - task: powershell@2 - displayName: Check if SymbolPublishingExclusionsFile.txt exists - inputs: - targetType: inline - script: | - $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" - if(Test-Path -Path $symbolExclusionfile) - { - Write-Host "SymbolExclusionFile exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" - } - else{ - Write-Host "Symbols Exclusion file does not exists" - Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" - } - - - task: PublishBuildArtifacts@1 - displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' - PublishLocation: Container - ArtifactName: ReleaseConfigs - - - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: - - template: /eng/common/templates/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion 3 - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' +- template: /eng/common/core-templates/job/publish-build-assets.yml + parameters: + is1ESPipeline: false - - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - - template: /eng/common/templates/steps/publish-logs.yml - parameters: - JobLabel: 'Publish_Artifacts_Logs' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/source-build.yml b/eng/common/templates/job/source-build.yml index 8a3deef2b7274..e44d47b1d760c 100644 --- a/eng/common/templates/job/source-build.yml +++ b/eng/common/templates/job/source-build.yml @@ -1,66 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. The template produces a server job with a - # default ID 'Source_Build_Complete' to put in a dependency list if necessary. - - # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. - jobNamePrefix: 'Source_Build' - - # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for - # managed-only repositories. This is an object with these properties: - # - # name: '' - # 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 - # 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. - # skipPublishValidation: false - # Disables publishing validation. By default, a check is performed to ensure no packages are - # published by source-build. - # container: '' - # A container to use. Runs in docker. - # pool: {} - # A pool to use. Runs directly on an agent. - # buildScript: '' - # Specifies the build script to invoke to perform the build in the repo. The default - # './build.sh' should work for typical Arcade repositories, but this is customizable for - # difficult situations. - # jobProperties: {} - # A list of job properties to inject at the top level, for potential extensibility beyond - # container and pool. - platform: {} - jobs: -- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} - displayName: Source-Build (${{ parameters.platform.name }}) - - ${{ each property in parameters.platform.jobProperties }}: - ${{ property.key }}: ${{ property.value }} - - ${{ if ne(parameters.platform.container, '') }}: - container: ${{ parameters.platform.container }} - - ${{ if eq(parameters.platform.pool, '') }}: - # The default VM host AzDO pool. This should be capable of running Docker containers: almost all - # source-build builds run in Docker, including the default managed platform. - # /eng/common/templates/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] - demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open - - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - demands: ImageOverride -equals Build.Ubuntu.1804.Amd64 - - ${{ if ne(parameters.platform.pool, '') }}: - pool: ${{ parameters.platform.pool }} - - workspace: - clean: all +- template: /eng/common/core-templates/job/source-build.yml + parameters: + is1ESPipeline: false - steps: - - template: /eng/common/templates/steps/source-build.yml - parameters: - platform: ${{ parameters.platform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/source-index-stage1.yml b/eng/common/templates/job/source-index-stage1.yml index b98202aa02d82..89f3291593cb7 100644 --- a/eng/common/templates/job/source-index-stage1.yml +++ b/eng/common/templates/job/source-index-stage1.yml @@ -1,67 +1,7 @@ -parameters: - runAsPublic: false - sourceIndexPackageVersion: 1.0.1-20230228.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 - condition: '' - dependsOn: '' - pool: '' - jobs: -- job: SourceIndexStage1 - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - variables: - - name: SourceIndexPackageVersion - value: ${{ parameters.sourceIndexPackageVersion }} - - name: SourceIndexPackageSource - value: ${{ parameters.sourceIndexPackageSource }} - - name: BinlogPath - value: ${{ parameters.binlogPath }} - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: source-dot-net stage1 variables - - template: /eng/common/templates/variables/pool-providers.yml - - ${{ if ne(parameters.pool, '') }}: - pool: ${{ parameters.pool }} - ${{ if eq(parameters.pool, '') }}: - pool: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: $(DncEngPublicBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64.open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - ${{ each preStep in parameters.preSteps }}: - - ${{ preStep }} - - - task: UseDotNet@2 - displayName: Use .NET Core SDK 6 - inputs: - packageType: sdk - version: 6.0.x - installationPath: $(Agent.TempDirectory)/dotnet - workingDirectory: $(Agent.TempDirectory) - - - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --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 +- template: /eng/common/core-templates/job/source-index-stage1.yml + parameters: + is1ESPipeline: false - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) - displayName: Upload stage1 artifacts to source index - env: - BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/jobs/codeql-build.yml b/eng/common/templates/jobs/codeql-build.yml index f7dc5ea4aaa63..517f24d6a52ce 100644 --- a/eng/common/templates/jobs/codeql-build.yml +++ b/eng/common/templates/jobs/codeql-build.yml @@ -1,31 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - jobs: -- template: /eng/common/templates/jobs/jobs.yml +- template: /eng/common/core-templates/jobs/codeql-build.yml parameters: - enableMicrobuild: false - enablePublishBuildArtifacts: false - enablePublishTestResults: false - enablePublishBuildAssets: false - enablePublishUsingPipelines: false - enableTelemetry: true + is1ESPipeline: false - variables: - - group: Publish-Build-Assets - # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in - # sync with the packages.config file. - - name: DefaultGuardianVersion - value: 0.109.0 - - name: GuardianPackagesConfigFile - value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config - - name: GuardianVersion - value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} - - jobs: ${{ parameters.jobs }} - + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/jobs/jobs.yml b/eng/common/templates/jobs/jobs.yml index 289bb2396ce83..388e9037b3e60 100644 --- a/eng/common/templates/jobs/jobs.yml +++ b/eng/common/templates/jobs/jobs.yml @@ -1,97 +1,7 @@ -parameters: - # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md - continueOnError: false - - # 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 - - # Optional: Parameters for source-build template. - # See /eng/common/templates/jobs/source-build.yml for options - sourceBuildParameters: [] - - graphFileGeneration: - # Optional: Enable generating the graph files at the end of the build - enabled: false - # Optional: Include toolset dependencies in the generated graph files - includeToolset: false - - # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job - jobs: [] - - # Optional: Override automatically derived dependsOn value for "publish build assets" job - publishBuildAssetsDependsOn: '' - - # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. - publishAssetsImmediately: 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: '' - - # Optional: should run as a public build even in the internal project - # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. - runAsPublic: false - - enableSourceIndex: false - sourceIndexParams: {} - -# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, -# and some (Microbuild) should only be applied to non-PR cases for internal builds. - jobs: -- ${{ each job in parameters.jobs }}: - - template: ../job/job.yml - parameters: - # pass along parameters - ${{ each parameter in parameters }}: - ${{ if ne(parameter.key, 'jobs') }}: - ${{ parameter.key }}: ${{ parameter.value }} - - # pass along job properties - ${{ each property in job }}: - ${{ if ne(property.key, 'job') }}: - ${{ property.key }}: ${{ property.value }} - - name: ${{ job.job }} - -- ${{ if eq(parameters.enableSourceBuild, true) }}: - - template: /eng/common/templates/jobs/source-build.yml - parameters: - allCompletedJobId: Source_Build_Complete - ${{ each parameter in parameters.sourceBuildParameters }}: - ${{ parameter.key }}: ${{ parameter.value }} - -- ${{ if eq(parameters.enableSourceIndex, 'true') }}: - - template: ../job/source-index-stage1.yml - parameters: - runAsPublic: ${{ parameters.runAsPublic }} - ${{ each parameter in parameters.sourceIndexParams }}: - ${{ 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, '')) }}: - - template: ../job/publish-build-assets.yml - parameters: - continueOnError: ${{ parameters.continueOnError }} - dependsOn: - - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.publishBuildAssetsDependsOn }}: - - ${{ job.job }} - - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: - - ${{ each job in parameters.jobs }}: - - ${{ job.job }} - - ${{ if eq(parameters.enableSourceBuild, true) }}: - - Source_Build_Complete +- template: /eng/common/core-templates/jobs/jobs.yml + parameters: + is1ESPipeline: false - runAsPublic: ${{ parameters.runAsPublic }} - publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} - publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} - enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} - artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} - signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/jobs/source-build.yml b/eng/common/templates/jobs/source-build.yml index a15b07eb51d9d..818d4c326dbbf 100644 --- a/eng/common/templates/jobs/source-build.yml +++ b/eng/common/templates/jobs/source-build.yml @@ -1,46 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. A job is created for each platform, as - # well as an optional server job that completes when all platform jobs complete. - - # The name of the "join" job for all source-build platforms. If set to empty string, the job is - # not included. Existing repo pipelines can use this job depend on all source-build jobs - # completing without maintaining a separate list of every single job ID: just depend on this one - # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. - allCompletedJobId: '' - - # See /eng/common/templates/job/source-build.yml - jobNamePrefix: 'Source_Build' - - # 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-stream8' - - # 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, - # one job runs on 'defaultManagedPlatform'. - platforms: [] - jobs: +- template: /eng/common/core-templates/jobs/source-build.yml + parameters: + is1ESPipeline: false -- ${{ if ne(parameters.allCompletedJobId, '') }}: - - job: ${{ parameters.allCompletedJobId }} - displayName: Source-Build Complete - pool: server - dependsOn: - - ${{ each platform in parameters.platforms }}: - - ${{ parameters.jobNamePrefix }}_${{ platform.name }} - - ${{ if eq(length(parameters.platforms), 0) }}: - - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} - -- ${{ each platform in parameters.platforms }}: - - template: /eng/common/templates/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ platform }} - -- ${{ if eq(length(parameters.platforms), 0) }}: - - template: /eng/common/templates/job/source-build.yml - parameters: - jobNamePrefix: ${{ parameters.jobNamePrefix }} - platform: ${{ parameters.defaultManagedPlatform }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index 173914f2364a7..7fa105875592c 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -1,22 +1,8 @@ variables: - - group: Publish-Build-Assets +- template: /eng/common/core-templates/post-build/common-variables.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: false - # Whether the build is internal or not - - name: IsInternalBuild - value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} - - # Default Maestro++ API Endpoint and API Version - - name: MaestroApiEndPoint - value: "https://maestro.dot.net" - - name: MaestroApiAccessToken - value: $(MaestroAccessToken) - - name: MaestroApiVersion - value: "2020-02-20" - - - name: SourceLinkCLIVersion - value: 3.0.0 - - name: SymbolToolVersion - value: 1.0.1 - - - name: runCodesignValidationInjection - value: false + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index aba44a25a3387..53ede714bdd20 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -1,281 +1,8 @@ -parameters: - # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. - # Publishing V1 is no longer supported - # Publishing V2 is no longer supported - # Publishing V3 is the default - - name: publishingInfraVersion - displayName: Which version of publishing should be used to promote the build definition? - type: number - default: 3 - values: - - 3 - - - name: BARBuildId - displayName: BAR Build Id - type: number - default: 0 - - - name: PromoteToChannelIds - displayName: Channel to promote BARBuildId to - type: string - default: '' - - - name: enableSourceLinkValidation - displayName: Enable SourceLink validation - type: boolean - default: false - - - name: enableSigningValidation - displayName: Enable signing validation - type: boolean - default: true - - - name: enableSymbolValidation - displayName: Enable symbol validation - type: boolean - default: false - - - name: enableNugetValidation - displayName: Enable NuGet validation - type: boolean - default: true - - - name: publishInstallersAndChecksums - displayName: Publish installers and checksums - type: boolean - default: true - - - name: SDLValidationParameters - type: object - default: - enable: false - publishGdn: false - continueOnError: false - params: '' - artifactNames: '' - downloadArtifacts: true - - # 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 - displayName: Symbol publishing additional parameters - type: string - default: '' - - - name: artifactsPublishingAdditionalParameters - displayName: Artifact publishing additional parameters - type: string - default: '' - - - name: signingValidationAdditionalParameters - displayName: Signing validation additional parameters - type: string - default: '' - - # Which stages should finish execution before post-build stages start - - name: validateDependsOn - type: object - default: - - build - - - name: publishDependsOn - type: object - default: - - Validate - - # Optional: Call asset publishing rather than running in a separate stage - - name: publishAssetsImmediately - type: boolean - default: false - stages: -- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - - stage: Validate - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Validate Build Assets - variables: - - template: common-variables.yml - - template: /eng/common/templates/variables/pool-providers.yml - jobs: - - job: - displayName: NuGet Validation - condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - - - job: - displayName: Signing Validation - condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - 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 - # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@1 - displayName: 'Authenticate to AzDO Feeds' - - # Signing validation will optionally work with the buildmanifest file which is downloaded from - # Azure DevOps above. - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task SigningValidation -restore -msbuildEngine vs - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' - /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' - ${{ parameters.signingValidationAdditionalParameters }} - - - template: ../steps/publish-logs.yml - parameters: - StageLabel: 'Validation' - JobLabel: 'Signing' - - - job: - displayName: SourceLink Validation - condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: BlobArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) - -GHCommit $(Build.SourceVersion) - -SourcelinkCliVersion $(SourceLinkCLIVersion) - continueOnError: true - - - template: /eng/common/templates/job/execute-sdl.yml - parameters: - enable: ${{ parameters.SDLValidationParameters.enable }} - publishGuardianDirectoryToPipeline: ${{ parameters.SDLValidationParameters.publishGdn }} - additionalParameters: ${{ parameters.SDLValidationParameters.params }} - continueOnError: ${{ parameters.SDLValidationParameters.continueOnError }} - artifactNames: ${{ parameters.SDLValidationParameters.artifactNames }} - downloadArtifacts: ${{ parameters.SDLValidationParameters.downloadArtifacts }} - -- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: - - stage: publish_using_darc - ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: - dependsOn: ${{ parameters.publishDependsOn }} - ${{ else }}: - dependsOn: ${{ parameters.validateDependsOn }} - displayName: Publish using Darc - variables: - - template: common-variables.yml - - template: /eng/common/templates/variables/pool-providers.yml - jobs: - - job: - displayName: Publish Using Darc - timeoutInMinutes: 120 - pool: - # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - name: VSEngSS-MicroBuild2022-1ES - demands: Cmd - # If it's not devdiv, it's dnceng - ${{ else }}: - name: NetCore1ESPool-Publishing-Internal - demands: ImageOverride -equals windows.vs2019.amd64 - steps: - - template: setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - - - task: NuGetAuthenticate@1 +- template: /eng/common/core-templates/post-build/post-build.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: false - - task: PowerShell@2 - displayName: Publish Using Darc - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) - -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} - -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' - -MaestroToken '$(MaestroApiAccessToken)' - -WaitPublishingFinish true - -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' - -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml index 0c87f149a4ad7..a79fab5b441e8 100644 --- a/eng/common/templates/post-build/setup-maestro-vars.yml +++ b/eng/common/templates/post-build/setup-maestro-vars.yml @@ -1,70 +1,8 @@ -parameters: - BARBuildId: '' - PromoteToChannelIds: '' - steps: - - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: - - task: DownloadBuildArtifacts@0 - displayName: Download Release Configs - inputs: - buildType: current - artifactName: ReleaseConfigs - checkDownloadedFiles: true - - - task: PowerShell@2 - name: setReleaseVars - displayName: Set Release Configs Vars - inputs: - targetType: inline - pwsh: true - script: | - try { - if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { - $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt - - $BarId = $Content | Select -Index 0 - $Channels = $Content | Select -Index 1 - $IsStableBuild = $Content | Select -Index 2 - - $AzureDevOpsProject = $Env:System_TeamProject - $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId - $AzureDevOpsBuildId = $Env:Build_BuildId - } - else { - $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" - - $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' - $apiHeaders.Add('Accept', 'application/json') - $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") - - $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } - - $BarId = $Env:BARBuildId - $Channels = $Env:PromoteToMaestroChannels -split "," - $Channels = $Channels -join "][" - $Channels = "[$Channels]" - - $IsStableBuild = $buildInfo.stable - $AzureDevOpsProject = $buildInfo.azureDevOpsProject - $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId - $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId - } - - Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" - Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" - Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" +- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + # Specifies whether to use 1ES + is1ESPipeline: false - Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" - Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" - Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" - } - catch { - Write-Host $_ - Write-Host $_.Exception - Write-Host $_.ScriptStackTrace - exit 1 - } - env: - MAESTRO_API_TOKEN: $(MaestroApiAccessToken) - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} \ No newline at end of file diff --git a/eng/common/templates/steps/add-build-to-channel.yml b/eng/common/templates/steps/add-build-to-channel.yml index f67a210d62f3e..42bbba161b9b6 100644 --- a/eng/common/templates/steps/add-build-to-channel.yml +++ b/eng/common/templates/steps/add-build-to-channel.yml @@ -1,13 +1,7 @@ -parameters: - ChannelId: 0 - steps: -- task: PowerShell@2 - displayName: Add Build to Channel - inputs: - filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 - arguments: -BuildId $(BARBuildId) - -ChannelId ${{ parameters.ChannelId }} - -MaestroApiAccessToken $(MaestroApiAccessToken) - -MaestroApiEndPoint $(MaestroApiEndPoint) - -MaestroApiVersion $(MaestroApiVersion) +- template: /eng/common/core-templates/steps/add-build-to-channel.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/build-reason.yml b/eng/common/templates/steps/build-reason.yml deleted file mode 100644 index eba58109b52c9..0000000000000 --- a/eng/common/templates/steps/build-reason.yml +++ /dev/null @@ -1,12 +0,0 @@ -# build-reason.yml -# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons -# to include steps (',' separated). -parameters: - conditions: '' - steps: [] - -steps: - - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: - - ${{ parameters.steps }} - - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml index cbba0596709da..c12a5f8d21d76 100644 --- a/eng/common/templates/steps/component-governance.yml +++ b/eng/common/templates/steps/component-governance.yml @@ -1,13 +1,7 @@ -parameters: - disableComponentGovernance: false - componentGovernanceIgnoreDirectories: '' - steps: -- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" - displayName: Set skipComponentGovernanceDetection variable -- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - - task: ComponentGovernanceComponentDetection@0 - continueOnError: true - inputs: - ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file +- template: /eng/common/core-templates/steps/component-governance.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/execute-codeql.yml b/eng/common/templates/steps/execute-codeql.yml deleted file mode 100644 index 3930b1630214b..0000000000000 --- a/eng/common/templates/steps/execute-codeql.yml +++ /dev/null @@ -1,32 +0,0 @@ -parameters: - # Language that should be analyzed. Defaults to csharp - language: csharp - # Build Commands - buildCommands: '' - overrideParameters: '' # Optional: to override values for parameters. - additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' - # Optional: if specified, restore and use this version of Guardian instead of the default. - overrideGuardianVersion: '' - # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth - # diagnosis of problems with specific tool configurations. - publishGuardianDirectoryToPipeline: false - # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL - # parameters rather than relying on YAML. It may be better to use a local script, because you can - # reproduce results locally without piecing together a command based on the YAML. - executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' - # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named - # 'continueOnError', the parameter value is not correctly picked up. - # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter - # optional: determines whether to continue the build if the step errors; - sdlContinueOnError: false - -steps: -- template: /eng/common/templates/steps/execute-sdl.yml - parameters: - overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} - executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} - overrideParameters: ${{ parameters.overrideParameters }} - additionalParameters: '${{ parameters.additionalParameters }} - -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")' - publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} - sdlContinueOnError: ${{ parameters.sdlContinueOnError }} \ No newline at end of file diff --git a/eng/common/templates/steps/execute-sdl.yml b/eng/common/templates/steps/execute-sdl.yml deleted file mode 100644 index 07426fde05d82..0000000000000 --- a/eng/common/templates/steps/execute-sdl.yml +++ /dev/null @@ -1,88 +0,0 @@ -parameters: - overrideGuardianVersion: '' - executeAllSdlToolsScript: '' - overrideParameters: '' - additionalParameters: '' - publishGuardianDirectoryToPipeline: false - sdlContinueOnError: false - condition: '' - -steps: -- task: NuGetAuthenticate@1 - inputs: - nuGetServiceConnections: GuardianConnect - -- task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - -- ${{ if ne(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian (Overridden) - -- ${{ if eq(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian - -- ${{ if ne(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} - displayName: Execute SDL (Overridden) - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if eq(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} - -GuardianCliLocation $(GuardianCliLocation) - -NugetPackageDirectory $(Build.SourcesDirectory)\.packages - -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) - ${{ parameters.additionalParameters }} - displayName: Execute SDL - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: - # We want to publish the Guardian results and configuration for easy diagnosis. However, the - # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default - # tooling files. Some of these files are large and aren't useful during an investigation, so - # exclude them by simply deleting them before publishing. (As of writing, there is no documented - # way to selectively exclude a dir from the pipeline artifact publish task.) - - task: DeleteFiles@1 - displayName: Delete Guardian dependencies to avoid uploading - inputs: - SourceFolder: $(Agent.BuildDirectory)/.gdn - Contents: | - c - i - condition: succeededOrFailed() - - - publish: $(Agent.BuildDirectory)/.gdn - artifact: GuardianConfiguration - displayName: Publish GuardianConfiguration - condition: succeededOrFailed() - - # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration - # with the "SARIF SAST Scans Tab" Azure DevOps extension - - task: CopyFiles@2 - displayName: Copy SARIF files - inputs: - flattenFolders: true - sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ - contents: '**/*.sarif' - targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs - condition: succeededOrFailed() - - # Use PublishBuildArtifacts because the SARIF extension only checks this case - # see microsoft/sarif-azuredevops-extension#4 - - task: PublishBuildArtifacts@1 - displayName: Publish SARIF files to CodeAnalysisLogs container - inputs: - pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs - artifactName: CodeAnalysisLogs - condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml index 2b21eae427328..26dc00a2e0f31 100644 --- a/eng/common/templates/steps/generate-sbom.yml +++ b/eng/common/templates/steps/generate-sbom.yml @@ -1,48 +1,7 @@ -# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. -# PackageName - The name of the package this SBOM represents. -# PackageVersion - The version of the package this SBOM represents. -# ManifestDirPath - The path of the directory where the generated manifest files will be placed -# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. - -parameters: - PackageVersion: 8.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - PackageName: '.NET' - ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom - IgnoreDirectories: '' - sbomContinueOnError: true - steps: -- task: PowerShell@2 - displayName: Prep for SBOM generation in (Non-linux) - condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) - inputs: - filePath: ./eng/common/generate-sbom-prep.ps1 - arguments: ${{parameters.manifestDirPath}} - -# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 -- script: | - chmod +x ./eng/common/generate-sbom-prep.sh - ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} - displayName: Prep for SBOM generation in (Linux) - condition: eq(variables['Agent.Os'], 'Linux') - continueOnError: ${{ parameters.sbomContinueOnError }} - -- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: 'Generate SBOM manifest' - continueOnError: ${{ parameters.sbomContinueOnError }} - inputs: - PackageName: ${{ parameters.packageName }} - BuildDropPath: ${{ parameters.buildDropPath }} - PackageVersion: ${{ parameters.packageVersion }} - ManifestDirPath: ${{ parameters.manifestDirPath }} - ${{ if ne(parameters.IgnoreDirectories, '') }}: - AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' - -- task: PublishPipelineArtifact@1 - displayName: Publish SBOM manifest - continueOnError: ${{parameters.sbomContinueOnError}} - inputs: - targetPath: '${{parameters.manifestDirPath}}' - artifactName: $(ARTIFACT_NAME) +- template: /eng/common/core-templates/steps/generate-sbom.yml + parameters: + is1ESPipeline: false + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/publish-build-artifacts.yml b/eng/common/templates/steps/publish-build-artifacts.yml new file mode 100644 index 0000000000000..6428a98dfef68 --- /dev/null +++ b/eng/common/templates/steps/publish-build-artifacts.yml @@ -0,0 +1,40 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: false + +- name: displayName + type: string + default: 'Publish to Build Artifact' + +- name: condition + type: string + default: succeeded() + +- name: artifactName + type: string + +- name: pathToPublish + type: string + +- name: continueOnError + type: boolean + default: false + +- name: publishLocation + type: string + default: 'Container' + +steps: +- ${{ if eq(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates cannot be referenced from a 1ES managed template': error +- task: PublishBuildArtifacts@1 + displayName: ${{ parameters.displayName }} + condition: ${{ parameters.condition }} + ${{ if parameters.continueOnError }}: + continueOnError: ${{ parameters.continueOnError }} + inputs: + PublishLocation: ${{ parameters.publishLocation }} + PathtoPublish: ${{ parameters.pathToPublish }} + ${{ if parameters.artifactName }}: + ArtifactName: ${{ parameters.artifactName }} \ No newline at end of file diff --git a/eng/common/templates/steps/publish-logs.yml b/eng/common/templates/steps/publish-logs.yml index 88f238f36bfd8..4ea86bd882355 100644 --- a/eng/common/templates/steps/publish-logs.yml +++ b/eng/common/templates/steps/publish-logs.yml @@ -1,23 +1,7 @@ -parameters: - StageLabel: '' - JobLabel: '' - steps: -- task: Powershell@2 - displayName: Prepare Binlogs to Upload - inputs: - targetType: inline - script: | - New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ - continueOnError: true - condition: always() +- template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: false -- task: PublishBuildArtifacts@1 - displayName: Publish Logs - inputs: - PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' - PublishLocation: Container - ArtifactName: PostBuildLogs - continueOnError: true - condition: always() + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/publish-pipeline-artifacts.yml b/eng/common/templates/steps/publish-pipeline-artifacts.yml new file mode 100644 index 0000000000000..5dd698b212fc6 --- /dev/null +++ b/eng/common/templates/steps/publish-pipeline-artifacts.yml @@ -0,0 +1,34 @@ +parameters: +- name: is1ESPipeline + type: boolean + default: false + +- name: args + type: object + default: {} + +steps: +- ${{ if eq(parameters.is1ESPipeline, true) }}: + - 'eng/common/templates cannot be referenced from a 1ES managed template': error +- task: PublishPipelineArtifact@1 + displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }} + ${{ if parameters.args.condition }}: + condition: ${{ parameters.args.condition }} + ${{ else }}: + condition: succeeded() + ${{ if parameters.args.continueOnError }}: + continueOnError: ${{ parameters.args.continueOnError }} + inputs: + targetPath: ${{ parameters.args.targetPath }} + ${{ if parameters.args.artifactName }}: + artifactName: ${{ parameters.args.artifactName }} + ${{ if parameters.args.publishLocation }}: + publishLocation: ${{ parameters.args.publishLocation }} + ${{ if parameters.args.fileSharePath }}: + fileSharePath: ${{ parameters.args.fileSharePath }} + ${{ if parameters.args.Parallel }}: + parallel: ${{ parameters.args.Parallel }} + ${{ if parameters.args.parallelCount }}: + parallelCount: ${{ parameters.args.parallelCount }} + ${{ if parameters.args.properties }}: + properties: ${{ parameters.args.properties }} \ No newline at end of file diff --git a/eng/common/templates/steps/retain-build.yml b/eng/common/templates/steps/retain-build.yml index 83d97a26a01ff..8e841ace3d293 100644 --- a/eng/common/templates/steps/retain-build.yml +++ b/eng/common/templates/steps/retain-build.yml @@ -1,28 +1,7 @@ -parameters: - # Optional azure devops PAT with build execute permissions for the build's organization, - # only needed if the build that should be retained ran on a different organization than - # the pipeline where this template is executing from - Token: '' - # Optional BuildId to retain, defaults to the current running build - BuildId: '' - # Azure devops Organization URI for the build in the https://dev.azure.com/ format. - # Defaults to the organization the current pipeline is running on - AzdoOrgUri: '$(System.CollectionUri)' - # Azure devops project for the build. Defaults to the project the current pipeline is running on - AzdoProject: '$(System.TeamProject)' - steps: - - task: powershell@2 - inputs: - targetType: 'filePath' - filePath: eng/common/retain-build.ps1 - pwsh: true - arguments: > - -AzdoOrgUri: ${{parameters.AzdoOrgUri}} - -AzdoProject ${{parameters.AzdoProject}} - -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} - -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} - displayName: Enable permanent build retention - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - BUILD_ID: $(Build.BuildId) \ No newline at end of file +- template: /eng/common/core-templates/steps/retain-build.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/run-on-unix.yml b/eng/common/templates/steps/run-on-unix.yml deleted file mode 100644 index e1733814f65dc..0000000000000 --- a/eng/common/templates/steps/run-on-unix.yml +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - agentOs: '' - steps: [] - -steps: -- ${{ if ne(parameters.agentOs, 'Windows_NT') }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/run-on-windows.yml b/eng/common/templates/steps/run-on-windows.yml deleted file mode 100644 index 73e7e9c275a1f..0000000000000 --- a/eng/common/templates/steps/run-on-windows.yml +++ /dev/null @@ -1,7 +0,0 @@ -parameters: - agentOs: '' - steps: [] - -steps: -- ${{ if eq(parameters.agentOs, 'Windows_NT') }}: - - ${{ parameters.steps }} diff --git a/eng/common/templates/steps/run-script-ifequalelse.yml b/eng/common/templates/steps/run-script-ifequalelse.yml deleted file mode 100644 index 3d1242f5587c8..0000000000000 --- a/eng/common/templates/steps/run-script-ifequalelse.yml +++ /dev/null @@ -1,33 +0,0 @@ -parameters: - # if parameter1 equals parameter 2, run 'ifScript' command, else run 'elsescript' command - parameter1: '' - parameter2: '' - ifScript: '' - elseScript: '' - - # name of script step - name: Script - - # display name of script step - displayName: If-Equal-Else Script - - # environment - env: {} - - # conditional expression for step execution - condition: '' - -steps: -- ${{ if and(ne(parameters.ifScript, ''), eq(parameters.parameter1, parameters.parameter2)) }}: - - script: ${{ parameters.ifScript }} - name: ${{ parameters.name }} - displayName: ${{ parameters.displayName }} - env: ${{ parameters.env }} - condition: ${{ parameters.condition }} - -- ${{ if and(ne(parameters.elseScript, ''), ne(parameters.parameter1, parameters.parameter2)) }}: - - script: ${{ parameters.elseScript }} - name: ${{ parameters.name }} - displayName: ${{ parameters.displayName }} - env: ${{ parameters.env }} - condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates/steps/send-to-helix.yml b/eng/common/templates/steps/send-to-helix.yml index 3eb7e2d5f840c..39f99fc2762d0 100644 --- a/eng/common/templates/steps/send-to-helix.yml +++ b/eng/common/templates/steps/send-to-helix.yml @@ -1,91 +1,7 @@ -# Please remember to update the documentation if you make changes to these parameters! -parameters: - HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ - HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' - HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number - HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues - HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group - HelixConfiguration: '' # optional -- additional property attached to a job - HelixPreCommands: '' # optional -- commands to run before Helix work item execution - HelixPostCommands: '' # optional -- commands to run after Helix work item execution - WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects - WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects - WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects - CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload - XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true - XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects - XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects - XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner - XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects - IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion - DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json - WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." - IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set - HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) - Creator: '' # optional -- if the build is external, use this to specify who is sending the job - DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO - condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() - continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false - steps: - - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' - displayName: ${{ parameters.DisplayNamePrefix }} (Windows) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Unix) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - HelixAccessToken: ${{ parameters.HelixAccessToken }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} +- template: /eng/common/core-templates/steps/send-to-helix.yml + parameters: + is1ESPipeline: false + + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/source-build.yml b/eng/common/templates/steps/source-build.yml index 41bbb915736a6..23c1d6f4e9f8d 100644 --- a/eng/common/templates/steps/source-build.yml +++ b/eng/common/templates/steps/source-build.yml @@ -1,129 +1,7 @@ -parameters: - # This template adds arcade-powered source-build to CI. - - # This is a 'steps' template, and is intended for advanced scenarios where the existing build - # infra has a careful build methodology that must be followed. For example, a repo - # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline - # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to - # GitHub. Using this steps template leaves room for that infra to be included. - - # Defines the platform on which to run the steps. See 'eng/common/templates/job/source-build.yml' - # for details. The entire object is described in the 'job' template for simplicity, even though - # the usage of the properties on this object is split between the 'job' and 'steps' templates. - platform: {} - steps: -# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) -- script: | - set -x - df -h - - # If building on the internal project, the artifact feeds variable may be available (usually only if needed) - # In that case, call the feed setup script to add internal feeds corresponding to public ones. - # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. - # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those - # changes. - internalRestoreArgs= - if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then - # Temporarily work around https://github.com/dotnet/arcade/issues/7709 - chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh - $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) - 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)' - fi - - buildConfig=Release - # Check if AzDO substitutes in a build config from a variable, and use it if so. - if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then - 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 - fi - - ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ - --configuration $buildConfig \ - --restore --build --pack $publishArgs -bl \ - $officialBuildArgs \ - $internalRuntimeDownloadArgs \ - $internalRestoreArgs \ - $targetRidArgs \ - $runtimeOsArgs \ - $baseOsArgs \ - /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ - /p:ArcadeBuildFromSource=true \ - /p:AssetManifestFileName=$assetManifestFileName - displayName: Build - -# Upload build logs for diagnosis. -- task: CopyFiles@2 - displayName: Prepare BuildLogs staging directory - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - **/*.log - **/*.binlog - artifacts/source-build/self/prebuilt-report/** - TargetFolder: '$(Build.StagingDirectory)/BuildLogs' - CleanTargetFolder: true - continueOnError: true - condition: succeededOrFailed() - -- task: PublishPipelineArtifact@1 - displayName: Publish BuildLogs - inputs: - targetPath: '$(Build.StagingDirectory)/BuildLogs' - artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) - continueOnError: true - condition: succeededOrFailed() +- template: /eng/common/core-templates/steps/source-build.yml + parameters: + is1ESPipeline: false -# 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 -- task: ComponentGovernanceComponentDetection@0 - displayName: Component Detection (Exclude upstream cache) - inputs: - ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache' + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/steps/telemetry-end.yml b/eng/common/templates/steps/telemetry-end.yml deleted file mode 100644 index fadc04ca1b9a3..0000000000000 --- a/eng/common/templates/steps/telemetry-end.yml +++ /dev/null @@ -1,102 +0,0 @@ -parameters: - maxRetries: 5 - retryDelay: 10 # in seconds - -steps: -- bash: | - if [ "$AGENT_JOBSTATUS" = "Succeeded" ] || [ "$AGENT_JOBSTATUS" = "PartiallySucceeded" ]; then - errorCount=0 - else - errorCount=1 - fi - warningCount=0 - - curlStatus=1 - retryCount=0 - # retry loop to harden against spotty telemetry connections - # we don't retry successes and 4xx client errors - until [[ $curlStatus -eq 0 || ( $curlStatus -ge 400 && $curlStatus -le 499 ) || $retryCount -ge $MaxRetries ]] - do - if [ $retryCount -gt 0 ]; then - echo "Failed to send telemetry to Helix; waiting $RetryDelay seconds before retrying..." - sleep $RetryDelay - fi - - # create a temporary file for curl output - res=`mktemp` - - curlResult=` - curl --verbose --output $res --write-out "%{http_code}"\ - -H 'Content-Type: application/json' \ - -H "X-Helix-Job-Token: $Helix_JobToken" \ - -H 'Content-Length: 0' \ - -X POST -G "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$Helix_WorkItemId/finish" \ - --data-urlencode "errorCount=$errorCount" \ - --data-urlencode "warningCount=$warningCount"` - curlStatus=$? - - if [ $curlStatus -eq 0 ]; then - if [ $curlResult -gt 299 ] || [ $curlResult -lt 200 ]; then - curlStatus=$curlResult - fi - fi - - let retryCount++ - done - - if [ $curlStatus -ne 0 ]; then - echo "Failed to Send Build Finish information after $retryCount retries" - vstsLogOutput="vso[task.logissue type=error;sourcepath=templates/steps/telemetry-end.yml;code=1;]Failed to Send Build Finish information: $curlStatus" - echo "##$vstsLogOutput" - exit 1 - fi - displayName: Send Unix Build End Telemetry - env: - # defined via VSTS variables in start-job.sh - Helix_JobToken: $(Helix_JobToken) - Helix_WorkItemId: $(Helix_WorkItemId) - MaxRetries: ${{ parameters.maxRetries }} - RetryDelay: ${{ parameters.retryDelay }} - condition: and(always(), ne(variables['Agent.Os'], 'Windows_NT')) -- powershell: | - if (($env:Agent_JobStatus -eq 'Succeeded') -or ($env:Agent_JobStatus -eq 'PartiallySucceeded')) { - $ErrorCount = 0 - } else { - $ErrorCount = 1 - } - $WarningCount = 0 - - # Basic retry loop to harden against server flakiness - $retryCount = 0 - while ($retryCount -lt $env:MaxRetries) { - try { - Invoke-RestMethod -Uri "https://helix.dot.net/api/2018-03-14/telemetry/job/build/$env:Helix_WorkItemId/finish?errorCount=$ErrorCount&warningCount=$WarningCount" -Method Post -ContentType "application/json" -Body "" ` - -Headers @{ 'X-Helix-Job-Token'=$env:Helix_JobToken } - break - } - catch { - $statusCode = $_.Exception.Response.StatusCode.value__ - if ($statusCode -ge 400 -and $statusCode -le 499) { - Write-Host "##vso[task.logissue]error Failed to send telemetry to Helix (status code $statusCode); not retrying (4xx client error)" - Write-Host "##vso[task.logissue]error ", $_.Exception.GetType().FullName, $_.Exception.Message - exit 1 - } - Write-Host "Failed to send telemetry to Helix (status code $statusCode); waiting $env:RetryDelay seconds before retrying..." - $retryCount++ - sleep $env:RetryDelay - continue - } - } - - if ($retryCount -ge $env:MaxRetries) { - Write-Host "##vso[task.logissue]error Failed to send telemetry to Helix after $retryCount retries." - exit 1 - } - displayName: Send Windows Build End Telemetry - env: - # defined via VSTS variables in start-job.ps1 - Helix_JobToken: $(Helix_JobToken) - Helix_WorkItemId: $(Helix_WorkItemId) - MaxRetries: ${{ parameters.maxRetries }} - RetryDelay: ${{ parameters.retryDelay }} - condition: and(always(),eq(variables['Agent.Os'], 'Windows_NT')) diff --git a/eng/common/templates/steps/telemetry-start.yml b/eng/common/templates/steps/telemetry-start.yml deleted file mode 100644 index 32c01ef0b553b..0000000000000 --- a/eng/common/templates/steps/telemetry-start.yml +++ /dev/null @@ -1,241 +0,0 @@ -parameters: - helixSource: 'undefined_defaulted_in_telemetry.yml' - helixType: 'undefined_defaulted_in_telemetry.yml' - buildConfig: '' - runAsPublic: false - maxRetries: 5 - retryDelay: 10 # in seconds - -steps: -- ${{ if and(eq(parameters.runAsPublic, 'false'), not(eq(variables['System.TeamProject'], 'public'))) }}: - - task: AzureKeyVault@1 - inputs: - azureSubscription: 'HelixProd_KeyVault' - KeyVaultName: HelixProdKV - SecretsFilter: 'HelixApiAccessToken' - condition: always() -- bash: | - # create a temporary file - jobInfo=`mktemp` - - # write job info content to temporary file - cat > $jobInfo < /dev/null; then echo "Curl failed; dumping some information about dotnet.microsoft.com for later investigation" - echo | openssl s_client -showcerts -servername dotnet.microsoft.com -connect dotnet.microsoft.com:443 + echo | openssl s_client -showcerts -servername dotnet.microsoft.com -connect dotnet.microsoft.com:443 || true fi echo "Will now retry the same URL with verbose logging." with_retries curl "$install_script_url" -sSL --verbose --retry 10 --create-dirs -o "$install_script" || { @@ -343,7 +341,7 @@ function InitializeBuildTool { _InitializeBuildToolCommand="msbuild" # use override if it exists - commonly set by source-build if [[ "${_OverrideArcadeInitializeBuildToolFramework:-x}" == "x" ]]; then - _InitializeBuildToolFramework="net8.0" + _InitializeBuildToolFramework="net9.0" else _InitializeBuildToolFramework="${_OverrideArcadeInitializeBuildToolFramework}" fi @@ -458,12 +456,10 @@ function MSBuild { local possiblePaths=() possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.ArcadeLogging.dll" ) possiblePaths+=( "$toolset_dir/$_InitializeBuildToolFramework/Microsoft.DotNet.Arcade.Sdk.dll" ) - possiblePaths+=( "$toolset_dir/netcoreapp2.1/Microsoft.DotNet.ArcadeLogging.dll" ) - possiblePaths+=( "$toolset_dir/netcoreapp2.1/Microsoft.DotNet.Arcade.Sdk.dll" ) - possiblePaths+=( "$toolset_dir/netcoreapp3.1/Microsoft.DotNet.ArcadeLogging.dll" ) - possiblePaths+=( "$toolset_dir/netcoreapp3.1/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 @@ -510,7 +506,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. - if [[ "$ci" == "true" && -n ${SYSTEM_TEAMPROJECT:-} ]]; then + # 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 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/eng/config/PublishData.json b/eng/config/PublishData.json index 6c568c4301a1c..bb43a7848c75a 100644 --- a/eng/config/PublishData.json +++ b/eng/config/PublishData.json @@ -205,7 +205,17 @@ "vsBranch": "rel/d17.10", "vsMajorVersion": 17, "insertionCreateDraftPR": false, - "insertionTitlePrefix": "[d17.10 P3]" + "insertionTitlePrefix": "[d17.10]" + }, + "release/dev17.11": { + "nugetKind": [ + "Shipping", + "NonShipping" + ], + "vsBranch": "rel/d17.11", + "vsMajorVersion": 17, + "insertionCreateDraftPR": false, + "insertionTitlePrefix": "[d17.11 P1]" }, "main": { "nugetKind": [ @@ -215,7 +225,7 @@ "vsBranch": "main", "vsMajorVersion": 17, "insertionCreateDraftPR": false, - "insertionTitlePrefix": "[d17.11 P1]" + "insertionTitlePrefix": "[d17.11 P2]" }, "dev/andrha/telemetry": { "nugetKind": [ @@ -227,6 +237,16 @@ "insertionCreateDraftPR": true, "insertionTitlePrefix": "[Telemetry Validation]" }, + "dev/jorobich/pr-val-v3-publishing": { + "nugetKind": [ + "Shipping", + "NonShipping" + ], + "vsBranch": "main", + "vsMajorVersion": 17, + "insertionCreateDraftPR": true, + "insertionTitlePrefix": "[PR Validation]" + }, "demo/razor-lexer": { "nugetKind": [ "Shipping", diff --git a/eng/pipelines/test-windows-job-single-machine.yml b/eng/pipelines/test-windows-job-single-machine.yml index 5546846e4d8fc..75acc4af38da4 100644 --- a/eng/pipelines/test-windows-job-single-machine.yml +++ b/eng/pipelines/test-windows-job-single-machine.yml @@ -28,6 +28,15 @@ jobs: steps: - checkout: none + # A .NET 9 runtime is needed since our unit tests target net9.0 + - task: UseDotNet@2 + displayName: 'Install .NET 9 Runtime' + inputs: + packageType: runtime + version: 9.0.0-preview.3.24172.9 + includePreviewVersions: true + installationPath: '$(Build.SourcesDirectory)/.dotnet' + - task: DownloadPipelineArtifact@2 displayName: Download Test Payload inputs: diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props index 99698db200629..3598b4bdc7671 100644 --- a/eng/targets/Settings.props +++ b/eng/targets/Settings.props @@ -58,6 +58,8 @@ false true + + <_SkipUpgradeNetAnalyzersNuGetWarning>true diff --git a/eng/targets/TargetFrameworks.props b/eng/targets/TargetFrameworks.props index 20b3ce78a455f..8493c1046cb51 100644 --- a/eng/targets/TargetFrameworks.props +++ b/eng/targets/TargetFrameworks.props @@ -18,6 +18,7 @@ net8.0 net7.0;net8.0 net6.0 + net9.0 + + $(NetMinimum) $(NetPrevious) $(NetCurrent);$(NetPrevious) $(NetCurrent);$(NetPrevious) $(NetPrevious) + $(NetPrevious) @@ -52,6 +56,7 @@ $(NetCurrent);$(NetPrevious) $(NetCurrent);$(NetPrevious) $(NetCurrent) + $(NetCurrent) diff --git a/global.json b/global.json index dd2c371a82896..6ed022b17724a 100644 --- a/global.json +++ b/global.json @@ -1,19 +1,18 @@ { "sdk": { - "version": "8.0.101", + "version": "9.0.100-preview.3.24204.13", "allowPrerelease": false, "rollForward": "patch" }, "tools": { - "dotnet": "8.0.101", + "dotnet": "9.0.100-preview.3.24204.13", "vs": { "version": "17.8.0" - }, - "xcopy-msbuild": "17.8.1-2" + } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24225.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24225.1", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24270.3", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24270.3", "Microsoft.Build.Traversal": "3.4.0" } } diff --git a/src/Analyzers/CSharp/Analyzers/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementDiagnosticAnalyzer.cs index 8972833f5689d..d7aec18cecdf8 100644 --- a/src/Analyzers/CSharp/Analyzers/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementDiagnosticAnalyzer.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.NewLines.ArrowExpressionClausePlacement; @@ -52,8 +53,8 @@ private void Recurse(SyntaxTreeAnalysisContext context, NotificationOption2 noti if (!context.ShouldAnalyzeSpan(child.Span)) continue; - if (child.IsNode) - Recurse(context, notificationOption, child.AsNode()!); + if (child.AsNode(out var childNode)) + Recurse(context, notificationOption, childNode); } } diff --git a/src/Analyzers/CSharp/Analyzers/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementDiagnosticAnalyzer.cs index d43ac7418c66e..ac3e534a24d81 100644 --- a/src/Analyzers/CSharp/Analyzers/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementDiagnosticAnalyzer.cs @@ -7,10 +7,10 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeStyle; -using Microsoft.CodeAnalysis.CSharp.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.NewLines.ConstructorInitializerPlacement; @@ -58,8 +58,8 @@ private void Recurse(SyntaxTreeAnalysisContext context, NotificationOption2 noti if (!context.ShouldAnalyzeSpan(child.Span)) continue; - if (child.IsNode) - Recurse(context, notificationOption, child.AsNode()!); + if (child.AsNode(out var childNode)) + Recurse(context, notificationOption, childNode); } } diff --git a/src/Analyzers/CSharp/Analyzers/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementDiagnosticAnalyzer.cs index 8aa7f141c6568..a7af57f730c9f 100644 --- a/src/Analyzers/CSharp/Analyzers/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementDiagnosticAnalyzer.cs @@ -7,9 +7,9 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp.CodeStyle; -using Microsoft.CodeAnalysis.CSharp.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.NewLines.EmbeddedStatementPlacement; @@ -63,8 +63,8 @@ private void Recurse(SyntaxTreeAnalysisContext context, NotificationOption2 noti if (!context.ShouldAnalyzeSpan(child.Span)) continue; - if (child.IsNode) - Recurse(context, notificationOption, child.AsNode()!); + if (child.AsNode(out var childNode)) + Recurse(context, notificationOption, childNode); } } diff --git a/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer.cs index e7f238402a12d..f1ed887255e6a 100644 --- a/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer.cs @@ -72,10 +72,10 @@ private void ProcessSyntaxTree( if (!current.ContainsDirectives) continue; - if (current.IsNode) + if (current.AsNode(out var childNode)) { // Add the nodes in reverse so we continue walking in a depth-first fashion. - foreach (var child in current.AsNode()!.ChildNodesAndTokens().Reverse()) + foreach (var child in childNode.ChildNodesAndTokens().Reverse()) stack.Push(child); } else if (current.IsToken) diff --git a/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs index 6fd5116709f92..8bc17b8207a5b 100644 --- a/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UsePatternCombinators/CSharpUsePatternCombinatorsDiagnosticAnalyzer.cs @@ -130,10 +130,10 @@ private static bool IsTopmostExpression(ExpressionSyntax node) { return node.WalkUpParentheses().Parent switch { - LambdaExpressionSyntax _ => true, - AssignmentExpressionSyntax _ => true, - ConditionalExpressionSyntax _ => true, - ExpressionSyntax _ => false, + LambdaExpressionSyntax => true, + AssignmentExpressionSyntax => true, + ConditionalExpressionSyntax => true, + ExpressionSyntax => false, _ => true }; } @@ -142,10 +142,10 @@ private static bool IsTrivial(AnalyzedPattern pattern) { return pattern switch { - Not { Pattern: Constant _ } => true, - Not { Pattern: Source { PatternSyntax: ConstantPatternSyntax _ } } => true, - Not _ => false, - Binary _ => false, + Not { Pattern: Constant } => true, + Not { Pattern: Source { PatternSyntax: ConstantPatternSyntax } } => true, + Not => false, + Binary => false, _ => true }; } diff --git a/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs index 6c1872cccbd0e..3d490403c7d1e 100644 --- a/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs @@ -233,8 +233,8 @@ private static bool ContainsVariableDeclaration( foreach (var child in current.ChildNodesAndTokens()) { - if (child.IsNode) - stack.Push(child.AsNode()!); + if (child.AsNode(out var childNode)) + stack.Push(childNode); } } diff --git a/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs index b23010c17f6a6..c24bdc78fec87 100644 --- a/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/MakeMethodAsynchronous/CSharpMakeMethodAsynchronousCodeFixProvider.cs @@ -28,6 +28,8 @@ internal class CSharpMakeMethodAsynchronousCodeFixProvider : AbstractMakeMethodA private const string CS4034 = nameof(CS4034); // The 'await' operator can only be used within an async lambda expression. Consider marking this method with the 'async' modifier. private const string CS0246 = nameof(CS0246); // The type or namespace name 'await' could not be found + private static readonly SyntaxToken s_asyncKeywordWithSpace = AsyncKeyword.WithoutTrivia().WithTrailingTrivia(Space); + [ImportingConstructor] [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] public CSharpMakeMethodAsynchronousCodeFixProvider() @@ -92,7 +94,7 @@ private static MethodDeclarationSyntax FixMethod( CancellationToken cancellationToken) { var newReturnType = FixMethodReturnType(keepVoid, methodSymbol, method.ReturnType, knownTypes, cancellationToken); - var newModifiers = AddAsyncModifierWithCorrectedTrivia(method.Modifiers, ref newReturnType); + (var newModifiers, newReturnType) = AddAsyncModifierWithCorrectedTrivia(method.Modifiers, newReturnType); return method.WithReturnType(newReturnType).WithModifiers(newModifiers); } @@ -104,7 +106,7 @@ private static LocalFunctionStatementSyntax FixLocalFunction( CancellationToken cancellationToken) { var newReturnType = FixMethodReturnType(keepVoid, methodSymbol, localFunction.ReturnType, knownTypes, cancellationToken); - var newModifiers = AddAsyncModifierWithCorrectedTrivia(localFunction.Modifiers, ref newReturnType); + (var newModifiers, newReturnType) = AddAsyncModifierWithCorrectedTrivia(localFunction.Modifiers, newReturnType); return localFunction.WithReturnType(newReturnType).WithModifiers(newModifiers); } @@ -176,15 +178,15 @@ private static bool IsIEnumerable(ITypeSymbol returnType, KnownTaskTypes knownTy private static bool IsIEnumerator(ITypeSymbol returnType, KnownTaskTypes knownTypes) => returnType.OriginalDefinition.Equals(knownTypes.IEnumeratorOfTType); - private static SyntaxTokenList AddAsyncModifierWithCorrectedTrivia(SyntaxTokenList modifiers, ref TypeSyntax newReturnType) + private static (SyntaxTokenList newModifiers, TypeSyntax newReturnType) AddAsyncModifierWithCorrectedTrivia(SyntaxTokenList modifiers, TypeSyntax returnType) { if (modifiers.Any()) - return modifiers.Add(AsyncKeyword); + return (modifiers.Add(s_asyncKeywordWithSpace), returnType); // Move the leading trivia from the return type to the new modifiers list. - var result = TokenList(AsyncKeyword.WithLeadingTrivia(newReturnType.GetLeadingTrivia())); - newReturnType = newReturnType.WithoutLeadingTrivia(); - return result; + var newModifiers = TokenList(s_asyncKeywordWithSpace.WithLeadingTrivia(returnType.GetLeadingTrivia())); + var newReturnType = returnType.WithoutLeadingTrivia(); + return (newModifiers, newReturnType); } private static AnonymousFunctionExpressionSyntax FixAnonymousFunction(AnonymousFunctionExpressionSyntax anonymous) diff --git a/src/Analyzers/CSharp/CodeFixes/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeFixProvider.cs index a894c26ed3cc6..39bcf0dc146c5 100644 --- a/src/Analyzers/CSharp/CodeFixes/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/UseConditionalExpression/CSharpUseConditionalExpressionForAssignmentCodeFixProvider.cs @@ -2,16 +2,15 @@ // 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; using System.Composition; -using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.CSharp.LanguageService; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Simplification; @@ -20,16 +19,12 @@ namespace Microsoft.CodeAnalysis.CSharp.UseConditionalExpression; [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.UseConditionalExpressionForAssignment), Shared] -internal partial class CSharpUseConditionalExpressionForAssignmentCodeFixProvider +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class CSharpUseConditionalExpressionForAssignmentCodeFixProvider() : AbstractUseConditionalExpressionForAssignmentCodeFixProvider< StatementSyntax, IfStatementSyntax, LocalDeclarationStatementSyntax, VariableDeclaratorSyntax, ExpressionSyntax, ConditionalExpressionSyntax> { - [ImportingConstructor] - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] - public CSharpUseConditionalExpressionForAssignmentCodeFixProvider() - { - } - protected override ISyntaxFacts SyntaxFacts => CSharpSyntaxFacts.Instance; diff --git a/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersFixAllTests.cs b/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersFixAllTests.cs index fe2376e3388fb..866c7eef2df9a 100644 --- a/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersFixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersFixAllTests.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.AddAccessibilityModifiers; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; @@ -15,39 +14,38 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddAccessibilityModifiers +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddAccessibilityModifiers; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddAccessibilityModifiers)] +public class AddAccessibilityModifiersFixAllTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddAccessibilityModifiers)] - public class AddAccessibilityModifiersFixAllTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddAccessibilityModifiersFixAllTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpAddAccessibilityModifiersDiagnosticAnalyzer(), new CSharpAddAccessibilityModifiersCodeFixProvider()); + + [Fact, WorkItem("https://github.com/dotnet/vscode-csharp/issues/6611")] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingType_DoesNotCrashInDuplicateProgramInTopLevelStatements() { - public AddAccessibilityModifiersFixAllTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpAddAccessibilityModifiersDiagnosticAnalyzer(), new CSharpAddAccessibilityModifiersCodeFixProvider()); - - [Fact, WorkItem("https://github.com/dotnet/vscode-csharp/issues/6611")] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingType_DoesNotCrashInDuplicateProgramInTopLevelStatements() - { - var input = """ - Console.WriteLine("Hello, World!"); - class {|FixAllInContainingType:Program|} - { - } - """; - - var expected = """ - Console.WriteLine("Hello, World!"); - - internal class Program - { - } - """; - - await TestAsync(input, expected, TestParameters.Default.parseOptions); - } + var input = """ + Console.WriteLine("Hello, World!"); + class {|FixAllInContainingType:Program|} + { + } + """; + + var expected = """ + Console.WriteLine("Hello, World!"); + + internal class Program + { + } + """; + + await TestAsync(input, expected, TestParameters.Default.parseOptions); } } diff --git a/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersTests.cs b/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersTests.cs index 09ce7b40be77d..28a7bdb9bd464 100644 --- a/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersTests.cs +++ b/src/Analyzers/CSharp/Tests/AddAccessibilityModifiers/AddAccessibilityModifiersTests.cs @@ -12,745 +12,744 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddAccessibilityModifiers +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddAccessibilityModifiers; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpAddAccessibilityModifiersDiagnosticAnalyzer, + CSharpAddAccessibilityModifiersCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddAccessibilityModifiers)] +public class AddAccessibilityModifiersTests { - using VerifyCS = CSharpCodeFixVerifier< - CSharpAddAccessibilityModifiersDiagnosticAnalyzer, - CSharpAddAccessibilityModifiersCodeFixProvider>; + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); - [Trait(Traits.Feature, Traits.Features.CodeActionsAddAccessibilityModifiers)] - public class AddAccessibilityModifiersTests + [Fact] + public async Task TestAllConstructs() { - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); - - [Fact] - public async Task TestAllConstructs() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - namespace Outer + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + namespace Outer + { + namespace Inner1.Inner2 { - namespace Inner1.Inner2 + partial class [|C|] : I { - partial class [|C|] : I - { - class [|NestedClass|] { } + class [|NestedClass|] { } - struct [|NestedStruct|] { } + struct [|NestedStruct|] { } - int [|f1|]; - int [|f2|], f3; - public int f4; + int [|f1|]; + int [|f2|], f3; + public int f4; - event Action [|e1|], e2; - public event Action e3; + event Action [|e1|], e2; + public event Action e3; - event Action [|e4|] { add { } remove { } } - public event Action e5 { add { } remove { } } - event Action I.e6 { add { } remove { } } + event Action [|e4|] { add { } remove { } } + public event Action e5 { add { } remove { } } + event Action I.e6 { add { } remove { } } - static C() { } - [|C|]() { } - public C(int i) { } + static C() { } + [|C|]() { } + public C(int i) { } - ~C() { } + ~C() { } - void [|M1|]() { } - public void M2() { } - void I.M3() { } - partial void M4(); - partial void M4() { } + void [|M1|]() { } + public void M2() { } + void I.M3() { } + partial void M4(); + partial void M4() { } - int [|P1|] { get; } - public int P2 { get; } - int I.P3 { get; } + int [|P1|] { get; } + public int P2 { get; } + int I.P3 { get; } - int [|this|][int i] => throw null; - public int this[string s] => throw null; - int I.this[bool b] => throw null; - } + int [|this|][int i] => throw null; + public int this[string s] => throw null; + int I.this[bool b] => throw null; + } - interface [|I|] - { - event Action e6; - void M3(); - int P3 { get; } - int this[bool b] { get; } - } + interface [|I|] + { + event Action e6; + void M3(); + int P3 { get; } + int this[bool b] { get; } + } - delegate void [|D|](); + delegate void [|D|](); - enum [|E|] - { - EMember - } + enum [|E|] + { + EMember } } - """, - """ - using System; - namespace Outer + } + """, + """ + using System; + namespace Outer + { + namespace Inner1.Inner2 { - namespace Inner1.Inner2 + internal partial class C : I { - internal partial class C : I - { - private class NestedClass { } + private class NestedClass { } - private struct NestedStruct { } + private struct NestedStruct { } - private int f1; - private int f2, f3; - public int f4; + private int f1; + private int f2, f3; + public int f4; - private event Action e1, e2; - public event Action e3; + private event Action e1, e2; + public event Action e3; - private event Action e4 { add { } remove { } } - public event Action e5 { add { } remove { } } - event Action I.e6 { add { } remove { } } + private event Action e4 { add { } remove { } } + public event Action e5 { add { } remove { } } + event Action I.e6 { add { } remove { } } - static C() { } + static C() { } - private C() { } - public C(int i) { } + private C() { } + public C(int i) { } - ~C() { } + ~C() { } - private void M1() { } - public void M2() { } - void I.M3() { } - partial void M4(); - partial void M4() { } + private void M1() { } + public void M2() { } + void I.M3() { } + partial void M4(); + partial void M4() { } - private int P1 { get; } - public int P2 { get; } - int I.P3 { get; } + private int P1 { get; } + public int P2 { get; } + int I.P3 { get; } - private int this[int i] => throw null; - public int this[string s] => throw null; - int I.this[bool b] => throw null; - } - - internal interface I - { - event Action e6; - void M3(); - int P3 { get; } - int this[bool b] { get; } - } - - internal delegate void D(); - - internal enum E - { - EMember - } + private int this[int i] => throw null; + public int this[string s] => throw null; + int I.this[bool b] => throw null; } - } - """); - } - - [Fact] - public async Task TestRefStructs() - { - await VerifyCS.VerifyCodeFixAsync(""" - namespace Test - { - ref struct [|S1|] { } - } - """, """ - namespace Test - { - internal ref struct S1 { } - } - """); - } - [Fact] - public async Task TestRecords() - { - var source = """ - record [|Record|] - { - int [|field|]; - } - namespace System.Runtime.CompilerServices - { - public sealed class IsExternalInit + internal interface I { + event Action e6; + void M3(); + int P3 { get; } + int this[bool b] { get; } } - } - """; - var fixedSource = """ - internal record Record - { - private int field; - } - namespace System.Runtime.CompilerServices - { - public sealed class IsExternalInit + + internal delegate void D(); + + internal enum E { + EMember } } - """; + } + """); + } - var test = new VerifyCS.Test + [Fact] + public async Task TestRefStructs() + { + await VerifyCS.VerifyCodeFixAsync(""" + namespace Test { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp9, - }; - - await test.RunAsync(); - } + ref struct [|S1|] { } + } + """, """ + namespace Test + { + internal ref struct S1 { } + } + """); + } - [Fact] - public async Task TestRecordStructs() - { - var source = """ - record struct [|Record|] + [Fact] + public async Task TestRecords() + { + var source = """ + record [|Record|] + { + int [|field|]; + } + namespace System.Runtime.CompilerServices + { + public sealed class IsExternalInit { - int [|field|]; } - """; - var fixedSource = """ - internal record struct Record + } + """; + var fixedSource = """ + internal record Record + { + private int field; + } + namespace System.Runtime.CompilerServices + { + public sealed class IsExternalInit { - private int field; } - """; + } + """; - var test = new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp12, - }; + var test = new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp9, + }; - await test.RunAsync(); - } + await test.RunAsync(); + } - [Fact] - public async Task TestReadOnlyStructs() + [Fact] + public async Task TestRecordStructs() + { + var source = """ + record struct [|Record|] + { + int [|field|]; + } + """; + var fixedSource = """ + internal record struct Record + { + private int field; + } + """; + + var test = new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" - namespace Test - { - readonly struct [|S1|] { } - } - """, """ - namespace Test - { - internal readonly struct S1 { } - } - """); - } + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp12, + }; - [Fact] - public async Task TestAllConstructsWithOmit() + await test.RunAsync(); + } + + [Fact] + public async Task TestReadOnlyStructs() + { + await VerifyCS.VerifyCodeFixAsync(""" + namespace Test + { + readonly struct [|S1|] { } + } + """, """ + namespace Test + { + internal readonly struct S1 { } + } + """); + } + + [Fact] + public async Task TestAllConstructsWithOmit() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestState = { - TestState = + Sources = { - Sources = + """ + using System; + namespace Outer { - """ - using System; - namespace Outer + namespace Inner1.Inner2 { - namespace Inner1.Inner2 + internal partial class [|C|] : I { - internal partial class [|C|] : I - { - private class [|NestedClass|] { } + private class [|NestedClass|] { } - private struct [|NestedStruct|] { } + private struct [|NestedStruct|] { } - private int [|f1|]; - private int [|f2|], f3; - public int f4; + private int [|f1|]; + private int [|f2|], f3; + public int f4; - private event Action [|e1|], e2; - public event Action e3; + private event Action [|e1|], e2; + public event Action e3; - private event Action [|e4|] { add { } remove { } } - public event Action e5 { add { } remove { } } - event Action I.e6 { add { } remove { } } + private event Action [|e4|] { add { } remove { } } + public event Action e5 { add { } remove { } } + event Action I.e6 { add { } remove { } } - static C() { } + static C() { } - private [|C|]() { } - public C(int i) { } + private [|C|]() { } + public C(int i) { } - ~C() { } + ~C() { } - private void [|M1|]() { } - public void M2() { } - void I.M3() { } - partial void M4(); - partial void M4() { } + private void [|M1|]() { } + public void M2() { } + void I.M3() { } + partial void M4(); + partial void M4() { } - private int [|P1|] { get; } - public int P2 { get; } - int I.P3 { get; } + private int [|P1|] { get; } + public int P2 { get; } + int I.P3 { get; } - private int [|this|][int i] => throw null; - public int this[string s] => throw null; - int I.this[bool b] => throw null; - } + private int [|this|][int i] => throw null; + public int this[string s] => throw null; + int I.this[bool b] => throw null; + } - internal interface [|I|] - { - event Action e6; - void M3(); - int P3 { get; } - int this[bool b] { get; } - } + internal interface [|I|] + { + event Action e6; + void M3(); + int P3 { get; } + int this[bool b] { get; } + } - internal delegate void [|D|](); + internal delegate void [|D|](); - internal enum [|E|] - { - EMember - } + internal enum [|E|] + { + EMember } } - """, - }, + } + """, }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = + """ + using System; + namespace Outer { - """ - using System; - namespace Outer + namespace Inner1.Inner2 { - namespace Inner1.Inner2 + partial class C : I { - partial class C : I - { - class NestedClass { } + class NestedClass { } - struct NestedStruct { } + struct NestedStruct { } - int f1; - int f2, f3; - public int f4; + int f1; + int f2, f3; + public int f4; - event Action e1, e2; - public event Action e3; + event Action e1, e2; + public event Action e3; - event Action e4 { add { } remove { } } - public event Action e5 { add { } remove { } } - event Action I.e6 { add { } remove { } } + event Action e4 { add { } remove { } } + public event Action e5 { add { } remove { } } + event Action I.e6 { add { } remove { } } - static C() { } + static C() { } - C() { } - public C(int i) { } + C() { } + public C(int i) { } - ~C() { } + ~C() { } - void M1() { } - public void M2() { } - void I.M3() { } - partial void M4(); - partial void M4() { } + void M1() { } + public void M2() { } + void I.M3() { } + partial void M4(); + partial void M4() { } - int P1 { get; } - public int P2 { get; } - int I.P3 { get; } + int P1 { get; } + public int P2 { get; } + int I.P3 { get; } - int this[int i] => throw null; - public int this[string s] => throw null; - int I.this[bool b] => throw null; - } + int this[int i] => throw null; + public int this[string s] => throw null; + int I.this[bool b] => throw null; + } - interface I - { - event Action e6; - void M3(); - int P3 { get; } - int this[bool b] { get; } - } + interface I + { + event Action e6; + void M3(); + int P3 { get; } + int this[bool b] { get; } + } - delegate void D(); + delegate void D(); - enum E - { - EMember - } + enum E + { + EMember } } - """, - }, - }, - Options = - { - { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, + } + """, }, - }.RunAsync(); - } - - [Fact] - public async Task TestRefStructsWithOmit() - { - await new VerifyCS.Test + }, + Options = { - TestCode = """ - namespace Test - { - internal ref struct [|S1|] { } - } - """, - FixedCode = """ - namespace Test - { - ref struct S1 { } - } - """, - Options = - { - { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, - }, - }.RunAsync(); - } + { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, + }, + }.RunAsync(); + } - [Fact] - public async Task TestReadOnlyStructsWithOmit() + [Fact] + public async Task TestRefStructsWithOmit() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + namespace Test { - TestCode = """ - namespace Test - { - internal readonly struct [|S1|] { } - } - """, - FixedCode = """ - namespace Test - { - readonly struct S1 { } - } - """, - Options = - { - { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, - }, - }.RunAsync(); - } + internal ref struct [|S1|] { } + } + """, + FixedCode = """ + namespace Test + { + ref struct S1 { } + } + """, + Options = + { + { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, + }, + }.RunAsync(); + } - [Fact] - public async Task TestClassOutsideNamespace() + [Fact] + public async Task TestReadOnlyStructsWithOmit() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - internal class [|C1|] { } - """, - FixedCode = """ - class C1 { } - """, - Options = - { - { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, - }, - }.RunAsync(); - } + TestCode = """ + namespace Test + { + internal readonly struct [|S1|] { } + } + """, + FixedCode = """ + namespace Test + { + readonly struct S1 { } + } + """, + Options = + { + { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, + }, + }.RunAsync(); + } - [Fact] - public async Task TestExternMethod() + [Fact] + public async Task TestClassOutsideNamespace() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Runtime.InteropServices; + TestCode = """ + internal class [|C1|] { } + """, + FixedCode = """ + class C1 { } + """, + Options = + { + { CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault }, + }, + }.RunAsync(); + } - internal class Program - { - [DllImport("User32.dll", CharSet = CharSet.Unicode)] - static extern int [|MessageBox|](IntPtr h, string m, string c, int type); - } - """, - """ - using System; - using System.Runtime.InteropServices; + [Fact] + public async Task TestExternMethod() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Runtime.InteropServices; - internal class Program - { - [DllImport("User32.dll", CharSet = CharSet.Unicode)] - private static extern int [|MessageBox|](IntPtr h, string m, string c, int type); - } - """); - } + internal class Program + { + [DllImport("User32.dll", CharSet = CharSet.Unicode)] + static extern int [|MessageBox|](IntPtr h, string m, string c, int type); + } + """, + """ + using System; + using System.Runtime.InteropServices; + + internal class Program + { + [DllImport("User32.dll", CharSet = CharSet.Unicode)] + private static extern int [|MessageBox|](IntPtr h, string m, string c, int type); + } + """); + } - [Fact] - public async Task TestVolatile() - { - await VerifyCS.VerifyCodeFixAsync(""" - internal class Program - { - volatile int [|x|]; - } - """, - """ - internal class Program - { - private volatile int x; - } - """); - } + [Fact] + public async Task TestVolatile() + { + await VerifyCS.VerifyCodeFixAsync(""" + internal class Program + { + volatile int [|x|]; + } + """, + """ + internal class Program + { + private volatile int x; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48899")] - public async Task TestAbstractMethod() - { - await VerifyCS.VerifyCodeFixAsync(""" - public abstract class TestClass - { - abstract string {|CS0621:[|Test|]|} { get; } - } - """, - """ - public abstract class TestClass - { - protected abstract string Test { get; } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48899")] + public async Task TestAbstractMethod() + { + await VerifyCS.VerifyCodeFixAsync(""" + public abstract class TestClass + { + abstract string {|CS0621:[|Test|]|} { get; } + } + """, + """ + public abstract class TestClass + { + protected abstract string Test { get; } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48899")] - public async Task TestOverriddenMethod() - { - await VerifyCS.VerifyCodeFixAsync(""" - public abstract class TestClass - { - public abstract string Test { get; } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48899")] + public async Task TestOverriddenMethod() + { + await VerifyCS.VerifyCodeFixAsync(""" + public abstract class TestClass + { + public abstract string Test { get; } + } - public class Derived : TestClass - { - override string {|CS0507:{|CS0621:[|Test|]|}|} { get; } - } - """, - """ - public abstract class TestClass - { - public abstract string Test { get; } - } + public class Derived : TestClass + { + override string {|CS0507:{|CS0621:[|Test|]|}|} { get; } + } + """, + """ + public abstract class TestClass + { + public abstract string Test { get; } + } - public class Derived : TestClass - { - public override string Test { get; } - } - """); - } + public class Derived : TestClass + { + public override string Test { get; } + } + """); + } - [Fact] - public async Task TestFileScopedNamespaces() + [Fact] + public async Task TestFileScopedNamespaces() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + namespace Test; + + struct [|S1|] { } + """, + FixedCode = """ + namespace Test; + + internal struct S1 { } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55703")] + public async Task TestPartial_WithExistingModifier() + { + var source = """ + partial class [|C|] { - TestCode = """ - namespace Test; + } - struct [|S1|] { } - """, - FixedCode = """ - namespace Test; + public partial class C + { + } + """; + var fixedSource = """ + public partial class C + { + } - internal struct S1 { } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + public partial class C + { + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55703")] - public async Task TestPartial_WithExistingModifier() + var test = new VerifyCS.Test { - var source = """ - partial class [|C|] - { - } - - public partial class C - { - } - """; - var fixedSource = """ - public partial class C - { - } + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp12, + }; - public partial class C - { - } - """; + await test.RunAsync(); + } - var test = new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58914")] + public async Task TestStaticOperatorInInterface() + { + var source = """ + internal interface I where T : I { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp12, - }; + abstract static int operator +(T x); + } - await test.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58914")] - public async Task TestStaticOperatorInInterface() - { - var source = """ - internal interface I where T : I + internal class C : I + { + static int I.operator +(C x) { - abstract static int operator +(T x); + throw new System.NotImplementedException(); } + } + """; - internal class C : I - { - static int I.operator +(C x) - { - throw new System.NotImplementedException(); - } - } - """; - - var test = new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp12, - ReferenceAssemblies = Testing.ReferenceAssemblies.Net.Net60 - }; - - await test.RunAsync(); - } - - [Theory] - [InlineData("class")] - [InlineData("struct")] - [InlineData("record")] - [InlineData("record struct")] - [InlineData("interface")] - [InlineData("enum")] - [WorkItem("https://github.com/dotnet/roslyn/issues/62259")] - public async Task TestFileDeclaration(string declarationKind) + var test = new VerifyCS.Test { - var source = $"file {declarationKind} C {{ }}"; + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp12, + ReferenceAssemblies = Testing.ReferenceAssemblies.Net.Net60 + }; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp12, - }.RunAsync(); - } + await test.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62259")] - public async Task TestFileDelegate() + [Theory] + [InlineData("class")] + [InlineData("struct")] + [InlineData("record")] + [InlineData("record struct")] + [InlineData("interface")] + [InlineData("enum")] + [WorkItem("https://github.com/dotnet/roslyn/issues/62259")] + public async Task TestFileDeclaration(string declarationKind) + { + var source = $"file {declarationKind} C {{ }}"; + + await new VerifyCS.Test { - var source = "file delegate void M();"; - - await new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp12, - }.RunAsync(); - } - - [Theory] - [InlineData("class")] - [InlineData("struct")] - [InlineData("record")] - [InlineData("record struct")] - [InlineData("interface")] - [InlineData("enum")] - [WorkItem("https://github.com/dotnet/roslyn/issues/62259")] - public async Task TestNestedFileDeclaration(string declarationKind) + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp12, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62259")] + public async Task TestFileDelegate() + { + var source = "file delegate void M();"; + + await new VerifyCS.Test { - var source = $$""" - file class C1 - { - {{declarationKind}} [|C2|] { } - } - """; + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp12, + }.RunAsync(); + } - var fixedSource = $$""" - file class C1 - { - private {{declarationKind}} C2 { } - } - """; + [Theory] + [InlineData("class")] + [InlineData("struct")] + [InlineData("record")] + [InlineData("record struct")] + [InlineData("interface")] + [InlineData("enum")] + [WorkItem("https://github.com/dotnet/roslyn/issues/62259")] + public async Task TestNestedFileDeclaration(string declarationKind) + { + var source = $$""" + file class C1 + { + {{declarationKind}} [|C2|] { } + } + """; - await new VerifyCS.Test + var fixedSource = $$""" + file class C1 { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp12, - }.RunAsync(); - } + private {{declarationKind}} C2 { } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29633")] - public async Task TestTitle1() + await new VerifyCS.Test { - var source = """ - internal class C - { - int [|field|]; - } - """; - var fixedSource = """ - internal class C - { - private int field; - } - """; + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp12, + }.RunAsync(); + } - var test = new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29633")] + public async Task TestTitle1() + { + var source = """ + internal class C { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp12, - CodeActionEquivalenceKey = nameof(AnalyzersResources.Add_accessibility_modifiers), - }; - - await test.RunAsync(); - } + int [|field|]; + } + """; + var fixedSource = """ + internal class C + { + private int field; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29633")] - public async Task TestTitle2() + var test = new VerifyCS.Test { - var source = """ - class C - { - private int [|field|]; - } - """; - var fixedSource = """ - class C - { - int field; - } - """; + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp12, + CodeActionEquivalenceKey = nameof(AnalyzersResources.Add_accessibility_modifiers), + }; - var test = new VerifyCS.Test + await test.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29633")] + public async Task TestTitle2() + { + var source = """ + class C { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp12, - CodeActionEquivalenceKey = nameof(AnalyzersResources.Remove_accessibility_modifiers), - Options = - { - { CodeStyleOptions2.AccessibilityModifiersRequired,AccessibilityModifiersRequired.OmitIfDefault } - } - }; + private int [|field|]; + } + """; + var fixedSource = """ + class C + { + int field; + } + """; + + var test = new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp12, + CodeActionEquivalenceKey = nameof(AnalyzersResources.Remove_accessibility_modifiers), + Options = + { + { CodeStyleOptions2.AccessibilityModifiersRequired,AccessibilityModifiersRequired.OmitIfDefault } + } + }; - await test.RunAsync(); - } + await test.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs b/src/Analyzers/CSharp/Tests/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs index 07d969148d5be..38d7302ea6983 100644 --- a/src/Analyzers/CSharp/Tests/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs +++ b/src/Analyzers/CSharp/Tests/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs @@ -11,77 +11,29 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddAnonymousTypeMemberName +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddAnonymousTypeMemberName; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddAnonymousTypeMemberName)] +public class AddAnonymousTypeMemberNameTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddAnonymousTypeMemberName)] - public class AddAnonymousTypeMemberNameTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddAnonymousTypeMemberNameTests(ITestOutputHelper logger) + : base(logger) { - public AddAnonymousTypeMemberNameTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAddAnonymousTypeMemberNameCodeFixProvider()); + } - [Fact] - public async Task Test1() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M() - { - var v = new { [||]this.GetType() }; - } - } - """, - """ - class C - { - void M() - { - var v = new { {|Rename:Type|} = this.GetType() }; - } - } - """); - } + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAddAnonymousTypeMemberNameCodeFixProvider()); - [Fact] - public async Task TestExistingName() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M() - { - var v = new { Type = 1, [||]this.GetType() }; - } - } - """, - """ - class C - { - void M() - { - var v = new { Type = 1, {|Rename:Type1|} = this.GetType() }; - } - } - """); - } - - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( + [Fact] + public async Task Test1() + { + await TestInRegularAndScript1Async( """ class C { void M() { - var v = new { {|FixAllInDocument:|}new { this.GetType(), this.ToString() } }; + var v = new { [||]this.GetType() }; } } """, @@ -90,22 +42,22 @@ class C { void M() { - var v = new { Value = new { Type = this.GetType(), V = this.ToString() } }; + var v = new { {|Rename:Type|} = this.GetType() }; } } """); - } + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScript1Async( + [Fact] + public async Task TestExistingName() + { + await TestInRegularAndScript1Async( """ class C { void M() { - var v = new { new { {|FixAllInDocument:|}this.GetType(), this.ToString() } }; + var v = new { Type = 1, [||]this.GetType() }; } } """, @@ -114,34 +66,81 @@ class C { void M() { - var v = new { Value = new { Type = this.GetType(), V = this.ToString() } }; + var v = new { Type = 1, {|Rename:Type1|} = this.GetType() }; } } """); + } + + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + var v = new { {|FixAllInDocument:|}new { this.GetType(), this.ToString() } }; + } } + """, + """ + class C + { + void M() + { + var v = new { Value = new { Type = this.GetType(), V = this.ToString() } }; + } + } + """); + } - [Fact] - public async Task TestFixAll3() + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScript1Async( + """ + class C { - await TestInRegularAndScript1Async( - """ - class C + void M() { - void M() - { - var v = new { {|FixAllInDocument:|}new { this.GetType(), this.GetType() } }; - } + var v = new { new { {|FixAllInDocument:|}this.GetType(), this.ToString() } }; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var v = new { Value = new { Type = this.GetType(), Type1 = this.GetType() } }; - } + var v = new { Value = new { Type = this.GetType(), V = this.ToString() } }; + } + } + """); + } + + [Fact] + public async Task TestFixAll3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + var v = new { {|FixAllInDocument:|}new { this.GetType(), this.GetType() } }; + } + } + """, + """ + class C + { + void M() + { + var v = new { Value = new { Type = this.GetType(), Type1 = this.GetType() } }; } - """); } + """); } } diff --git a/src/Analyzers/CSharp/Tests/AddBraces/AddBracesFixAllTests.cs b/src/Analyzers/CSharp/Tests/AddBraces/AddBracesFixAllTests.cs index e38aa7cc8d6dd..d11a49d082c13 100644 --- a/src/Analyzers/CSharp/Tests/AddBraces/AddBracesFixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/AddBraces/AddBracesFixAllTests.cs @@ -8,727 +8,726 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddBraces +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddBraces; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] +public partial class AddBracesTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] - public partial class AddBracesTests + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument1() { - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument1() - { - var input = """ - class Program1 - { - static void Main() - { - {|FixAllInDocument:if|} (true) if (true) return; - } + var input = """ + class Program1 + { + static void Main() + { + {|FixAllInDocument:if|} (true) if (true) return; } - """; + } + """; - var expected = """ - class Program1 + var expected = """ + class Program1 + { + static void Main() { - static void Main() + if (true) { if (true) { - if (true) - { - return; - } + return; } } } - """; + } + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument2() - { - var input = """ - class Program1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument2() + { + var input = """ + class Program1 + { + static void Main() { - static void Main() - { - if (true) {|FixAllInDocument:if|} (true) return; - } + if (true) {|FixAllInDocument:if|} (true) return; } - """; + } + """; - var expected = """ - class Program1 + var expected = """ + class Program1 + { + static void Main() { - static void Main() + if (true) { if (true) { - if (true) - { - return; - } + return; } } } - """; + } + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument() - { - var input = """ - - - - class Program1 - { - static void Main() - { - {|FixAllInDocument:if|} (true) return; - if (true) return; - } - } - - - class Program2 - { - static void Main() - { - if (true) return; - } - } - - - - - class Program3 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() + { + var input = """ + + + + class Program1 + { + static void Main() + { + {|FixAllInDocument:if|} (true) return; + if (true) return; + } + } + + + class Program2 + { + static void Main() + { + if (true) return; + } + } + + + + + class Program3 + { + static void Main() + { + if (true) return; + } + } + + + + """; + + var expected = """ + + + + class Program1 + { + static void Main() { - static void Main() + if (true) { - if (true) return; + return; } - } - - - - """; - - var expected = """ - - - - class Program1 - { - static void Main() - { - if (true) - { - return; - } - if (true) - { - return; - } - } - } - - - class Program2 - { - static void Main() - { - if (true) return; - } - } - - - - - class Program3 - { - static void Main() - { - if (true) return; - } - } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject() - { - var input = """ - - - - class Program1 - { - static void Main() + if (true) { - {|FixAllInProject:if|} (true) return; + return; } } - - - class Program2 + } + + + class Program2 + { + static void Main() { - static void Main() - { - if (true) return; - } + if (true) return; } - - - - - class Program3 + } + + + + + class Program3 + { + static void Main() { - static void Main() - { - if (true) return; - } + if (true) return; } - - - - """; + } + + + + """; - var expected = """ - - - - class Program1 - { - static void Main() - { - if (true) - { - return; - } - } - } - - - class Program2 - { - static void Main() - { - if (true) - { - return; - } - } - } - - - - - class Program3 + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var input = """ + + + + class Program1 + { + static void Main() + { + {|FixAllInProject:if|} (true) return; + } + } + + + class Program2 + { + static void Main() + { + if (true) return; + } + } + + + + + class Program3 + { + static void Main() + { + if (true) return; + } + } + + + + """; + + var expected = """ + + + + class Program1 + { + static void Main() { - static void Main() - { - if (true) return; - } - } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution() - { - var input = """ - - - - class Program1 - { - static void Main() + if (true) { - {|FixAllInSolution:if|} (true) return; + return; } } - - - class Program2 + } + + + class Program2 + { + static void Main() { - static void Main() + if (true) { - if (true) return; + return; } } - - - - - class Program3 + } + + + + + class Program3 + { + static void Main() { - static void Main() - { - if (true) return; - } + if (true) return; } - - - - """; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } - var expected = """ - - - - class Program1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() + { + var input = """ + + + + class Program1 + { + static void Main() + { + {|FixAllInSolution:if|} (true) return; + } + } + + + class Program2 + { + static void Main() + { + if (true) return; + } + } + + + + + class Program3 + { + static void Main() + { + if (true) return; + } + } + + + + """; + + var expected = """ + + + + class Program1 + { + static void Main() { - static void Main() + if (true) { - if (true) - { - return; - } + return; } } - - - class Program2 + } + + + class Program2 + { + static void Main() { - static void Main() + if (true) { - if (true) - { - return; - } + return; } } - - - - - class Program3 + } + + + + + class Program3 + { + static void Main() { - static void Main() + if (true) { - if (true) - { - return; - } + return; } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingMember() - { - var input = """ - class Program1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingMember() + { + var input = """ + class Program1 + { + static void Main() { - static void Main() - { - {|FixAllInContainingMember:if|} (true) if (true) return; + {|FixAllInContainingMember:if|} (true) if (true) return; - if (false) if (false) return; - } + if (false) if (false) return; + } - void OtherMethod() - { - if (true) if (true) return; - } + void OtherMethod() + { + if (true) if (true) return; } + } - class OtherType + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - """; + } + """; - var expected = """ - class Program1 + var expected = """ + class Program1 + { + static void Main() { - static void Main() + if (true) { if (true) { - if (true) - { - return; - } + return; } + } + if (false) + { if (false) { - if (false) - { - return; - } + return; } } + } - void OtherMethod() - { - if (true) if (true) return; - } + void OtherMethod() + { + if (true) if (true) return; } + } - class OtherType + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - """; + } + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingType_AcrossSingleFile() - { - var input = """ - class Program1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingType_AcrossSingleFile() + { + var input = """ + class Program1 + { + static void Main() { - static void Main() - { - {|FixAllInContainingType:if|} (true) if (true) return; + {|FixAllInContainingType:if|} (true) if (true) return; - if (false) if (false) return; - } + if (false) if (false) return; + } - void OtherMethod() - { - if (true) if (true) return; - } + void OtherMethod() + { + if (true) if (true) return; } + } - class OtherType + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - """; + } + """; - var expected = """ - class Program1 + var expected = """ + class Program1 + { + static void Main() { - static void Main() + if (true) { if (true) { - if (true) - { - return; - } + return; } + } + if (false) + { if (false) { - if (false) - { - return; - } + return; } } + } - void OtherMethod() + void OtherMethod() + { + if (true) { if (true) { - if (true) - { - return; - } + return; } } } + } - class OtherType + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - """; + } + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingType_AcrossMultipleFiles() - { - var input = """ - - - - partial class Program1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingType_AcrossMultipleFiles() + { + var input = """ + + + + partial class Program1 + { + static void Main() { - static void Main() - { - {|FixAllInContainingType:if|} (true) if (true) return; + {|FixAllInContainingType:if|} (true) if (true) return; - if (false) if (false) return; - } + if (false) if (false) return; + } - void OtherMethod() - { - if (true) if (true) return; - } + void OtherMethod() + { + if (true) if (true) return; } - - - partial class Program1 + } + + + partial class Program1 + { + void OtherFileMethod() { - void OtherFileMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - - - class Program2 + } + + + class Program2 + { + void OtherTypeMethod() { - void OtherTypeMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - - - - """; + } + + + + """; - var expected = """ - - - - partial class Program1 + var expected = """ + + + + partial class Program1 + { + static void Main() { - static void Main() + if (true) { if (true) { - if (true) - { - return; - } + return; } + } + if (false) + { if (false) { - if (false) - { - return; - } + return; } } + } - void OtherMethod() + void OtherMethod() + { + if (true) { if (true) { - if (true) - { - return; - } + return; } } } - - - partial class Program1 + } + + + partial class Program1 + { + void OtherFileMethod() { - void OtherFileMethod() + if (true) { if (true) { - if (true) - { - return; - } + return; } } } - - - class Program2 + } + + + class Program2 + { + void OtherTypeMethod() { - void OtherTypeMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Theory] - [InlineData("FixAllInContainingMember")] - [InlineData("FixAllInContainingType")] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingMemberAndType_TopLevelStatements(string fixAllScope) - { - var input = $$""" - {|{{fixAllScope}}:if|} (true) if (true) return; + [Theory] + [InlineData("FixAllInContainingMember")] + [InlineData("FixAllInContainingType")] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingMemberAndType_TopLevelStatements(string fixAllScope) + { + var input = $$""" + {|{{fixAllScope}}:if|} (true) if (true) return; - if (false) if (false) return; + if (false) if (false) return; - class OtherType + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - """; + } + """; - var expected = """ + var expected = """ + if (true) + { if (true) { - if (true) - { - return; - } + return; } + } + if (false) + { if (false) { - if (false) - { - return; - } + return; } + } - class OtherType + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } - """; + } + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Theory] - [InlineData("FixAllInContainingMember")] - [InlineData("FixAllInContainingType")] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingMemberAndType_TopLevelStatements_02(string fixAllScope) - { - var input = $$""" - using System; + [Theory] + [InlineData("FixAllInContainingMember")] + [InlineData("FixAllInContainingType")] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingMemberAndType_TopLevelStatements_02(string fixAllScope) + { + var input = $$""" + using System; - {|{{fixAllScope}}:if|} (true) if (true) return; + {|{{fixAllScope}}:if|} (true) if (true) return; - if (false) if (false) return; + if (false) if (false) return; - namespace N + namespace N + { + class OtherType { - class OtherType + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } } - """; + } + """; - var expected = """ - using System; + var expected = """ + using System; + if (true) + { if (true) { - if (true) - { - return; - } + return; } + } + if (false) + { if (false) { - if (false) - { - return; - } + return; } + } - namespace N + namespace N + { + class OtherType { - class OtherType + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } } - """; + } + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Theory] - [InlineData("FixAllInContainingMember")] - [InlineData("FixAllInContainingType")] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingMemberAndType_TopLevelStatements_ErrorCase(string fixAllScope) - { - // Error case: Global statements should precede non-global statements. - var input = $$""" - class OtherType + [Theory] + [InlineData("FixAllInContainingMember")] + [InlineData("FixAllInContainingType")] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingMemberAndType_TopLevelStatements_ErrorCase(string fixAllScope) + { + // Error case: Global statements should precede non-global statements. + var input = $$""" + class OtherType + { + void OtherMethod() { - void OtherMethod() - { - if (true) if (true) return; - } + if (true) if (true) return; } + } - {|{{fixAllScope}}:if|} (true) if (true) return; + {|{{fixAllScope}}:if|} (true) if (true) return; - if (false) if (false) return; - """; + if (false) if (false) return; + """; - await TestMissingInRegularAndScriptAsync(input); - } + await TestMissingInRegularAndScriptAsync(input); } } diff --git a/src/Analyzers/CSharp/Tests/AddBraces/AddBracesTests.cs b/src/Analyzers/CSharp/Tests/AddBraces/AddBracesTests.cs index 33da6ee1710ac..d3c3199c6a03e 100644 --- a/src/Analyzers/CSharp/Tests/AddBraces/AddBracesTests.cs +++ b/src/Analyzers/CSharp/Tests/AddBraces/AddBracesTests.cs @@ -14,1955 +14,1954 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddBraces +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddBraces; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] +public partial class AddBracesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddBraces)] - public partial class AddBracesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddBracesTests(ITestOutputHelper logger) + : base(logger) { - public AddBracesTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpAddBracesDiagnosticAnalyzer(), new CSharpAddBracesCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpAddBracesDiagnosticAnalyzer(), new CSharpAddBracesCodeFixProvider()); - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForIfWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForIfWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + [|if|] (true) { - [|if|] (true) - { - return; - } + return; } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForElseWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForElseWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + if (true) { - if (true) - { - return; - } - [|else|] - { - return; - } + return; + } + [|else|] + { + return; } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForElseWithChildIf(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForElseWithChildIf(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() - { - if (true) - return; - [|else|] if (false) - return; - } + if (true) + return; + [|else|] if (false) + return; } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForForWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForForWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + [|for|] (var i = 0; i < 5; i++) { - [|for|] (var i = 0; i < 5; i++) - { - return; - } + return; } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForForEachWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForForEachWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + [|foreach|] (var c in "test") { - [|foreach|] (var c in "test") - { - return; - } + return; } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForWhileWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForWhileWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + [|while|] (true) { - [|while|] (true) - { - return; - } + return; } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForDoWhileWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForDoWhileWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + [|do|] { - [|do|] - { - return; - } - while (true); + return; } + while (true); } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForUsingWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForUsingWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + [|using|] (var f = new Fizz()) { - [|using|] (var f = new Fizz()) - { - return; - } + return; } } + } - class Fizz : IDisposable + class Fizz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForUsingWithChildUsing(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForUsingWithChildUsing(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() - { - [|using|] (var f = new Fizz()) - using (var b = new Buzz()) - return; - } + [|using|] (var f = new Fizz()) + using (var b = new Buzz()) + return; } + } - class Fizz : IDisposable + class Fizz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } - class Buzz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForLockWithBraces(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForLockWithBraces(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() + var str = "test"; + [|lock|] (str) { - var str = "test"; - [|lock|] (str) - { - return; - } + return; } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForLockWithChildLock(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForLockWithChildLock(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() - { - var str1 = "test"; - var str2 = "test"; - [|lock|] (str1) - lock (str2) - return; - } + var str1 = "test"; + var str2 = "test"; + [|lock|] (str1) + lock (str2) + return; } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - public async Task DoNotFireForFixedWithChildFixed(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + public async Task DoNotFireForFixedWithChildFixed(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + unsafe static void Main() { - unsafe static void Main() + [|fixed|] (int* p = null) + fixed (int* q = null) { - [|fixed|] (int* p = null) - fixed (int* q = null) - { - } } } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForFixedWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForFixedWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + unsafe static void Main() { - unsafe static void Main() - { - fixed (int* p = null) - [|fixed|] (int* q = null) - return; - } + fixed (int* p = null) + [|fixed|] (int* q = null) + return; } - """, - """ - class Program + } + """, + """ + class Program + { + unsafe static void Main() { - unsafe static void Main() + fixed (int* p = null) + fixed (int* q = null) { - fixed (int* p = null) - fixed (int* q = null) - { - return; - } + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - [|if|] (true) return; - } + [|if|] (true) return; } - """, + } + """, - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) { - if (true) - { - return; - } + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/57770")] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfWithoutBracesTopLevel(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - [|if|] (true) return; - """, - """ - if (true) - { - return; - } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/57770")] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfWithoutBracesTopLevel(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + [|if|] (true) return; + """, + """ + if (true) + { + return; + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForElseWithoutBracesButHasContextBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForElseWithoutBracesButHasContextBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - if (true) { return; } - [|else|] return; - } + if (true) { return; } + [|else|] return; } - """, + } + """, - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) { return; } + else { - if (true) { return; } - else - { - return; - } + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForElseWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForElseWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - if (true) return; - [|else|] return; - } + if (true) return; + [|else|] return; } - """, + } + """, - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) return; + else { - if (true) return; - else - { - return; - } + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForStandaloneElseWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForStandaloneElseWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - [|else|] - return; - } + [|else|] + return; } - """, + } + """, - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + else { - else - { - return; - } + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfNestedInElseWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfNestedInElseWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() + { + if (true) return; + else [|if|] (false) return; + } + } + """, + + """ + class Program + { + static void Main() { - static void Main() + if (true) return; + else if (false) { - if (true) return; - else [|if|] (false) return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext1(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - if (true) return; - else if (false) - { + if (true) + if (true) // This multiline statement does not directly impact the other nested statement return; - } - } + else + return; + else [|if|] (false) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext1(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) + if (true) // This multiline statement does not directly impact the other nested statement + return; + else + return; + else if (false) { - if (true) - if (true) // This multiline statement does not directly impact the other nested statement - return; - else - return; - else [|if|] (false) return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext2(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) - if (true) // This multiline statement does not directly impact the other nested statement - return; - else - return; - else if (false) - { return; - } + else + return; } + else [|if|] (false) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext2(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) - { - if (true) - return; - else - return; - } - else [|if|] (false) return; + return; + else + return; + } + else if (false) + { + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext3(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() + if (true) { - if (true) - { - if (true) - return; - else - return; - } - else if (false) - { + [|if|] (true) + return; + else return; - } } + else if (false) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext3(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) { - [|if|] (true) - return; - else - return; + return; } - else if (false) return; + else + return; } + else if (false) return; } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext4(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) - { - if (true) - { - return; - } - else - return; - } - else if (false) return; + return; + [|else|] + return; } + else if (false) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext4(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) + return; + else { - if (true) - return; - [|else|] - return; + return; } - else if (false) return; } + else if (false) return; } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program +#pragma warning disable CA1200 // Avoid using cref tags with a prefix - Remove the suppression when https://github.com/dotnet/roslyn/issues/42611 is fixed. + /// + /// Verifies that the use of braces in a construct nested within the true portion of an if statement does + /// not trigger the multiline behavior the else clause of a containing stetemnet for + /// . The else clause would only need braces if the true + /// portion also used braces (which would be required if the true portion was considered multiline. + /// +#pragma warning restore CA1200 // Avoid using cref tags with a prefix + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext5(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) - { - if (true) - return; - else - { - return; - } - } - else if (false) return; + if (true) { return; } else { return; } + [|else|] + return; } + else if (false) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, -#pragma warning disable CA1200 // Avoid using cref tags with a prefix - Remove the suppression when https://github.com/dotnet/roslyn/issues/42611 is fixed. - /// - /// Verifies that the use of braces in a construct nested within the true portion of an if statement does - /// not trigger the multiline behavior the else clause of a containing stetemnet for - /// . The else clause would only need braces if the true - /// portion also used braces (which would be required if the true portion was considered multiline. - /// -#pragma warning restore CA1200 // Avoid using cref tags with a prefix - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForIfNestedInElseWithoutBracesWithMultilineContext5(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + if (true) { if (true) + if (true) { return; } else { return; } + else { - if (true) - if (true) { return; } else { return; } - [|else|] - return; + return; } - else if (false) return; } + else if (false) return; } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForForWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - if (true) - { - if (true) - if (true) { return; } else { return; } - else - { - return; - } - } - else if (false) return; - } + [|for|] (var i = 0; i < 5; i++) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForForWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + for (var i = 0; i < 5; i++) { - [|for|] (var i = 0; i < 5; i++) return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForMultilineForWithoutBraces1(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - for (var i = 0; i < 5; i++) - { - return; - } - } + [|for|] (var i = 0; + i < 5; + i++) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForMultilineForWithoutBraces1(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + for (var i = 0; + i < 5; + i++) { - [|for|] (var i = 0; - i < 5; - i++) return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForMultilineForWithoutBraces2(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - for (var i = 0; - i < 5; - i++) - { - return; - } - } + [|for|] (var i = 0; i < 5; i++) if (true) + return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForMultilineForWithoutBraces2(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + for (var i = 0; i < 5; i++) { - [|for|] (var i = 0; i < 5; i++) if (true) - return; + if (true) + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForMultilineForWithoutBraces3(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - for (var i = 0; i < 5; i++) - { - if (true) + [|for|] (var i = 0; i < 5; i++) + if (true) return; - } - } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForMultilineForWithoutBraces3(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + for (var i = 0; i < 5; i++) { - [|for|] (var i = 0; i < 5; i++) - if (true) - return; + if (true) + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForForEachWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - for (var i = 0; i < 5; i++) - { - if (true) - return; - } - } + [|foreach|] (var c in "test") return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForForEachWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + foreach (var c in "test") { - [|foreach|] (var c in "test") return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForWhileWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - foreach (var c in "test") - { - return; - } - } + [|while|] (true) return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForWhileWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + while (true) { - [|while|] (true) return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForDoWhileWithoutBraces1(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - while (true) - { - return; - } - } + [|do|] return; while (true); } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForDoWhileWithoutBraces1(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + do { - [|do|] return; while (true); + return; } + while (true); } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForDoWhileWithoutBraces2(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - do - { - return; - } - while (true); - } + [|do|] + return; + while (true); } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForDoWhileWithoutBraces2(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + do { - [|do|] - return; - while (true); + return; } + while (true); } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForMultilineDoWhileWithoutBraces1(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - do - { - return; - } - while (true); - } + [|do|] return; while (true || + true); } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForMultilineDoWhileWithoutBraces1(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + do { - [|do|] return; while (true || - true); + return; } + while (true || + true); } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForUsingWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - do - { - return; - } - while (true || - true); - } + [|using|] (var f = new Fizz()) + return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForUsingWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - [|using|] (var f = new Fizz()) - return; - } + throw new NotImplementedException(); } + } + """, - class Fizz : IDisposable + """ + class Program + { + static void Main() { - public void Dispose() + using (var f = new Fizz()) { - throw new NotImplementedException(); + return; } } - """, + } - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f = new Fizz()) - { - return; - } - } + throw new NotImplementedException(); } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - class Fizz : IDisposable + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForUsingWithoutBracesNestedInUsing(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - public void Dispose() - { - throw new NotImplementedException(); - } + using (var f = new Fizz()) + [|using|] (var b = new Buzz()) + return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForUsingWithoutBracesNestedInUsing(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f = new Fizz()) - [|using|] (var b = new Buzz()) - return; - } + throw new NotImplementedException(); } + } - class Fizz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } + """, - class Buzz : IDisposable + """ + class Program + { + static void Main() { - public void Dispose() + using (var f = new Fizz()) + using (var b = new Buzz()) { - throw new NotImplementedException(); + return; } } - """, + } - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f = new Fizz()) - using (var b = new Buzz()) - { - return; - } - } + throw new NotImplementedException(); } + } - class Fizz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - class Buzz : IDisposable + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForMultilineUsingWithoutBracesNestedInUsing1(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - public void Dispose() - { - throw new NotImplementedException(); - } + using (var f // <-- This multiline condition doesn't trigger a multiline braces requirement when it's the outer 'using' statement + = new Fizz()) + [|using|] (var b = new Buzz()) + return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForMultilineUsingWithoutBracesNestedInUsing1(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f // <-- This multiline condition doesn't trigger a multiline braces requirement when it's the outer 'using' statement - = new Fizz()) - [|using|] (var b = new Buzz()) - return; - } + throw new NotImplementedException(); } + } - class Fizz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } + """, - class Buzz : IDisposable + """ + class Program + { + static void Main() { - public void Dispose() + using (var f // <-- This multiline condition doesn't trigger a multiline braces requirement when it's the outer 'using' statement + = new Fizz()) + using (var b = new Buzz()) { - throw new NotImplementedException(); + return; } } - """, + } - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f // <-- This multiline condition doesn't trigger a multiline braces requirement when it's the outer 'using' statement - = new Fizz()) - using (var b = new Buzz()) - { - return; - } - } + throw new NotImplementedException(); } + } - class Fizz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - class Buzz : IDisposable + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForMultilineUsingWithoutBracesNestedInUsing2(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - public void Dispose() - { - throw new NotImplementedException(); - } + using (var f = new Fizz()) + [|using|] (var b // <-- This multiline condition triggers a multiline braces requirement because it's the inner 'using' statement + = new Buzz()) + return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForMultilineUsingWithoutBracesNestedInUsing2(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f = new Fizz()) - [|using|] (var b // <-- This multiline condition triggers a multiline braces requirement because it's the inner 'using' statement - = new Buzz()) - return; - } + throw new NotImplementedException(); } + } - class Fizz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } + """, - class Buzz : IDisposable + """ + class Program + { + static void Main() { - public void Dispose() + using (var f = new Fizz()) + using (var b // <-- This multiline condition triggers a multiline braces requirement because it's the inner 'using' statement + = new Buzz()) { - throw new NotImplementedException(); + return; } } - """, + } - """ - class Program + class Fizz : IDisposable + { + public void Dispose() { - static void Main() - { - using (var f = new Fizz()) - using (var b // <-- This multiline condition triggers a multiline braces requirement because it's the inner 'using' statement - = new Buzz()) - { - return; - } - } + throw new NotImplementedException(); } + } - class Fizz : IDisposable + class Buzz : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - class Buzz : IDisposable + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForLockWithoutBraces(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - public void Dispose() - { - throw new NotImplementedException(); - } + var str = "test"; + [|lock|] (str) + return; } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForLockWithoutBraces(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + """ + class Program + { + static void Main() { - static void Main() + var str = "test"; + lock (str) { - var str = "test"; - [|lock|] (str) - return; + return; } } - """, + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + public async Task FireForLockWithoutBracesNestedInLock(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + class Program + { + static void Main() { - static void Main() - { - var str = "test"; - lock (str) + var str1 = "test"; + var str2 = "test"; + + lock (str1) + [|lock|] (str2) // VS thinks this should be indented one more level + return; + } + } + """, + + """ + class Program + { + static void Main() + { + var str1 = "test"; + var str2 = "test"; + + lock (str1) + lock (str2) // VS thinks this should be indented one more level { return; } - } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - public async Task FireForLockWithoutBracesNestedInLock(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task DoNotFireForIfWhenIntercedingDirectiveBefore(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - var str1 = "test"; - var str2 = "test"; - - lock (str1) - [|lock|] (str2) // VS thinks this should be indented one more level - return; - } + #if test + [|if (true)|] + #endif + return; } - """, + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - """ - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task DoNotFireForIfWithIntercedingDirectiveAfter(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - var str1 = "test"; - var str2 = "test"; - - lock (str1) - lock (str2) // VS thinks this should be indented one more level - { - return; - } - } + [|if (true)|] + #if test + return; + #endif } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task DoNotFireForIfWhenIntercedingDirectiveBefore(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None)] + [InlineData((int)PreferBracesPreference.WhenMultiline)] + [InlineData((int)PreferBracesPreference.Always)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task DoNotFireForIfElseWithIntercedingDirectiveInBoth(int bracesPreference) + { + await TestMissingInRegularAndScriptAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - #if test - [|if (true)|] - #endif - return; - } + [|if (true) + #if test + return; + else|] + #endif + return; } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); + } - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task DoNotFireForIfWithIntercedingDirectiveAfter(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task OnlyFireForIfWithIntercedingDirectiveInElseAroundIf(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - [|if (true)|] - #if test - return; - #endif - } + #if test + [|if (true) + return; + else|] + #endif + return; } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, - [Theory] - [InlineData((int)PreferBracesPreference.None)] - [InlineData((int)PreferBracesPreference.WhenMultiline)] - [InlineData((int)PreferBracesPreference.Always)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task DoNotFireForIfElseWithIntercedingDirectiveInBoth(int bracesPreference) - { - await TestMissingInRegularAndScriptAsync( - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + #if test + if (true) { - [|if (true) - #if test - return; - else|] - #endif - return; + return; } + else + #endif + return; } - """, - new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, (PreferBracesPreference)bracesPreference, NotificationOption2.Silent))); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task OnlyFireForIfWithIntercedingDirectiveInElseAroundIf(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task OnlyFireForElseWithIntercedingDirectiveInIfAroundElse(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - #if test - [|if (true) - return; - else|] - #endif - return; - } + [|if (true) + #if test + return; + else|] + return; + #endif } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + if (true) + #if test + return; + else { - #if test - if (true) - { - return; - } - else - #endif - return; + return; } + #endif } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task OnlyFireForElseWithIntercedingDirectiveInIfAroundElse(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task OnlyFireForElseWithIntercedingDirectiveInIf(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - [|if (true) - #if test - return; - else|] - return; - #endif - } + #if test + [|if (true) + #endif + return; + else|] + return; } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + #if test + if (true) + #endif + return; + else { - if (true) - #if test - return; - else - { - return; - } - #endif + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task OnlyFireForElseWithIntercedingDirectiveInIf(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task OnlyFireForIfWithIntercedingDirectiveInElse(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - #if test - [|if (true) - #endif - return; - else|] - return; - } + [|if (true) + return; + else|] + #if test + return; + #endif } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + if (true) { - #if test - if (true) - #endif - return; - else - { - return; - } + return; } + else + #if test + return; + #endif } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task OnlyFireForIfWithIntercedingDirectiveInElse(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task FireForIfElseWithDirectiveAroundIf(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() + #if test + [|if (true) + return; + #endif + else|] { - [|if (true) - return; - else|] - #if test - return; - #endif + return; } } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + #if test + if (true) { - if (true) - { - return; - } - else - #if test - return; - #endif + return; + } + #endif + else + { + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task FireForIfElseWithDirectiveAroundIf(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task FireForIfElseWithDirectiveAroundElse(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() + [|if (true) { - #if test - [|if (true) - return; - #endif - else|] - { - return; - } + return; } + #if test + else|] + return; + #endif } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + if (true) { - #if test - if (true) - { - return; - } - #endif - else - { - return; - } + return; + } + #if test + else + { + return; } + #endif } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task FireForIfElseWithDirectiveAroundElse(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task FireForIfWithoutIntercedingDirective(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - [|if (true) - { - return; - } - #if test - else|] - return; - #endif - } + #if test + #endif + [|if (true)|] + return; } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + #if test + #endif + if (true) { - if (true) - { - return; - } - #if test - else - { - return; - } - #endif + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task FireForIfWithoutIntercedingDirective(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task FireForIfWithDirectiveAfterEmbeddedStatement(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - #if test - #endif - [|if (true)|] - return; - } + [|if (true)|] + return; + #if test + #endif } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + if (true) { - #if test - #endif - if (true) - { - return; - } + return; } + #if test + #endif } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task FireForIfWithDirectiveAfterEmbeddedStatement(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, false)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task FireForInnerNestedStatementWhenDirectiveEntirelyInside(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - [|if (true)|] + [|while (true) + #if test + if (true)|] return; - #if test - #endif - } + #endif } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() - { + while (true) + #if test if (true) { return; } - #if test - #endif - } + #endif } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, false)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task FireForInnerNestedStatementWhenDirectiveEntirelyInside(int bracesPreference, bool expectDiagnostic) - { - await TestAsync( - """ - #define test - class Program + [Theory] + [InlineData((int)PreferBracesPreference.None, false)] + [InlineData((int)PreferBracesPreference.WhenMultiline, true)] + [InlineData((int)PreferBracesPreference.Always, true)] + [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] + public async Task FireForOuterNestedStatementWhenDirectiveEntirelyInside(int bracesPreference, bool expectDiagnostic) + { + await TestAsync( + """ + #define test + class Program + { + static void Main() { - static void Main() - { - [|while (true) - #if test - if (true)|] - return; - #endif - } + [|while (true) + #if test + if (true)|] + #endif + return; } - """, + } + """, - """ - #define test - class Program + """ + #define test + class Program + { + static void Main() { - static void Main() + while (true) { - while (true) - #if test - if (true) - { - return; - } - #endif + #if test + if (true) + #endif + return; } } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); - } + } + """, + (PreferBracesPreference)bracesPreference, + expectDiagnostic); + } - [Theory] - [InlineData((int)PreferBracesPreference.None, false)] - [InlineData((int)PreferBracesPreference.WhenMultiline, true)] - [InlineData((int)PreferBracesPreference.Always, true)] - [WorkItem("https://github.com/dotnet/roslyn/issues/32480")] - public async Task FireForOuterNestedStatementWhenDirectiveEntirelyInside(int bracesPreference, bool expectDiagnostic) + private async Task TestAsync(string initialMarkup, string expectedMarkup, PreferBracesPreference bracesPreference, bool expectDiagnostic) + { + if (expectDiagnostic) { - await TestAsync( - """ - #define test - class Program - { - static void Main() - { - [|while (true) - #if test - if (true)|] - #endif - return; - } - } - """, - - """ - #define test - class Program - { - static void Main() - { - while (true) - { - #if test - if (true) - #endif - return; - } - } - } - """, - (PreferBracesPreference)bracesPreference, - expectDiagnostic); + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: Option(CSharpCodeStyleOptions.PreferBraces, bracesPreference, NotificationOption2.Silent)); } - - private async Task TestAsync(string initialMarkup, string expectedMarkup, PreferBracesPreference bracesPreference, bool expectDiagnostic) + else { - if (expectDiagnostic) - { - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: Option(CSharpCodeStyleOptions.PreferBraces, bracesPreference, NotificationOption2.Silent)); - } - else - { - await TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, bracesPreference, NotificationOption2.Silent))); - } + await TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: Option(CSharpCodeStyleOptions.PreferBraces, bracesPreference, NotificationOption2.Silent))); } } } diff --git a/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests.cs b/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests.cs index f4f89182d2311..ac6aef166fa25 100644 --- a/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests.cs +++ b/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests.cs @@ -13,2427 +13,2606 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AddExplicitCast +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AddExplicitCast; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] +public partial class AddExplicitCastTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - public partial class AddExplicitCastTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddExplicitCastTests(ITestOutputHelper logger) + : base(logger) { - public AddExplicitCastTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAddExplicitCastCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAddExplicitCastCodeFixProvider()); - protected override ImmutableArray MassageActions(ImmutableArray actions) - => FlattenActions(actions); + protected override ImmutableArray MassageActions(ImmutableArray actions) + => FlattenActions(actions); - [Fact] - public async Task SimpleVariableDeclaration() + [Fact] + public async Task SimpleVariableDeclaration() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base {} + class Derived : Base {} + void M() { - class Base {} - class Derived : Base {} - void M() - { - Base b; - Derived d = [|b|]; - } + Base b; + Derived d = [|b|]; } - """, - """ - class Program + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} + void M() { - class Base {} - class Derived : Base {} - void M() - { - Base b; - Derived d = (Derived)b; - } + Base b; + Derived d = (Derived)b; } - """); } + """); + } - [Fact] - public async Task SimpleVariableDeclarationWithFunctionInnvocation() + [Fact] + public async Task SimpleVariableDeclarationWithFunctionInnvocation() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - - Base returnBase() { - Base b; - return b; - } + class Base {} + class Derived : Base {} - void M() - { - Derived d = [|returnBase()|]; - } + Base returnBase() { + Base b; + return b; } - """, - """ - class Program + + void M() { - class Base {} - class Derived : Base {} + Derived d = [|returnBase()|]; + } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void M() - { - Derived d = (Derived)returnBase(); - } + void M() + { + Derived d = (Derived)returnBase(); } - """); } + """); + } - [Fact] - public async Task ReturnStatementWithObject() + [Fact] + public async Task ReturnStatementWithObject() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Derived returnBase() { - Base b; - return b[||]; - } + Derived returnBase() { + Base b; + return b[||]; } - """, - """ - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - Derived returnBase() { - Base b; - return (Derived)b; - } + Derived returnBase() { + Base b; + return (Derived)b; } - """); } + """); + } - [Fact] - public async Task ReturnStatementWithIEnumerable() + [Fact] + public async Task ReturnStatementWithIEnumerable() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; + class Program { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - IEnumerable returnBase() { - Base b; - return b[||]; - } + IEnumerable returnBase() { + Base b; + return b[||]; } - """, - """ - using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + using System.Collections.Generic; + class Program + { + class Base {} + class Derived : Base {} - IEnumerable returnBase() { - Base b; - return (IEnumerable)b; - } + IEnumerable returnBase() { + Base b; + return (IEnumerable)b; } - """); } + """); + } - [Fact] - public async Task ReturnStatementWithIEnumerator() + [Fact] + public async Task ReturnStatementWithIEnumerator() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; + class Program { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - IEnumerator returnBase() { - Base b; - return b[||]; - } + IEnumerator returnBase() { + Base b; + return b[||]; } - """, - """ - using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + using System.Collections.Generic; + class Program + { + class Base {} + class Derived : Base {} - IEnumerator returnBase() { - Base b; - return (IEnumerator)b; - } + IEnumerator returnBase() { + Base b; + return (IEnumerator)b; } - """); } + """); + } - [Fact] - public async Task ReturnStatementWithFunctionInnvocation() + [Fact] + public async Task ReturnStatementWithFunctionInnvocation() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - Derived returnDerived() { - return [|returnBase()|]; - } + Derived returnDerived() { + return [|returnBase()|]; } - """, - """ - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - Derived returnDerived() { - return (Derived)returnBase(); - } + Derived returnDerived() { + return (Derived)returnBase(); } - """); } + """); + } - [Fact] - public async Task SimpleFunctionArgumentsWithObject1() + [Fact] + public async Task SimpleFunctionArgumentsWithObject1() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void passDerived(Derived d) {} + void passDerived(Derived d) {} - void M() { - Base b; - passDerived([|b|]); - } + void M() { + Base b; + passDerived([|b|]); } - """, - """ - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void passDerived(Derived d) {} + void passDerived(Derived d) {} - void M() { - Base b; - passDerived((Derived)b); - } + void M() { + Base b; + passDerived((Derived)b); } - """); } + """); + } - [Fact] - public async Task SimpleFunctionArgumentsWithObject2() + [Fact] + public async Task SimpleFunctionArgumentsWithObject2() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void passDerived(int i, Derived d) {} + void passDerived(int i, Derived d) {} - void M() { - Base b; - passDerived(1, [|b|]); - } + void M() { + Base b; + passDerived(1, [|b|]); } - """, - """ - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void passDerived(int i, Derived d) {} + void passDerived(int i, Derived d) {} - void M() { - Base b; - passDerived(1, (Derived)b); - } + void M() { + Base b; + passDerived(1, (Derived)b); } - """); } + """); + } - [Fact] - public async Task SimpleFunctionArgumentsWithFunctionInvocation() + [Fact] + public async Task SimpleFunctionArgumentsWithFunctionInvocation() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void passDerived(Derived d) {} + void passDerived(Derived d) {} - void M() { - passDerived([|returnBase()|]); - } + void M() { + passDerived([|returnBase()|]); } - """, - """ - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - Base returnBase() { - Base b; - return b; - } + Base returnBase() { + Base b; + return b; + } - void passDerived(Derived d) {} + void passDerived(Derived d) {} - void M() { - passDerived((Derived)returnBase()); - } + void M() { + passDerived((Derived)returnBase()); } - """); } + """); + } - [Fact] - public async Task YieldReturnStatementWithObject() + [Fact] + public async Task YieldReturnStatementWithObject() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; + class Program { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - IEnumerable returnDerived() { - Base b; - yield return [|b|]; - } + IEnumerable returnDerived() { + Base b; + yield return [|b|]; } - """, - """ - using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + } + """, + """ + using System.Collections.Generic; + class Program + { + class Base {} + class Derived : Base {} - IEnumerable returnDerived() { - Base b; - yield return (Derived)b; - } + IEnumerable returnDerived() { + Base b; + yield return (Derived)b; } - """); } + """); + } - [Fact] - public async Task SimpleConstructorArgumentsWithObject() + [Fact] + public async Task SimpleConstructorArgumentsWithObject() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Test(Derived d) {} - } + class Base {} + class Derived : Base {} + class Test { + public Test(Derived d) {} + } - void M() { - Base b; - Test t = new Test(b[||]); - } + void M() { + Base b; + Test t = new Test(b[||]); + } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} + class Test { + public Test(Derived d) {} } - """, - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Test(Derived d) {} - } - void M() { - Base b; - Test t = new Test((Derived)b); - } + void M() { + Base b; + Test t = new Test((Derived)b); } - """); } + """); + } - [Fact] - public async Task ReturnTypeWithTask() - { - await TestInRegularAndScriptAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task ReturnTypeWithTask() + { + await TestInRegularAndScriptAsync( + """ + using System.Threading.Tasks; - class Program - { - class Base {} - class Derived : Base {} + class Program + { + class Base {} + class Derived : Base {} - async Task M() { - Base b; - return [||]b; - } + async Task M() { + Base b; + return [||]b; } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class Program - { - class Base {} - class Derived : Base {} + class Program + { + class Base {} + class Derived : Base {} - async Task M() { - Base b; - return (Derived)b; - } + async Task M() { + Base b; + return (Derived)b; } - """); } + """); + } - [Fact] - public async Task VariableDeclarationWithPublicFieldMember() + [Fact] + public async Task VariableDeclarationWithPublicFieldMember() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Base b; - public Test(Base b) { this.b = b; } - } - - void M() { - Base b; - Test t = new Test(b); - Derived d = [||]t.b; - } + class Base {} + class Derived : Base {} + class Test { + public Base b; + public Test(Base b) { this.b = b; } } - """, - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Base b; - public Test(Base b) { this.b = b; } - } - void M() { - Base b; - Test t = new Test(b); - Derived d = (Derived)t.b; - } + void M() { + Base b; + Test t = new Test(b); + Derived d = [||]t.b; } - """); } - - [Fact] - public async Task VariableDeclarationWithPrivateFieldMember() + """, + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - Base b; - public Test(Base b) { this.b = b; } - } + class Base {} + class Derived : Base {} + class Test { + public Base b; + public Test(Base b) { this.b = b; } + } - void M() { - Base b; - Test t = new Test(b); - Derived d = [||]t.b; - } + void M() { + Base b; + Test t = new Test(b); + Derived d = (Derived)t.b; } - """); } + """); + } - [Fact] - public async Task PublicMemberFunctionArgument1() + [Fact] + public async Task VariableDeclarationWithPrivateFieldMember() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; + class Base {} + class Derived : Base {} + class Test { + Base b; + public Test(Base b) { this.b = b; } + } - class Program - { - class Base {} - class Derived : Base {} + void M() { + Base b; + Test t = new Test(b); + Derived d = [||]t.b; + } + } + """); + } - void M() { - Base b; - List list = new List(); - list.Add(b[||]); - } + [Fact] + public async Task PublicMemberFunctionArgument1() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; + + class Program + { + class Base {} + class Derived : Base {} + + void M() { + Base b; + List list = new List(); + list.Add(b[||]); } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class Program - { - class Base {} - class Derived : Base {} + class Program + { + class Base {} + class Derived : Base {} - void M() { - Base b; - List list = new List(); - list.Add((Derived)b); - } + void M() { + Base b; + List list = new List(); + list.Add((Derived)b); } - """); } + """); + } - [Fact] - public async Task PublicMemberFunctionArgument2() + [Fact] + public async Task PublicMemberFunctionArgument2() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public void testing(Derived d) {} - } + class Base {} + class Derived : Base {} + class Test { + public void testing(Derived d) {} + } - void M() { - Base b; - Test t; - t.testing(b[||]); - } + void M() { + Base b; + Test t; + t.testing(b[||]); + } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} + class Test { + public void testing(Derived d) {} } - """, - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public void testing(Derived d) {} - } - void M() { - Base b; - Test t; - t.testing((Derived)b); - } + void M() { + Base b; + Test t; + t.testing((Derived)b); } - """); } + """); + } - [Fact] - public async Task PrivateMemberFunctionArgument() + [Fact] + public async Task PrivateMemberFunctionArgument() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - private void testing(Derived d) {} - } + class Base {} + class Derived : Base {} + class Test { + private void testing(Derived d) {} + } - void M() { - Base b; - Test t; - t.testing(b[||]); - } + void M() { + Base b; + Test t; + t.testing(b[||]); } - """); } + """); + } - [Fact] - public async Task MemberFunctions() + [Fact] + public async Task MemberFunctions() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public void testing(Derived d) {} - private void testing(Base b) {} - } + class Base {} + class Derived : Base {} + class Test { + public void testing(Derived d) {} + private void testing(Base b) {} + } - void M() { - Base b; - Test t; - t.testing(b[||]); - } + void M() { + Base b; + Test t; + t.testing(b[||]); + } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} + class Test { + public void testing(Derived d) {} + private void testing(Base b) {} } - """, - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public void testing(Derived d) {} - private void testing(Base b) {} - } - void M() { - Base b; - Test t; - t.testing((Derived)b); - } + void M() { + Base b; + Test t; + t.testing((Derived)b); } - """); } + """); + } - [Fact] - public async Task BaseConstructorArgument() + [Fact] + public async Task BaseConstructorArgument() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Test(Derived d) {} - } - class Derived_Test : Test { - public Derived_Test (Base b) : base([||]b) {} - } + class Base {} + class Derived : Base {} + class Test { + public Test(Derived d) {} } - """, - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Test(Derived d) {} - } - class Derived_Test : Test { - public Derived_Test (Base b) : base((Derived)b) {} - } + class Derived_Test : Test { + public Derived_Test (Base b) : base([||]b) {} } - """); } - - [Fact] - public async Task ThisConstructorArgument() + """, + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Test(Derived d) {} - public Test(Base b, int i) : this([||]b) {} - } + class Base {} + class Derived : Base {} + class Test { + public Test(Derived d) {} } - """, - """ - class Program - { - class Base {} - class Derived : Base {} - class Test { - public Test(Derived d) {} - public Test(Base b, int i) : this((Derived)b) {} - } + class Derived_Test : Test { + public Derived_Test (Base b) : base((Derived)b) {} } - """); } + """); + } - [Fact] - public async Task LambdaFunction1() + [Fact] + public async Task ThisConstructorArgument() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} - void M() { - Func foo = d => [||]d; - } + class Base {} + class Derived : Base {} + class Test { + public Test(Derived d) {} + public Test(Base b, int i) : this([||]b) {} } - """, - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} - void M() { - Func foo = d => (Derived)d; - } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} + class Test { + public Test(Derived d) {} + public Test(Base b, int i) : this((Derived)b) {} } - """); } + """); + } - [Fact] - public async Task LambdaFunction2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task LambdaFunction1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class Program - { - class Base {} - class Derived : Base {} + class Program + { + class Base {} + class Derived : Base {} + void M() { + Func foo = d => [||]d; + } + } + """, + """ + using System; - void Goo() { - Func func = d => d; - Base b; - Base b2 = func([||]b); - } + class Program + { + class Base {} + class Derived : Base {} + void M() { + Func foo = d => (Derived)d; } - """, - """ - using System; + } + """); + } - class Program - { - class Base {} - class Derived : Base {} + [Fact] + public async Task LambdaFunction2() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Goo() { - Func func = d => d; - Base b; - Base b2 = func((Derived)b); - } + class Program + { + class Base {} + class Derived : Base {} + + void Goo() { + Func func = d => d; + Base b; + Base b2 = func([||]b); } - """); } + """, + """ + using System; - [Fact] - public async Task LambdaFunction3() + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - void Goo() { - Func func = d => d; - Base b; - Derived b2 = [||]func(b); - } + void Goo() { + Func func = d => d; + Base b; + Base b2 = func((Derived)b); } - """, - """ - using System; + } + """); + } - class Program - { - class Base {} - class Derived : Base {} + [Fact] + public async Task LambdaFunction3() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Goo() { - Func func = d => d; - Base b; - Derived b2 = (Derived)func(b); - } + class Program + { + class Base {} + class Derived : Base {} + + void Goo() { + Func func = d => d; + Base b; + Derived b2 = [||]func(b); } - """); } + """, + """ + using System; - [Fact] - public async Task LambdaFunction4() + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Derived Goo() { - Func func = d => d; - Base b; - return [||]func(b); - } + void Goo() { + Func func = d => d; + Base b; + Derived b2 = (Derived)func(b); } - """, - """ - using System; + } + """); + } - class Program - { - class Base {} - class Derived : Base {} + [Fact] + public async Task LambdaFunction4() + { + await TestInRegularAndScriptAsync( + """ + using System; - Derived Goo() { - Func func = d => d; - Base b; - return (Derived)func(b); - } + class Program + { + class Base {} + class Derived : Base {} + + Derived Goo() { + Func func = d => d; + Base b; + return [||]func(b); } - """); } + """, + """ + using System; - [Fact] - public async Task LambdaFunction5_ReturnStatement() + class Program { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - Action Goo() { - return [||](Base b) => { }; - } + Derived Goo() { + Func func = d => d; + Base b; + return (Derived)func(b); } - """); } + """); + } - [Fact] - public async Task LambdaFunction6_Arguments() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task LambdaFunction5_ReturnStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program - { - class Base {} - class Derived : Base {} + class Program + { + class Base {} + class Derived : Base {} - void M(Derived d, Action action) { } - void Goo() { - Base b = new Derived(); - M([||]b, (Derived d) => { }); - } + Action Goo() { + return [||](Base b) => { }; } - """, - """ - using System; + } + """); + } - class Program - { - class Base {} - class Derived : Base {} + [Fact] + public async Task LambdaFunction6_Arguments() + { + await TestInRegularAndScriptAsync( + """ + using System; - void M(Derived d, Action action) { } - void Goo() { - Base b = new Derived(); - M((Derived)b, (Derived d) => { }); - } + class Program + { + class Base {} + class Derived : Base {} + + void M(Derived d, Action action) { } + void Goo() { + Base b = new Derived(); + M([||]b, (Derived d) => { }); } - """); } + """, + """ + using System; - [Fact] - public async Task LambdaFunction7_Arguments() + class Program { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - void M(Derived d, Action action) { } - void Goo() { - Base b = new Derived(); - M([||]b, (Base base) => { }); - } + void M(Derived d, Action action) { } + void Goo() { + Base b = new Derived(); + M((Derived)b, (Derived d) => { }); } - """); } + """); + } + + [Fact] + public async Task LambdaFunction7_Arguments() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - [Fact] - public async Task LambdaFunction8_Arguments() + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - void M(Derived d, params Action[] action) { } - void Goo() { - Base b1 = new Derived(); - M([||]b1, (Derived d) => { }, (Derived d) => { }); - } + void M(Derived d, Action action) { } + void Goo() { + Base b = new Derived(); + M([||]b, (Base base) => { }); } - """, - """ - using System; + } + """); + } - class Program - { - class Base {} - class Derived : Base {} + [Fact] + public async Task LambdaFunction8_Arguments() + { + await TestInRegularAndScriptAsync( + """ + using System; - void M(Derived d, params Action[] action) { } - void Goo() { - Base b1 = new Derived(); - M((Derived)b1, (Derived d) => { }, (Derived d) => { }); - } + class Program + { + class Base {} + class Derived : Base {} + + void M(Derived d, params Action[] action) { } + void Goo() { + Base b1 = new Derived(); + M([||]b1, (Derived d) => { }, (Derived d) => { }); } - """); } + """, + """ + using System; - [Fact] - public async Task LambdaFunction9_Arguments() + class Program { - await TestMissingInRegularAndScriptAsync( - """ - using System; + class Base {} + class Derived : Base {} - class Program - { - class Base {} - class Derived : Base {} + void M(Derived d, params Action[] action) { } + void Goo() { + Base b1 = new Derived(); + M((Derived)b1, (Derived d) => { }, (Derived d) => { }); + } + } + """); + } - void M(Derived d, params Action[] action) { } - void Goo() { - Base b1 = new Derived(); - M([||]b1, action: new Action[0], (Derived d) => { }, (Derived d) => { }); - } + [Fact] + public async Task LambdaFunction9_Arguments() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class Program + { + class Base {} + class Derived : Base {} + + void M(Derived d, params Action[] action) { } + void Goo() { + Base b1 = new Derived(); + M([||]b1, action: new Action[0], (Derived d) => { }, (Derived d) => { }); } - """); } + """); + } - [Fact] - public async Task InheritInterfaces1() + [Fact] + public async Task InheritInterfaces1() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - interface Base1 {} - interface Base2 {} - class Derived : Base1, Base2 {} + interface Base1 {} + interface Base2 {} + class Derived : Base1, Base2 {} - void Goo(Base2 b) { - Derived d = [||]b; - } + void Goo(Base2 b) { + Derived d = [||]b; } - """, - """ - class Program - { - interface Base1 {} - interface Base2 {} - class Derived : Base1, Base2 {} + } + """, + """ + class Program + { + interface Base1 {} + interface Base2 {} + class Derived : Base1, Base2 {} - void Goo(Base2 b) { - Derived d = (Derived)b; - } + void Goo(Base2 b) { + Derived d = (Derived)b; } - """); } + """); + } - [Fact] - public async Task InheritInterfaces2() + [Fact] + public async Task InheritInterfaces2() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - interface Base1 {} - interface Base2 {} - class Derived1 : Base1, Base2 {} - class Derived2 : Derived1 {} + interface Base1 {} + interface Base2 {} + class Derived1 : Base1, Base2 {} + class Derived2 : Derived1 {} - void Goo(Base2 b) { - Derived2 d = [||]b; - } + void Goo(Base2 b) { + Derived2 d = [||]b; } - """, - """ - class Program - { - interface Base1 {} - interface Base2 {} - class Derived1 : Base1, Base2 {} - class Derived2 : Derived1 {} + } + """, + """ + class Program + { + interface Base1 {} + interface Base2 {} + class Derived1 : Base1, Base2 {} + class Derived2 : Derived1 {} - void Goo(Base2 b) { - Derived2 d = (Derived2)b; - } + void Goo(Base2 b) { + Derived2 d = (Derived2)b; } - """); } + """); + } - [Fact] - public async Task InheritInterfaces3() + [Fact] + public async Task InheritInterfaces3() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - interface Base1 {} - interface Base2 : Base1 {} + interface Base1 {} + interface Base2 : Base1 {} - Base2 Goo(Base1 b) { - return [||]b; - } + Base2 Goo(Base1 b) { + return [||]b; } - """, - """ - class Program - { - interface Base1 {} - interface Base2 : Base1 {} + } + """, + """ + class Program + { + interface Base1 {} + interface Base2 : Base1 {} - Base2 Goo(Base1 b) { - return (Base2)b; - } + Base2 Goo(Base1 b) { + return (Base2)b; } - """); } + """); + } - [Fact] - public async Task InheritInterfaces4() + [Fact] + public async Task InheritInterfaces4() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - interface Base1 {} - interface Base2 : Base1 {} + interface Base1 {} + interface Base2 : Base1 {} - void Goo(Base1 b) { - Base2 b2 = [||]b; - } + void Goo(Base1 b) { + Base2 b2 = [||]b; } - """, - """ - class Program - { - interface Base1 {} - interface Base2 : Base1 {} + } + """, + """ + class Program + { + interface Base1 {} + interface Base2 : Base1 {} - void Goo(Base1 b) { - Base2 b2 = (Base2)b; - } + void Goo(Base1 b) { + Base2 b2 = (Base2)b; } - """); } + """); + } - [Fact] - public async Task InheritInterfaces5() + [Fact] + public async Task InheritInterfaces5() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - interface Base1 {} - interface Base2 : Base1 {} - interface Base3 {} - class Derived1 : Base2, Base3 {} - class Derived2 : Derived1 {} + interface Base1 {} + interface Base2 : Base1 {} + interface Base3 {} + class Derived1 : Base2, Base3 {} + class Derived2 : Derived1 {} - void Goo(Derived2 b) {} - void M(Base1 b) { - Goo([||]b); - } + void Goo(Derived2 b) {} + void M(Base1 b) { + Goo([||]b); } - """, - """ - class Program - { - interface Base1 {} - interface Base2 : Base1 {} - interface Base3 {} - class Derived1 : Base2, Base3 {} - class Derived2 : Derived1 {} + } + """, + """ + class Program + { + interface Base1 {} + interface Base2 : Base1 {} + interface Base3 {} + class Derived1 : Base2, Base3 {} + class Derived2 : Derived1 {} - void Goo(Derived2 b) {} - void M(Base1 b) { - Goo((Derived2)b); - } + void Goo(Derived2 b) {} + void M(Base1 b) { + Goo((Derived2)b); } - """); } + """); + } - [Fact] - public async Task GenericType() + [Fact] + public async Task GenericType() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - void M() - { - Func func1 = b => b; - Func func2 = [||]func1; - } - } - """, - """ - using System; - class Program + void M() { - class Base {} - class Derived : Base {} + Func func1 = b => b; + Func func2 = [||]func1; + } + } + """, + """ + using System; + class Program + { + class Base {} + class Derived : Base {} - void M() - { - Func func1 = b => b; - Func func2 = (Func)func1; - } + void M() + { + Func func1 = b => b; + Func func2 = (Func)func1; } - """); } + """); + } - [Fact] - public async Task GenericType2() + [Fact] + public async Task GenericType2() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - class Program - { - class Base { } - class Derived : Base { } - void Goo(Func func) { } + class Base { } + class Derived : Base { } + void Goo(Func func) { } - void M() - { - Func func1 = b => b; - Goo(func1[||]); - } - } - """, - """ - using System; - class Program + void M() { - class Base { } - class Derived : Base { } - void Goo(Func func) { } + Func func1 = b => b; + Goo(func1[||]); + } + } + """, + """ + using System; + class Program + { + class Base { } + class Derived : Base { } + void Goo(Func func) { } - void M() - { - Func func1 = b => b; - Goo((Func)func1); - } + void M() + { + Func func1 = b => b; + Goo((Func)func1); } - """); } + """); + } - [Fact] - public async Task GenericType3() + [Fact] + public async Task GenericType3() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + class Base { } + class Derived : Base { } + Func Goo(Func func) { - class Base { } - class Derived : Base { } - Func Goo(Func func) - { - Func func1 = b => b; - return func1[||]; - } + Func func1 = b => b; + return func1[||]; } - """, - """ - using System; - class Program + } + """, + """ + using System; + class Program + { + class Base { } + class Derived : Base { } + Func Goo(Func func) { - class Base { } - class Derived : Base { } - Func Goo(Func func) - { - Func func1 = b => b; - return (Func)func1; - } + Func func1 = b => b; + return (Func)func1; } - """); } + """); + } - [Fact] - public async Task GenericType4() + [Fact] + public async Task GenericType4() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + void Goo() { - void Goo() - { - B b = null; - A c1 = [||]b; - } + B b = null; + A c1 = [||]b; + } - public interface IA { } - public class CB : IA { } - public interface A where T : IA { } + public interface IA { } + public class CB : IA { } + public interface A where T : IA { } - public class B : A where T : CB { } - } - """, - """ - class Program + public class B : A where T : CB { } + } + """, + """ + class Program + { + void Goo() { - void Goo() - { - B b = null; - A c1 = (A)b; - } + B b = null; + A c1 = (A)b; + } - public interface IA { } - public class CB : IA { } - public interface A where T : IA { } + public interface IA { } + public class CB : IA { } + public interface A where T : IA { } - public class B : A where T : CB { } - } - """); + public class B : A where T : CB { } } + """); + } - [Fact] - public async Task GenericType5() + [Fact] + public async Task GenericType5() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + void Goo() { - void Goo() - { - B b = null; - A c1 = [||]b; - } + B b = null; + A c1 = [||]b; + } - public interface IA { } - public interface IB : IA { } - public class A where T : IA { } + public interface IA { } + public interface IB : IA { } + public class A where T : IA { } - public class B : A where T : IB { } - } - """); + public class B : A where T : IB { } } + """); + } - [Fact] - public async Task GenericType6() + [Fact] + public async Task GenericType6() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + void Goo() { - void Goo() - { - B b = null; - A c1 = [||]b; - } + B b = null; + A c1 = [||]b; + } - public interface IA { } - public class IB : IA { } - public interface A where T : IA { } + public interface IA { } + public class IB : IA { } + public interface A where T : IA { } - public class B : A where T : IB { } - } - """, - """ - class Program + public class B : A where T : IB { } + } + """, + """ + class Program + { + void Goo() { - void Goo() - { - B b = null; - A c1 = (A)b; - } + B b = null; + A c1 = (A)b; + } - public interface IA { } - public class IB : IA { } - public interface A where T : IA { } + public interface IA { } + public class IB : IA { } + public interface A where T : IA { } - public class B : A where T : IB { } - } - """); + public class B : A where T : IB { } } + """); + } - [Fact] - public async Task ObjectInitializer() + [Fact] + public async Task ObjectInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M() { - Derived d = [||]new Base(); - Derived d2 = new Test(); - } + static public explicit operator Derived(Test t) { return new Derived(); } + } + void M() { + Derived d = [||]new Base(); + Derived d2 = new Test(); } - """); } + """); + } - [Fact] - public async Task ObjectInitializer2() + [Fact] + public async Task ObjectInitializer2() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M() { - Derived d = new Base(); - Derived d2 = [||]new Test(); - } + static public explicit operator Derived(Test t) { return new Derived(); } } - """, - """ - class Program - { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M() { - Derived d = new Base(); - Derived d2 = (Derived)new Test(); - } + void M() { + Derived d = new Base(); + Derived d2 = [||]new Test(); } - """); } - - [Fact] - public async Task ObjectInitializer3() + """, + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - Derived returnDerived() { - return [||]new Base(); - } + static public explicit operator Derived(Test t) { return new Derived(); } + } + void M() { + Derived d = new Base(); + Derived d2 = (Derived)new Test(); } - """); } + """); + } - [Fact] - public async Task ObjectInitializer4() + [Fact] + public async Task ObjectInitializer3() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - Derived returnDerived() { - return [||]new Test(); - } + static public explicit operator Derived(Test t) { return new Derived(); } } - """, - """ - class Program - { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - Derived returnDerived() { - return (Derived)new Test(); - } + Derived returnDerived() { + return [||]new Base(); } - """); } + """); + } - [Fact] - public async Task ObjectInitializer5() + [Fact] + public async Task ObjectInitializer4() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M(Derived d) { } - void Goo() { - M([||]new Base()); - } + static public explicit operator Derived(Test t) { return new Derived(); } + } + Derived returnDerived() { + return [||]new Test(); } - """); } - - [Fact] - public async Task ObjectInitializer6() + """, + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M(Derived d) { } - void Goo() { - M([||]new Test()); - } + static public explicit operator Derived(Test t) { return new Derived(); } } - """, - """ - class Program - { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M(Derived d) { } - void Goo() { - M((Derived)new Test()); - } + Derived returnDerived() { + return (Derived)new Test(); } - """); } + """); + } - [Fact] - public async Task ObjectInitializer7() + [Fact] + public async Task ObjectInitializer5() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - class Test - { - static public explicit operator Derived(Test t) { return new Derived(); } - } - void M(Derived d) { } - void Goo() { - M([||]new Base()); - } + static public explicit operator Derived(Test t) { return new Derived(); } + } + void M(Derived d) { } + void Goo() { + M([||]new Base()); } - """); } + """); + } - [Fact] - public async Task RedundantCast1() + [Fact] + public async Task ObjectInitializer6() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - void Goo() { - Base b; - Derived d = [||](Base)b; - } + static public explicit operator Derived(Test t) { return new Derived(); } } - """, - """ - class Program + void M(Derived d) { } + void Goo() { + M([||]new Test()); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived : Base { } - void Goo() { - Base b; - Derived d = (Derived)b; - } + static public explicit operator Derived(Test t) { return new Derived(); } + } + void M(Derived d) { } + void Goo() { + M((Derived)new Test()); } - """); } + """); + } - [Fact] - public async Task RedundantCast2() + [Fact] + public async Task ObjectInitializer7() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + class Test { - class Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - void Goo() { - Base b; - Derived2 d = [||](Derived1)b; - } + static public explicit operator Derived(Test t) { return new Derived(); } } - """, - """ - class Program - { - class Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - void Goo() { - Base b; - Derived2 d = (Derived2)b; - } + void M(Derived d) { } + void Goo() { + M([||]new Base()); } - """); } + """); + } - [Fact] - public async Task RedundantCast3() + [Fact] + public async Task RedundantCast1() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } - void M(Derived d) { } - void Goo() { - Base b; - M([||](Base)b); - } + class Base { } + class Derived : Base { } + void Goo() { + Base b; + Derived d = [||](Base)b; } - """, - """ - class Program - { - class Base { } - class Derived : Base { } - void M(Derived d) { } - void Goo() { - Base b; - M((Derived)b); - } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } + void Goo() { + Base b; + Derived d = (Derived)b; } - """); } + """); + } - [Fact] - public async Task RedundantCast4() + [Fact] + public async Task RedundantCast2() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - void M(Derived2 d) { } - void Goo() { - Base b; - M([||](Derived1)b); - } + class Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + void Goo() { + Base b; + Derived2 d = [||](Derived1)b; } - """, - """ - class Program - { - class Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - void M(Derived2 d) { } - void Goo() { - Base b; - M((Derived2)b); - } + } + """, + """ + class Program + { + class Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + void Goo() { + Base b; + Derived2 d = (Derived2)b; } - """); } + """); + } - [Fact] - public async Task ExactMethodCandidate() + [Fact] + public async Task RedundantCast3() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - class Base - { - public void Testing(Base d) { } - } - class Derived : Base - { - public void Testing(Derived d) { } - } + class Base { } + class Derived : Base { } + void M(Derived d) { } + void Goo() { + Base b; + M([||](Base)b); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } + void M(Derived d) { } + void Goo() { + Base b; + M((Derived)b); + } + } + """); + } - void M() - { - Base b = new Base(); - Derived d = new Derived(); - d.Testing([||]b); - } + [Fact] + public async Task RedundantCast4() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + void M(Derived2 d) { } + void Goo() { + Base b; + M([||](Derived1)b); } - """); } + """, + """ + class Program + { + class Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + void M(Derived2 d) { } + void Goo() { + Base b; + M((Derived2)b); + } + } + """); + } - [Fact] - public async Task MethodCandidates1_ArgumentsInOrder_NoLabels() + [Fact] + public async Task ExactMethodCandidate() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { - class Base {} - class Derived : Base {} - - void Goo(string s, Derived d) {} - void Goo(string s, int i) {} - - void M() - { - Base b = new Base(); - Goo("", [||]b); - } + public void Testing(Base d) { } } - """, - """ - class Program + class Derived : Base { - class Base {} - class Derived : Base {} - - void Goo(string s, Derived d) {} - void Goo(string s, int i) {} + public void Testing(Derived d) { } + } - void M() - { - Base b = new Base(); - Goo("", (Derived)b); - } + void M() + { + Base b = new Base(); + Derived d = new Derived(); + d.Testing([||]b); } - """); } + """); + } - [Fact] - public async Task MethodCandidates2_ArgumentsInOrder_NoLabels() + [Fact] + public async Task MethodCandidates1_ArgumentsInOrder_NoLabels() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived : Base {} + class Base {} + class Derived : Base {} - void Goo(string s, Derived d, out int i) { - i = 1; - } - void Goo(string s, Derived d) {} + void Goo(string s, Derived d) {} + void Goo(string s, int i) {} - void M() - { - Base b = new Base(); - Goo("", [||]b, out var i); - } - } - """, - """ - class Program + void M() { - class Base {} - class Derived : Base {} + Base b = new Base(); + Goo("", [||]b); + } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - void Goo(string s, Derived d, out int i) { - i = 1; - } - void Goo(string s, Derived d) {} + void Goo(string s, Derived d) {} + void Goo(string s, int i) {} - void M() - { - Base b = new Base(); - Goo("", (Derived)b, out var i); - } + void M() + { + Base b = new Base(); + Goo("", (Derived)b); } - """); } + """); + } - [Fact] - public async Task MethodCandidates3_ArgumentsInOrder_NoLabels_Params() + [Fact] + public async Task MethodCandidates2_ArgumentsInOrder_NoLabels() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base {} + class Derived : Base {} - void Goo(string s, Derived d, out int i, params object[] list) - { - i = 1; - } + void Goo(string s, Derived d, out int i) { + i = 1; + } + void Goo(string s, Derived d) {} - void M() - { - Base b = new Base(); - Goo("", [||]b, out var i); - } - } - """, - """ - class Program + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", [||]b, out var i); + } + } + """, + """ + class Program + { + class Base {} + class Derived : Base {} - void Goo(string s, Derived d, out int i, params object[] list) - { - i = 1; - } + void Goo(string s, Derived d, out int i) { + i = 1; + } + void Goo(string s, Derived d) {} - void M() - { - Base b = new Base(); - Goo("", (Derived)b, out var i); - } + void M() + { + Base b = new Base(); + Goo("", (Derived)b, out var i); } - """); } + """); + } - [Fact] - public async Task MethodCandidates4_ArgumentsInOrder_NoLabels_Params() + [Fact] + public async Task MethodCandidates3_ArgumentsInOrder_NoLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + + void Goo(string s, Derived d, out int i, params object[] list) { - class Base { } - class Derived : Base { } + i = 1; + } - void Goo(string s, Derived d, out int i, params object[] list) - { - i = 1; - } + void M() + { + Base b = new Base(); + Goo("", [||]b, out var i); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - void M() - { - Base b = new Base(); - Goo("", [||]b, out var i, 1); - } + void Goo(string s, Derived d, out int i, params object[] list) + { + i = 1; } - """, - """ - class Program + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", (Derived)b, out var i); + } + } + """); + } - void Goo(string s, Derived d, out int i, params object[] list) - { - i = 1; - } + [Fact] + public async Task MethodCandidates4_ArgumentsInOrder_NoLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } - void M() - { - Base b = new Base(); - Goo("", (Derived)b, out var i, 1); - } + void Goo(string s, Derived d, out int i, params object[] list) + { + i = 1; } - """); - } - [Fact] - public async Task MethodCandidates5_ArgumentsInOrder_NoLabels_Params() + void M() + { + Base b = new Base(); + Goo("", [||]b, out var i, 1); + } + } + """, + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + + void Goo(string s, Derived d, out int i, params object[] list) { - class Base { } - class Derived : Base { } + i = 1; + } - void Goo(string s, Derived d, out int i, params object[] list) - { - i = 1; - } + void M() + { + Base b = new Base(); + Goo("", (Derived)b, out var i, 1); + } + } + """); + } - void M() - { - Base b = new Base(); - Goo("", [||]b, out var i, 1, 2, 3); - } + [Fact] + public async Task MethodCandidates5_ArgumentsInOrder_NoLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } + + void Goo(string s, Derived d, out int i, params object[] list) + { + i = 1; } - """, - """ - class Program + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", [||]b, out var i, 1, 2, 3); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - void Goo(string s, Derived d, out int i, params object[] list) - { - i = 1; - } + void Goo(string s, Derived d, out int i, params object[] list) + { + i = 1; + } - void M() - { - Base b = new Base(); - Goo("", (Derived)b, out var i, 1, 2, 3); - } + void M() + { + Base b = new Base(); + Goo("", (Derived)b, out var i, 1, 2, 3); } - """); } + """); + } - [Fact] - public async Task MethodCandidates6_ArgumentsInOrder_NoLabels_Params() + [Fact] + public async Task MethodCandidates6_ArgumentsInOrder_NoLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, params Derived2[] list) { } + void Goo(string s, Derived d, params Derived2[] list) { } - void M() - { - Base b = new Base(); - Goo("", [||]b); - } - } - """, - """ - class Program + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", [||]b); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, params Derived2[] list) { } + void Goo(string s, Derived d, params Derived2[] list) { } - void M() - { - Base b = new Base(); - Goo("", (Derived)b); - } + void M() + { + Base b = new Base(); + Goo("", (Derived)b); } - """); } + """); + } - [Fact] - public async Task MethodCandidates7_ArgumentsInOrder_NoLabels_Params() + [Fact] + public async Task MethodCandidates7_ArgumentsInOrder_NoLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, params Derived2[] list) { } + void Goo(string s, Derived d, params Derived2[] list) { } - void M() - { - Base b = new Base(); - Goo("", b, [||]b); - } - } - """, - """ - class Program + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", b, [||]b); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, params Derived2[] list) { } + void Goo(string s, Derived d, params Derived2[] list) { } - void M() - { - Base b = new Base(); - Goo("", b, (Derived2)b); - } + void M() + { + Base b = new Base(); + Goo("", b, (Derived2)b); } - """); } + """); + } - [Fact] - public async Task MethodCandidates8_ArgumentsInOrder_NoLabels() + [Fact] + public async Task MethodCandidates8_ArgumentsInOrder_NoLabels() + { + await TestInRegularAndScriptAsync( + """ + namespace ExtensionMethods { - await TestInRegularAndScriptAsync( - """ - namespace ExtensionMethods - { - public class Base { } - public class Derived : Base { } + public class Base { } + public class Derived : Base { } - class Program - { - Program() - { - string s = ""; - Base b = new Derived(); - Derived d = new Derived(); - s.Goo([||]b, d); - } - } - public static class MyExtensions + class Program + { + Program() { - public static void Goo(this string str, Derived d, Derived d2) { } + string s = ""; + Base b = new Derived(); + Derived d = new Derived(); + s.Goo([||]b, d); } } - """, - """ - namespace ExtensionMethods + public static class MyExtensions { - public class Base { } - public class Derived : Base { } + public static void Goo(this string str, Derived d, Derived d2) { } + } + } + """, + """ + namespace ExtensionMethods + { + public class Base { } + public class Derived : Base { } - class Program - { - Program() - { - string s = ""; - Base b = new Derived(); - Derived d = new Derived(); - s.Goo((Derived)b, d); - } - } - public static class MyExtensions + class Program + { + Program() { - public static void Goo(this string str, Derived d, Derived d2) { } + string s = ""; + Base b = new Derived(); + Derived d = new Derived(); + s.Goo((Derived)b, d); } } - """); + public static class MyExtensions + { + public static void Goo(this string str, Derived d, Derived d2) { } + } } + """); + } - [Fact] - public async Task MethodCandidates9_ArgumentsOutOfOrder_NoLabels() + [Fact] + public async Task MethodCandidates9_ArgumentsOutOfOrder_NoLabels() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - class Base {} - class Derived1 : Base {} - class Derived2 : Derived1 {} + class Base {} + class Derived1 : Base {} + class Derived2 : Derived1 {} - void Goo(string s, Derived d) {} - void Goo(string s, int i) {} + void Goo(string s, Derived d) {} + void Goo(string s, int i) {} - void M() - { - Base b = new Base(); - Goo(b[||], ""); - } + void M() + { + Base b = new Base(); + Goo(b[||], ""); } - """); } + """); + } - [Fact] - public async Task MethodCandidates10_ArgumentsInOrder_SomeLabels() + [Fact] + public async Task MethodCandidates10_ArgumentsInOrder_SomeLabels() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i) { } + void Goo(string s, Derived d, int i) { } - void M() - { - Base b = new Base(); - Goo("", d: [||]b, 1); - } - } - """, - """ - class Program + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", d: [||]b, 1); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i) { } + void Goo(string s, Derived d, int i) { } - void M() - { - Base b = new Base(); - Goo("", d: (Derived)b, 1); - } + void M() + { + Base b = new Base(); + Goo("", d: (Derived)b, 1); } - """); } + """); + } - [Fact] - public async Task MethodCandidates11_ArgumentsInOrder_SomeLabels_Params() + [Fact] + public async Task MethodCandidates11_ArgumentsInOrder_SomeLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(string s, Derived d, int i, params object[] list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: [||]b, 1, list: strlist); - } - } - """, - """ - class Program + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: [||]b, 1, list: strlist); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(string s, Derived d, int i, params object[] list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (Derived)b, 1, list: strlist); - } + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: (Derived)b, 1, list: strlist); } - """); } + """); + } - [Fact] - public async Task MethodCandidates12_ArgumentsInOrder_SomeLabels_Params() + [Fact] + public async Task MethodCandidates12_ArgumentsInOrder_SomeLabels_Params() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(string s, Derived d, int i, params object[] list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: [||]b, list: strlist, i: 1); - } + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: [||]b, list: strlist, i: 1); } - """, - """ - class Program + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s, Derived d, int i, params object[] list) { } + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: (Derived)b, list: strlist, i: 1); + } + } + """); + } - class Derived2 : Derived { } + [Fact] + public async Task MethodCandidates13_ArgumentsOutOfOrder_SomeLabels() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } - void Goo(string s, Derived d, int i, params object[] list) { } + class Derived2 : Derived { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (Derived)b, list: strlist, i: 1); - } + void Goo(string s, Derived d, int i) { } + + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo(d: [||]b, "", 1, list: strlist); } - """); } + """); + } - [Fact] - public async Task MethodCandidates13_ArgumentsOutOfOrder_SomeLabels() + [Fact] + public async Task MethodCandidates14_ArgumentsOutOfOrder_AllLabels() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s, Derived d, int i, params object[] list) { } + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + var strlist = new string[1]; + Goo(d: [||]b, s: "", list: strlist, i: 1); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i) { } + void Goo(string s, Derived d, int i, params object[] list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo(d: [||]b, "", 1, list: strlist); - } + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo(d: (Derived)b, s: "", list: strlist, i: 1); } - """); } + """); + } - [Fact] - public async Task MethodCandidates14_ArgumentsOutOfOrder_AllLabels() + [Fact] + public async Task MethodCandidates15_ArgumentsOutOfOrder_AllLabels() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s, Derived d, int i, params object[] list) { } + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + var strlist = new string[1]; + Goo(d: "", s: [||]b, list: strlist, i: 1); + } + } + """); + } - class Derived2 : Derived { } + [Fact] + public async Task MethodCandidates17_ArgumentsInOrder_SomeLabels() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } - void Goo(string s, Derived d, int i, params object[] list) { } + class Derived2 : Derived { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo(d: [||]b, s: "", list: strlist, i: 1); - } + void Goo(string s, Derived d, int i, int j = 1) { } + + void M() + { + Base b = new Base(); + Goo("", d: [||]b, 1); } - """, - """ - class Program + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s, Derived d, int i, int j = 1) { } + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", d: (Derived)b, 1); + } + } + """); + } + + [Fact] + public async Task MethodCandidates18_ArgumentsInOrder_SomeLabels() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s, Derived d, params Derived2[] d2list) { } + + void M() + { + Base b = new Base(); + var dlist = new Derived[] {}; + Goo("", d: b, [||]dlist); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(string s, Derived d, params Derived2[] d2list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo(d: (Derived)b, s: "", list: strlist, i: 1); - } + void M() + { + Base b = new Base(); + var dlist = new Derived[] {}; + Goo("", d: b, (Derived2[])dlist); } - """); } + """); + } - [Fact] - public async Task MethodCandidates15_ArgumentsOutOfOrder_AllLabels() + [Fact] + public async Task MethodCandidates19_ArgumentsInOrder_NoLabels_Params() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(params Derived2[] d2list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo(d: "", s: [||]b, list: strlist, i: 1); - } + void M() + { + Base b = new Base(); + var dlist = new Derived[] {}; + Goo([||]dlist, new Derived2()); } - """); } + """); + } - [Fact] - public async Task MethodCandidates17_ArgumentsInOrder_SomeLabels() + [Fact] + public async Task MethodCandidates20_ArgumentsInOrder_NoLabels_Params() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, int j = 1) { } + void Goo(params Derived2[] d2list) { } - void M() - { - Base b = new Base(); - Goo("", d: [||]b, 1); - } - } - """, - """ - class Program + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + var dlist = new Derived[] {}; + Goo([||]dlist, dlist); + } + } + """); + } - class Derived2 : Derived { } + [Fact] + public async Task MethodCandidates21_ArgumentsInOrder_Labels() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } - void Goo(string s, Derived d, int i, int j = 1) { } + void Goo(Derived d, int i) { } - void M() - { - Base b = new Base(); - Goo("", d: (Derived)b, 1); - } + void M() + { + Base b = new Base(); + Goo([||]b, i:1, i:1); } - """); } + """); + } - [Fact] - public async Task MethodCandidates18_ArgumentsInOrder_SomeLabels() + [Fact] + public async Task MethodCandidates22_ArgumentsInOrder() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program { - await TestInRegularAndScriptAsync( - """ - class Program + class Base {} + class Derived : Base {} + + void Goo(string s, Derived d, out Derived i) { + i = new Derived(); + } + void Goo(string s, Derived d) {} + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + Goo("", [||]b, out Base i); + } + } + """); + } - class Derived2 : Derived { } + [Fact] + public async Task ConstructorCandidates1() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } - void Goo(string s, Derived d, params Derived2[] d2list) { } + class Derived2 : Derived { } - void M() - { - Base b = new Base(); - var dlist = new Derived[] {}; - Goo("", d: b, [||]dlist); - } + class Test + { + public Test(string s, Derived d, int i, params object[] list) { } } - """, - """ - class Program + + void M() { - class Base { } - class Derived : Base { } + Base b = new Base(); + var strlist = new string[1]; + Test t = new Test(d: [||]b, s:"", i:1, list : strlist); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, params Derived2[] d2list) { } + class Test + { + public Test(string s, Derived d, int i, params object[] list) { } + } - void M() - { - Base b = new Base(); - var dlist = new Derived[] {}; - Goo("", d: b, (Derived2[])dlist); - } + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Test t = new Test(d: (Derived)b, s:"", i:1, list : strlist); } - """); } + """); + } - [Fact] - public async Task MethodCandidates19_ArgumentsInOrder_NoLabels_Params() + [Fact] + public async Task ConstructorCandidates2() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + class Test { - class Base { } - class Derived : Base { } + public Test(string s, Derived d, int i, params object[] list) { } + } - class Derived2 : Derived { } + void Goo(string s, Derived d, int i, params object[] list) { } - void Goo(params Derived2[] d2list) { } + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Test t = new Test("", d: [||]b, i:1, "1", "2", "3"); + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - void M() - { - Base b = new Base(); - var dlist = new Derived[] {}; - Goo([||]dlist, new Derived2()); - } + class Derived2 : Derived { } + + class Test + { + public Test(string s, Derived d, int i, params object[] list) { } + } + + void Goo(string s, Derived d, int i, params object[] list) { } + + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Test t = new Test("", d: (Derived)b, i:1, "1", "2", "3"); } - """); } + """); + } - [Fact] - public async Task MethodCandidates20_ArgumentsInOrder_NoLabels_Params() + [Fact] + public async Task ConstructorCandidates3() + { + await TestInRegularAndScriptAsync( + """ + class Program { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(params Derived2[] d2list) { } + class Test + { + public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - void M() - { - Base b = new Base(); - var dlist = new Derived[] {}; - Goo([||]dlist, dlist); - } + class Derived2 : Derived { } + + class Test + { + public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } + Test(string s, Derived d, int i) { } } - """); } + """); + } - [Fact] - public async Task MethodCandidates21_ArgumentsInOrder_Labels() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task MultipleOptions1() + { + var initialMarkup = """ class Program { class Base { } class Derived : Base { } - void Goo(Derived d, int i) { } + class Derived2 : Derived { } - void M() + class Test { - Base b = new Base(); - Goo([||]b, i:1, i:1); + public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + Test(string s, Derived2 d, int i) { } } } - """); + """; + using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) + { + var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); + Assert.Equal(2, actions.Length); } - [Fact] - public async Task MethodCandidates22_ArgumentsInOrder() - { - await TestMissingInRegularAndScriptAsync( + var expect_0 = """ class Program { - class Base {} - class Derived : Base {} + class Base { } + class Derived : Base { } - void Goo(string s, Derived d, out Derived i) { - i = new Derived(); - } - void Goo(string s, Derived d) {} + class Derived2 : Derived { } - void M() + class Test { - Base b = new Base(); - Goo("", [||]b, out Base i); + public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + Test(string s, Derived2 d, int i) { } } } - """); - } + """; + await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); - [Fact] - public async Task ConstructorCandidates1() - { - await TestInRegularAndScriptAsync( + var expect_1 = """ class Program { @@ -2444,17 +2623,20 @@ class Derived2 : Derived { } class Test { - public Test(string s, Derived d, int i, params object[] list) { } - } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Test t = new Test(d: [||]b, s:"", i:1, list : strlist); + public Test(string s, Base b, int i, params object[] list) : this(d : (Derived2)b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + Test(string s, Derived2 d, int i) { } } } - """, + """; + await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); + } + + [Fact] + public async Task MultipleOptions2() + { + var initialMarkup = """ class Program { @@ -2465,23 +2647,20 @@ class Derived2 : Derived { } class Test { - public Test(string s, Derived d, int i, params object[] list) { } - } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Test t = new Test(d: (Derived)b, s:"", i:1, list : strlist); + public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + Test(string s, int i, Derived2 d) { } } } - """); - } + """; - [Fact] - public async Task ConstructorCandidates2() + using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) { - await TestInRegularAndScriptAsync( + var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); + Assert.Equal(2, actions.Length); + } + + var expect_0 = """ class Program { @@ -2492,19 +2671,16 @@ class Derived2 : Derived { } class Test { - public Test(string s, Derived d, int i, params object[] list) { } - } - - void Goo(string s, Derived d, int i, params object[] list) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Test t = new Test("", d: [||]b, i:1, "1", "2", "3"); + public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + Test(string s, int i, Derived2 d) { } } } - """, + """; + await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); + + var expect_1 = """ class Program { @@ -2515,25 +2691,21 @@ class Derived2 : Derived { } class Test { - public Test(string s, Derived d, int i, params object[] list) { } - } - - void Goo(string s, Derived d, int i, params object[] list) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Test t = new Test("", d: (Derived)b, i:1, "1", "2", "3"); + public Test(string s, Base b, int i, params object[] list) : this(d : (Derived2)b, s : s, i : i) { } + Test(string s, Derived d, int i) { } + Test(string s, int i, Derived2 d) { } } } - """); - } + """; + await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); - [Fact] - public async Task ConstructorCandidates3() - { - await TestInRegularAndScriptAsync( + } + + [Fact] + public async Task MultipleOptions3() + { + var initialMarkup = """ class Program { @@ -2546,9 +2718,11 @@ class Test { public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } Test(string s, Derived d, int i) { } + Test(string s, Derived d, int i, params object[] list)) { } } } - """, + """; + var expected = """ class Program { @@ -2561,237 +2735,89 @@ class Test { public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } Test(string s, Derived d, int i) { } + Test(string s, Derived d, int i, params object[] list)) { } } } - """); - } - - [Fact] - public async Task MultipleOptions1() - { - var initialMarkup = - """ - class Program - { - class Base { } - class Derived : Base { } - - class Derived2 : Derived { } + """; + await TestInRegularAndScriptAsync(initialMarkup, expected); + } - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, Derived2 d, int i) { } - } - } - """; - using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) + [Fact] + public async Task MultipleOptions4() + { + var initialMarkup = + """ + class Program { - var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); - Assert.Equal(2, actions.Length); - } - - var expect_0 = - """ - class Program - { - class Base { } - class Derived : Base { } - - class Derived2 : Derived { } - - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, Derived2 d, int i) { } - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); - - var expect_1 = - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } + class Derived2 : Derived { } - class Derived2 : Derived { } + void Goo(string s, int j, int i, Derived d) { } - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : (Derived2)b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, Derived2 d, int i) { } - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); - } + void Goo(string s, int i, Derived2 d) { } - [Fact] - public async Task MultipleOptions2() - { - var initialMarkup = - """ - class Program + void M() { - class Base { } - class Derived : Base { } - - class Derived2 : Derived { } - - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, int i, Derived2 d) { } - } + Base b = new Base(); + var strlist = new string[1]; + Goo("", 1, i:1, d: [||]b); } - """; - - using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) + } + """; + var expected = + """ + class Program { - var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); - Assert.Equal(2, actions.Length); - } - - var expect_0 = - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } + class Derived2 : Derived { } - class Derived2 : Derived { } + void Goo(string s, int j, int i, Derived d) { } - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, int i, Derived2 d) { } - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); + void Goo(string s, int i, Derived2 d) { } - var expect_1 = - """ - class Program + void M() { - class Base { } - class Derived : Base { } - - class Derived2 : Derived { } - - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : (Derived2)b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, int i, Derived2 d) { } - } + Base b = new Base(); + var strlist = new string[1]; + Goo("", 1, i:1, d: (Derived)b); } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); - - } + } + """; + await TestInRegularAndScriptAsync(initialMarkup, expected); + } - [Fact] - public async Task MultipleOptions3() + [Fact] + public async Task MultipleOptions5() + { + var initialMarkup = + """ + class Program { - var initialMarkup = - """ - class Program - { - class Base { } - class Derived : Base { } + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, Derived d, int i, params object[] list)) { } - } - } - """; - var expected = - """ - class Program - { - class Base { } - class Derived : Base { } + void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(string s, Derived2 d, int i, object[] list) { } - class Derived2 : Derived { } - - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d : (Derived)b, s : s, i : i) { } - Test(string s, Derived d, int i) { } - Test(string s, Derived d, int i, params object[] list)) { } - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expected); + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: [||]b, list: strlist, i: 1); + } } - - [Fact] - public async Task MultipleOptions4() + """; + using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) { - var initialMarkup = - """ - class Program - { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } - - void Goo(string s, int j, int i, Derived d) { } - - void Goo(string s, int i, Derived2 d) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", 1, i:1, d: [||]b); - } - } - """; - var expected = - """ - class Program - { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } - - void Goo(string s, int j, int i, Derived d) { } - - void Goo(string s, int i, Derived2 d) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", 1, i:1, d: (Derived)b); - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expected); + var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); + Assert.Equal(2, actions.Length); } - [Fact] - public async Task MultipleOptions5() - { - var initialMarkup = + var expect_0 = """ class Program { @@ -2807,67 +2833,70 @@ void M() { Base b = new Base(); var strlist = new string[1]; - Goo("", d: [||]b, list: strlist, i: 1); + Goo("", d: (Derived)b, list: strlist, i: 1); } } """; - using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) - { - var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); - Assert.Equal(2, actions.Length); - } + await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); - var expect_0 = - """ - class Program - { - class Base { } - class Derived : Base { } + var expect_1 = + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } - void Goo(string s, Derived2 d, int i, object[] list) { } + void Goo(string s, Derived d, int i, params object[] list) { } + void Goo(string s, Derived2 d, int i, object[] list) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (Derived)b, list: strlist, i: 1); - } + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: (Derived2)b, list: strlist, i: 1); } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); + } + """; + await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); + } - var expect_1 = - """ - class Program - { - class Base { } - class Derived : Base { } + [Fact] + public async Task MultipleOptions6() + { + var initialMarkup = + """ + class Program + { + class Base { + static public explicit operator string(Base b) { return ""; } + } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(string s, Derived d, int i, params object[] list) { } - void Goo(string s, Derived2 d, int i, object[] list) { } + void Goo(string s, Derived d, int i) { } + void Goo(string s, Derived2 d, int i) { } + void Goo(string s, string d, int i) { } - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (Derived2)b, list: strlist, i: 1); - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo("", d: [||]b, i: 1); + } } - - [Fact] - public async Task MultipleOptions6() + """; + using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) { - var initialMarkup = + var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); + Assert.Equal(3, actions.Length); + } + + var expect_0 = """ class Program { @@ -2886,147 +2915,164 @@ void M() { Base b = new Base(); var strlist = new string[1]; - Goo("", d: [||]b, i: 1); + Goo("", d: (string)b, i: 1); } } """; - using (var workspace = CreateWorkspaceFromOptions(initialMarkup, new TestParameters())) - { - var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters()); - Assert.Equal(3, actions.Length); - } - - var expect_0 = - """ - class Program - { - class Base { - static public explicit operator string(Base b) { return ""; } - } - class Derived : Base { } - - class Derived2 : Derived { } - - void Goo(string s, Derived d, int i) { } - void Goo(string s, Derived2 d, int i) { } - void Goo(string s, string d, int i) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (string)b, i: 1); - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, - title: string.Format(CodeFixesResources.Convert_type_to_0, "string")); + await TestInRegularAndScriptAsync(initialMarkup, expect_0, index: 0, + title: string.Format(CodeFixesResources.Convert_type_to_0, "string")); - var expect_1 = - """ - class Program - { - class Base { - static public explicit operator string(Base b) { return ""; } - } - class Derived : Base { } - - class Derived2 : Derived { } - - void Goo(string s, Derived d, int i) { } - void Goo(string s, Derived2 d, int i) { } - void Goo(string s, string d, int i) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (Derived)b, i: 1); - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); - - var expect_2 = - """ - class Program - { - class Base { - static public explicit operator string(Base b) { return ""; } - } - class Derived : Base { } - - class Derived2 : Derived { } - - void Goo(string s, Derived d, int i) { } - void Goo(string s, Derived2 d, int i) { } - void Goo(string s, string d, int i) { } - - void M() - { - Base b = new Base(); - var strlist = new string[1]; - Goo("", d: (Derived2)b, i: 1); - } - } - """; - await TestInRegularAndScriptAsync(initialMarkup, expect_2, index: 2, - title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); - } - - [Fact] - public async Task MultipleOptions7() - { - var initialMarkup = + var expect_1 = """ class Program { - class Base { } + class Base { + static public explicit operator string(Base b) { return ""; } + } class Derived : Base { } class Derived2 : Derived { } - void Goo(string s1, int i, Derived d) { } - - void Goo(string s2, int i, Derived2 d) { } + void Goo(string s, Derived d, int i) { } + void Goo(string s, Derived2 d, int i) { } + void Goo(string s, string d, int i) { } void M() { Base b = new Base(); var strlist = new string[1]; - Goo(s1:"", 1, d: [||]b); + Goo("", d: (Derived)b, i: 1); } } """; - var expected = + await TestInRegularAndScriptAsync(initialMarkup, expect_1, index: 1, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived")); + + var expect_2 = """ class Program { - class Base { } + class Base { + static public explicit operator string(Base b) { return ""; } + } class Derived : Base { } class Derived2 : Derived { } - void Goo(string s1, int i, Derived d) { } - - void Goo(string s2, int i, Derived2 d) { } + void Goo(string s, Derived d, int i) { } + void Goo(string s, Derived2 d, int i) { } + void Goo(string s, string d, int i) { } void M() { Base b = new Base(); var strlist = new string[1]; - Goo(s1:"", 1, d: (Derived)b); + Goo("", d: (Derived2)b, i: 1); } } """; - await TestInRegularAndScriptAsync(initialMarkup, expected); + await TestInRegularAndScriptAsync(initialMarkup, expect_2, index: 2, + title: string.Format(CodeFixesResources.Convert_type_to_0, "Derived2")); + } + + [Fact] + public async Task MultipleOptions7() + { + var initialMarkup = + """ + class Program + { + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s1, int i, Derived d) { } + + void Goo(string s2, int i, Derived2 d) { } + + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo(s1:"", 1, d: [||]b); + } + } + """; + var expected = + """ + class Program + { + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Goo(string s1, int i, Derived d) { } + + void Goo(string s2, int i, Derived2 d) { } + + void M() + { + Base b = new Base(); + var strlist = new string[1]; + Goo(s1:"", 1, d: (Derived)b); + } } + """; + await TestInRegularAndScriptAsync(initialMarkup, expected); + } + + [Fact] + public async Task MultipleOptions8() + { + var initialMarkup = + """ + class Program + { + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } - [Fact] - public async Task MultipleOptions8() + void Foo4(Derived d, string a, string b, params string[] list) { } + void Foo4(Derived2 d, params string[] list) { } + + void M() + { + Base b = new Base(); + var strlist = new string[] { }; + Foo4([||]b, "1", "2", list: strlist); + } + } + """; + var expected = + """ + class Program { - var initialMarkup = + class Base { } + class Derived : Base { } + + class Derived2 : Derived { } + + void Foo4(Derived d, string a, string b, params string[] list) { } + void Foo4(Derived2 d, params string[] list) { } + + void M() + { + Base b = new Base(); + var strlist = new string[] { }; + Foo4((Derived)b, "1", "2", list: strlist); + } + } + """; + await TestInRegularAndScriptAsync(initialMarkup, expected); + } + + [Fact] + public async Task MultipleOptions9() + { + var initialMarkup = """ class Program { @@ -3035,18 +3081,21 @@ class Derived : Base { } class Derived2 : Derived { } - void Foo4(Derived d, string a, string b, params string[] list) { } - void Foo4(Derived2 d, params string[] list) { } + void Goo(Derived d1) { } + void Goo(Derived2 d2) { } - void M() - { - Base b = new Base(); - var strlist = new string[] { }; - Foo4([||]b, "1", "2", list: strlist); + void M() { + Goo([||]new Base()); } } """; - var expected = + await TestMissingInRegularAndScriptAsync(initialMarkup); + } + + [Fact] + public async Task MultipleErrors1() + { + await TestInRegularAndScriptAsync( """ class Program { @@ -3055,221 +3104,171 @@ class Derived : Base { } class Derived2 : Derived { } - void Foo4(Derived d, string a, string b, params string[] list) { } - void Foo4(Derived2 d, params string[] list) { } + void M(Derived2 d2) { } - void M() - { - Base b = new Base(); - var strlist = new string[] { }; - Foo4((Derived)b, "1", "2", list: strlist); + void Goo(Base b) { + Derived d; + M(d = [|b|]); } } - """; - await TestInRegularAndScriptAsync(initialMarkup, expected); - } - - [Fact] - public async Task MultipleOptions9() - { - var initialMarkup = - """ - class Program - { - class Base { } - class Derived : Base { } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void Goo(Derived d1) { } - void Goo(Derived2 d2) { } + void M(Derived2 d2) { } - void M() { - Goo([||]new Base()); - } + void Goo(Base b) { + Derived d; + M(d = (Derived)b); } - """; - await TestMissingInRegularAndScriptAsync(initialMarkup); - } + } + """); + } - [Fact] - public async Task MultipleErrors1() - { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } + [Fact] + public async Task MultipleErrors2() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void M(Derived2 d2) { } + void M(Derived2 d2) { } - void Goo(Base b) { - Derived d; - M(d = [|b|]); - } + void Goo(Base b) { + Derived d; + M([||]d = b); } - """, - """ - class Program - { - class Base { } - class Derived : Base { } + } + """, + """ + class Program + { + class Base { } + class Derived : Base { } - class Derived2 : Derived { } + class Derived2 : Derived { } - void M(Derived2 d2) { } + void M(Derived2 d2) { } - void Goo(Base b) { - Derived d; - M(d = (Derived)b); - } + void Goo(Base b) { + Derived d; + M((Derived2)(d = b)); } - """); - } - - [Fact] - public async Task MultipleErrors2() - { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived : Base { } - - class Derived2 : Derived { } - - void M(Derived2 d2) { } + } + """); + } - void Goo(Base b) { - Derived d; - M([||]d = b); - } + [Fact] + public async Task ErrorType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(C c) + { + TypeThatDoesntExist t = new TypeThatDoesntExist(); + M([||]t); } - """, - """ - class Program - { - class Base { } - class Derived : Base { } - - class Derived2 : Derived { } - - void M(Derived2 d2) { } + } + """); + } - void Goo(Base b) { - Derived d; - M((Derived2)(d = b)); - } - } - """); - } + [Fact] + public async Task AttributeArgument() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static object str = ""; - [Fact] - public async Task ErrorType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Obsolete([||]str, false)] + void M() { - void M(C c) - { - TypeThatDoesntExist t = new TypeThatDoesntExist(); - M([||]t); - } } - """); - } - - [Fact] - public async Task AttributeArgument() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C - { - static object str = ""; + } + """, + """ + using System; + class C + { + static object str = ""; - [Obsolete([||]str, false)] - void M() - { - } - } - """, - """ - using System; - class C + [Obsolete((string)str, false)] + void M() { - static object str = ""; - - [Obsolete((string)str, false)] - void M() - { - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50493")] - public async Task ArrayAccess() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50493")] + public async Task ArrayAccess() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public void M(object o) { - public void M(object o) - { - var array = new int[10]; + var array = new int[10]; - if (array[[||]o] > 0) {} - } + if (array[[||]o] > 0) {} } - """, - """ - class C + } + """, + """ + class C + { + public void M(object o) { - public void M(object o) - { - var array = new int[10]; + var array = new int[10]; - if (array[(int)o] > 0) {} - } + if (array[(int)o] > 0) {} } - """); - } + } + """); + } - [Fact] - public async Task RemoveExistingCast1() - { - await TestInRegularAndScriptAsync( - """ - class Program - { - class Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - void Goo() { - Base b; - Derived2 d = [||](Derived1)b; - } + [Fact] + public async Task RemoveExistingCast1() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + class Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + void Goo() { + Base b; + Derived2 d = [||](Derived1)b; } - """, - """ - class Program - { - class Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - void Goo() { - Base b; - Derived2 d = (Derived2)b; - } + } + """, + """ + class Program + { + class Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + void Goo() { + Base b; + Derived2 d = (Derived2)b; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests_FixAllTests.cs index 0fde7f0e6bb3f..69a8b925efe31 100644 --- a/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/AddExplicitCast/AddExplicitCastTests_FixAllTests.cs @@ -8,1749 +8,1748 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AddExplicitCast -{ - public partial class AddExplicitCastTests - { - #region "Fix all occurrences tests" - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task CS0266TestFixAllInDocument() - { - var input = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - - public class Program1 - { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - } - - Base ReturnBase() - { - Base b = new Base(); - return b; - } - - Base ReturnBase(Derived d) - { - Base b = new Base(); - return b; - } +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AddExplicitCast; - Derived ReturnDerived(Base b) - { - return b; - } +public partial class AddExplicitCastTests +{ + #region "Fix all occurrences tests" - ReturnDerived() ]]> - { - Base b; - yield return b; - } + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task CS0266TestFixAllInDocument() + { + var input = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + } - ReturnDerived() - { - Base b; - return b; - } ]]> + Base ReturnBase() + { + Base b = new Base(); + return b; + } - M() ]]> - { - Base b; - return b; - } + Base ReturnBase(Derived d) + { + Base b = new Base(); + return b; + } - Derived ReturnDerived2(Base b) - { - return ReturnBase(); - } + Derived ReturnDerived(Base b) + { + return b; + } - Derived Foo() - { - func = d => d; ]]> - Base b; - return func(b); - } - public Program1() - { - Base b; - Derived d = {|FixAllInDocument:b|}; - d = new Base() { }; + ReturnDerived() ]]> + { + Base b; + yield return b; + } - Derived d2 = ReturnBase(); - Derived d2 = ReturnBase(b); + ReturnDerived() + { + Base b; + return b; + } ]]> - Test t = new Test(); - t.D = b; - t.d = b; - d = t.B; + M() ]]> + { + Base b; + return b; + } - foo = d => d; ]]> + Derived ReturnDerived2(Base b) + { + return ReturnBase(); + } - foo2 = d => d; ]]> - d2 = foo2(d); - } + Derived Foo() + { + func = d => d; ]]> + Base b; + return func(b); } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = {|FixAllInDocument:b|}; + d = new Base() { }; - class Test - { - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + Derived d2 = ReturnBase(); + Derived d2 = ReturnBase(b); - Derived2 returnDerived2_1() { - return new Derived1(); - } + Test t = new Test(); + t.D = b; + t.d = b; + d = t.B; - Derived2 returnDerived2_2() { - return new Test(); - } + foo = d => d; ]]> - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Derived2 derived2 = b1; - derived2 = b3; - Base2 base2 = b1; - derived2 = d1; - Derived2 d2 = new Test(); - } + foo2 = d => d; ]]> + d2 = foo2(d); } - - - - - public class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - Derived2 returnD2(Base b) - { - Derived d; - return d = b; - } + Derived2 returnDerived2_1() { + return new Derived1(); } - - - - """; - var expected = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; + Derived2 returnDerived2_2() { + return new Test(); + } - public class Program1 + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - } - - Base ReturnBase() - { - Base b = new Base(); - return b; - } - - Base ReturnBase(Derived d) - { - Base b = new Base(); - return b; - } - - Derived ReturnDerived(Base b) - { - return (Derived)b; - } - - ReturnDerived() ]]> - { - Base b; - yield return (Derived)b; - } + Derived2 derived2 = b1; + derived2 = b3; + Base2 base2 = b1; + derived2 = d1; + Derived2 d2 = new Test(); + } + } + + + + + public class Program3 + { + class Base { } + class Derived : Base { } + class Derived2 : Derived { } + + Derived2 returnD2(Base b) + { + Derived d; + return d = b; + } + } + + + + """; + + var expected = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + } - ReturnDerived() - { - Base b; - return (IEnumerable)b; - } ]]> + Base ReturnBase() + { + Base b = new Base(); + return b; + } - M() ]]> - { - Base b; - return (Derived)b; - } + Base ReturnBase(Derived d) + { + Base b = new Base(); + return b; + } - Derived ReturnDerived2(Base b) - { - return (Derived)ReturnBase(); - } + Derived ReturnDerived(Base b) + { + return (Derived)b; + } - Derived Foo() - { - func = d => d; ]]> - Base b; - return (Derived)func(b); - } - public Program1() - { - Base b; - Derived d = (Derived)b; - d = new Base() { }; + ReturnDerived() ]]> + { + Base b; + yield return (Derived)b; + } - Derived d2 = (Derived)ReturnBase(); - Derived d2 = ReturnBase(b); + ReturnDerived() + { + Base b; + return (IEnumerable)b; + } ]]> - Test t = new Test(); - t.D = (Derived)b; - t.d = b; - d = (Derived)t.B; + M() ]]> + { + Base b; + return (Derived)b; + } - foo = d => (Derived)d; ]]> + Derived ReturnDerived2(Base b) + { + return (Derived)ReturnBase(); + } - foo2 = d => d; ]]> - d2 = (Derived)foo2(d); - } + Derived Foo() + { + func = d => d; ]]> + Base b; + return (Derived)func(b); } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = (Derived)b; + d = new Base() { }; - class Test - { - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + Derived d2 = (Derived)ReturnBase(); + Derived d2 = ReturnBase(b); - Derived2 returnDerived2_1() { - return new Derived1(); - } + Test t = new Test(); + t.D = (Derived)b; + t.d = b; + d = (Derived)t.B; - Derived2 returnDerived2_2() { - return new Test(); - } + foo = d => (Derived)d; ]]> - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Derived2 derived2 = b1; - derived2 = b3; - Base2 base2 = b1; - derived2 = d1; - Derived2 d2 = new Test(); - } + foo2 = d => d; ]]> + d2 = (Derived)foo2(d); } - - - - - public class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - Derived2 returnD2(Base b) - { - Derived d; - return d = b; - } + Derived2 returnDerived2_1() { + return new Derived1(); } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task CS0266TestFixAllInProject() - { - var input = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - - public class Program1 - { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + Derived2 returnDerived2_2() { + return new Test(); + } - Base ReturnBase(Derived d) - { - Base b = new Base(); - return b; - } + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Derived2 derived2 = b1; + derived2 = b3; + Base2 base2 = b1; + derived2 = d1; + Derived2 d2 = new Test(); + } + } + + + + + public class Program3 + { + class Base { } + class Derived : Base { } + class Derived2 : Derived { } + + Derived2 returnD2(Base b) + { + Derived d; + return d = b; + } + } + + + + """; - Derived ReturnDerived(Base b) - { - return b; - } + await TestInRegularAndScriptAsync(input, expected); + } - ReturnDerived() ]]> - { - Base b; - yield return b; - } + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task CS0266TestFixAllInProject() + { + var input = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + } - ReturnDerived() - { - Base b; - return b; - } ]]> + Base ReturnBase() + { + Base b = new Base(); + return b; + } - M() ]]> - { - Base b; - return b; - } + Base ReturnBase(Derived d) + { + Base b = new Base(); + return b; + } - Derived ReturnDerived2(Base b) - { - return ReturnBase(); - } + Derived ReturnDerived(Base b) + { + return b; + } - Derived Foo() - { - func = d => d; ]]> - Base b; - return func(b); - } - public Program1() - { - Base b; - Derived d = {|FixAllInProject:b|}; - d = new Base() { }; + ReturnDerived() ]]> + { + Base b; + yield return b; + } - Derived d2 = ReturnBase(); - Derived d2 = ReturnBase(b); + ReturnDerived() + { + Base b; + return b; + } ]]> - Test t = new Test(); - t.D = b; - t.d = b; - d = t.B; + M() ]]> + { + Base b; + return b; + } - foo = d => d; ]]> + Derived ReturnDerived2(Base b) + { + return ReturnBase(); + } - foo2 = d => d; ]]> - d2 = foo2(d); - } + Derived Foo() + { + func = d => d; ]]> + Base b; + return func(b); } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = {|FixAllInProject:b|}; + d = new Base() { }; - class Test - { - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + Derived d2 = ReturnBase(); + Derived d2 = ReturnBase(b); - Derived2 returnDerived2_1() { - return new Derived1(); - } + Test t = new Test(); + t.D = b; + t.d = b; + d = t.B; - Derived2 returnDerived2_2() { - return new Test(); - } + foo = d => d; ]]> - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Derived2 derived2 = b1; - derived2 = b3; - Base2 base2 = b1; - derived2 = d1; - Derived2 d2 = new Test(); - } + foo2 = d => d; ]]> + d2 = foo2(d); } - - - - - public class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - Derived2 returnD2(Base b) - { - Derived d; - return d = b; - } + Derived2 returnDerived2_1() { + return new Derived1(); } - - - - """; - var expected = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; + Derived2 returnDerived2_2() { + return new Test(); + } - public class Program1 + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - } - - Base ReturnBase() - { - Base b = new Base(); - return b; - } - - Base ReturnBase(Derived d) - { - Base b = new Base(); - return b; - } - - Derived ReturnDerived(Base b) - { - return (Derived)b; - } - - ReturnDerived() ]]> - { - Base b; - yield return (Derived)b; - } + Derived2 derived2 = b1; + derived2 = b3; + Base2 base2 = b1; + derived2 = d1; + Derived2 d2 = new Test(); + } + } + + + + + public class Program3 + { + class Base { } + class Derived : Base { } + class Derived2 : Derived { } + + Derived2 returnD2(Base b) + { + Derived d; + return d = b; + } + } + + + + """; + + var expected = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + } - ReturnDerived() - { - Base b; - return (IEnumerable)b; - } ]]> + Base ReturnBase() + { + Base b = new Base(); + return b; + } - M() ]]> - { - Base b; - return (Derived)b; - } + Base ReturnBase(Derived d) + { + Base b = new Base(); + return b; + } - Derived ReturnDerived2(Base b) - { - return (Derived)ReturnBase(); - } + Derived ReturnDerived(Base b) + { + return (Derived)b; + } - Derived Foo() - { - func = d => d; ]]> - Base b; - return (Derived)func(b); - } - public Program1() - { - Base b; - Derived d = (Derived)b; - d = new Base() { }; + ReturnDerived() ]]> + { + Base b; + yield return (Derived)b; + } - Derived d2 = (Derived)ReturnBase(); - Derived d2 = ReturnBase(b); + ReturnDerived() + { + Base b; + return (IEnumerable)b; + } ]]> - Test t = new Test(); - t.D = (Derived)b; - t.d = b; - d = (Derived)t.B; + M() ]]> + { + Base b; + return (Derived)b; + } - foo = d => (Derived)d; ]]> + Derived ReturnDerived2(Base b) + { + return (Derived)ReturnBase(); + } - foo2 = d => d; ]]> - d2 = (Derived)foo2(d); - } + Derived Foo() + { + func = d => d; ]]> + Base b; + return (Derived)func(b); } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = (Derived)b; + d = new Base() { }; - class Test - { - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + Derived d2 = (Derived)ReturnBase(); + Derived d2 = ReturnBase(b); - Derived2 returnDerived2_1() { - return new Derived1(); - } + Test t = new Test(); + t.D = (Derived)b; + t.d = b; + d = (Derived)t.B; - Derived2 returnDerived2_2() { - return (Derived2)new Test(); - } + foo = d => (Derived)d; ]]> - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Derived2 derived2 = (Derived2)b1; - derived2 = (Derived2)b3; - Base2 base2 = (Base2)b1; - derived2 = (Derived2)d1; - Derived2 d2 = (Derived2)new Test(); - } + foo2 = d => d; ]]> + d2 = (Derived)foo2(d); } - - - - - public class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - Derived2 returnD2(Base b) - { - Derived d; - return d = b; - } + Derived2 returnDerived2_1() { + return new Derived1(); } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task CS0266TestFixAllInSolution() - { - var input = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - - public class Program1 - { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + Derived2 returnDerived2_2() { + return (Derived2)new Test(); + } - Base ReturnBase(Derived d) - { - Base b = new Base(); - return b; - } + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Derived2 derived2 = (Derived2)b1; + derived2 = (Derived2)b3; + Base2 base2 = (Base2)b1; + derived2 = (Derived2)d1; + Derived2 d2 = (Derived2)new Test(); + } + } + + + + + public class Program3 + { + class Base { } + class Derived : Base { } + class Derived2 : Derived { } + + Derived2 returnD2(Base b) + { + Derived d; + return d = b; + } + } + + + + """; - Derived ReturnDerived(Base b) - { - return b; - } + await TestInRegularAndScriptAsync(input, expected); + } - ReturnDerived() ]]> - { - Base b; - yield return b; - } + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task CS0266TestFixAllInSolution() + { + var input = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + } - ReturnDerived() - { - Base b; - return b; - } ]]> + Base ReturnBase() + { + Base b = new Base(); + return b; + } - M() ]]> - { - Base b; - return b; - } + Base ReturnBase(Derived d) + { + Base b = new Base(); + return b; + } - Derived ReturnDerived2(Base b) - { - return ReturnBase(); - } + Derived ReturnDerived(Base b) + { + return b; + } - Derived Foo() - { - func = d => d; ]]> - Base b; - return func(b); - } - public Program1() - { - Base b; - Derived d = {|FixAllInSolution:b|}; - d = new Base() { }; + ReturnDerived() ]]> + { + Base b; + yield return b; + } - Derived d2 = ReturnBase(); - Derived d2 = ReturnBase(b); + ReturnDerived() + { + Base b; + return b; + } ]]> - Test t = new Test(); - t.D = b; - t.d = b; - d = t.B; + M() ]]> + { + Base b; + return b; + } - foo = d => d; ]]> + Derived ReturnDerived2(Base b) + { + return ReturnBase(); + } - foo2 = d => d; ]]> - d2 = foo2(d); - } + Derived Foo() + { + func = d => d; ]]> + Base b; + return func(b); } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = {|FixAllInSolution:b|}; + d = new Base() { }; - class Test - { - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + Derived d2 = ReturnBase(); + Derived d2 = ReturnBase(b); - Derived2 returnDerived2_1() { - return new Derived1(); - } + Test t = new Test(); + t.D = b; + t.d = b; + d = t.B; - Derived2 returnDerived2_2() { - return new Test(); - } + foo = d => d; ]]> - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Derived2 derived2 = b1; - derived2 = b3; - Base2 base2 = b1; - derived2 = d1; - Derived2 d2 = new Test(); - } + foo2 = d => d; ]]> + d2 = foo2(d); } - - - - - public class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - Derived2 returnD2(Base b) - { - Derived d; - return d = b; - } + Derived2 returnDerived2_1() { + return new Derived1(); } - - - - """; - var expected = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; + Derived2 returnDerived2_2() { + return new Test(); + } - public class Program1 + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - } - - Base ReturnBase() - { - Base b = new Base(); - return b; - } - - Base ReturnBase(Derived d) - { - Base b = new Base(); - return b; - } - - Derived ReturnDerived(Base b) - { - return (Derived)b; - } - - ReturnDerived() ]]> - { - Base b; - yield return (Derived)b; - } + Derived2 derived2 = b1; + derived2 = b3; + Base2 base2 = b1; + derived2 = d1; + Derived2 d2 = new Test(); + } + } + + + + + public class Program3 + { + class Base { } + class Derived : Base { } + class Derived2 : Derived { } + + Derived2 returnD2(Base b) + { + Derived d; + return d = b; + } + } + + + + """; + + var expected = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + } - ReturnDerived() - { - Base b; - return (IEnumerable)b; - } ]]> + Base ReturnBase() + { + Base b = new Base(); + return b; + } - M() ]]> - { - Base b; - return (Derived)b; - } + Base ReturnBase(Derived d) + { + Base b = new Base(); + return b; + } - Derived ReturnDerived2(Base b) - { - return (Derived)ReturnBase(); - } + Derived ReturnDerived(Base b) + { + return (Derived)b; + } - Derived Foo() - { - func = d => d; ]]> - Base b; - return (Derived)func(b); - } - public Program1() - { - Base b; - Derived d = (Derived)b; - d = new Base() { }; + ReturnDerived() ]]> + { + Base b; + yield return (Derived)b; + } - Derived d2 = (Derived)ReturnBase(); - Derived d2 = ReturnBase(b); + ReturnDerived() + { + Base b; + return (IEnumerable)b; + } ]]> - Test t = new Test(); - t.D = (Derived)b; - t.d = b; - d = (Derived)t.B; + M() ]]> + { + Base b; + return (Derived)b; + } - foo = d => (Derived)d; ]]> + Derived ReturnDerived2(Base b) + { + return (Derived)ReturnBase(); + } - foo2 = d => d; ]]> - d2 = (Derived)foo2(d); - } + Derived Foo() + { + func = d => d; ]]> + Base b; + return (Derived)func(b); } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = (Derived)b; + d = new Base() { }; - class Test - { - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + Derived d2 = (Derived)ReturnBase(); + Derived d2 = ReturnBase(b); - Derived2 returnDerived2_1() { - return new Derived1(); - } + Test t = new Test(); + t.D = (Derived)b; + t.d = b; + d = (Derived)t.B; - Derived2 returnDerived2_2() { - return (Derived2)new Test(); - } + foo = d => (Derived)d; ]]> - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Derived2 derived2 = (Derived2)b1; - derived2 = (Derived2)b3; - Base2 base2 = (Base2)b1; - derived2 = (Derived2)d1; - Derived2 d2 = (Derived2)new Test(); - } + foo2 = d => d; ]]> + d2 = (Derived)foo2(d); } - - - - - public class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - class Base { } - class Derived : Base { } - class Derived2 : Derived { } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - Derived2 returnD2(Base b) - { - Derived d; - return (Derived2)(d = (Derived)b); - } + Derived2 returnDerived2_1() { + return new Derived1(); } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task CS1503TestFixAllInDocument() - { - var input = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - public class Program1 - { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Test(Derived derived) - { - d = derived; - B = derived; - } - - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - - public void testing(Derived d) { } - private void testing(Base b) { } - } - class Test2 : Test - { - public Test2(Base b) : base(b) { } - } + Derived2 returnDerived2_2() { + return (Derived2)new Test(); + } - class Test3 - { - public Test3(Derived b) { } - public Test3(int i, Base b) : this(b) { } + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Derived2 derived2 = (Derived2)b1; + derived2 = (Derived2)b3; + Base2 base2 = (Base2)b1; + derived2 = (Derived2)d1; + Derived2 d2 = (Derived2)new Test(); + } + } + + + + + public class Program3 + { + class Base { } + class Derived : Base { } + class Derived2 : Derived { } + + Derived2 returnD2(Base b) + { + Derived d; + return (Derived2)(d = (Derived)b); + } + } + + + + """; - public void testing(int i, Derived d) { } - private void testing(int i, Base d) { } - } + await TestInRegularAndScriptAsync(input, expected); + } - Base ReturnBase() + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task CS1503TestFixAllInDocument() + { + var input = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Test(Derived derived) { - Base b = new Base(); - return b; + d = derived; + B = derived; } - void PassDerived(Derived d) { } - void PassDerived(int i, Derived d) { } - - public Program1() - { - Base b; - Derived d = b; + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } - PassDerived({|FixAllInDocument:b|}); - PassDerived(ReturnBase()); - PassDerived(1, b); - PassDerived(1, ReturnBase()); + public void testing(Derived d) { } + private void testing(Base b) { } + } - list = new List(); ]]> - list.Add(b); + class Test2 : Test + { + public Test2(Base b) : base(b) { } + } - Test t = new Test(); - t.testing(b); + class Test3 + { + public Test3(Derived b) { } + public Test3(int i, Base b) : this(b) { } - foo2 = d => d; ]]> - Derived d2 = foo2(b); - d2 = foo2(d); - } + public void testing(int i, Derived d) { } + private void testing(int i, Base d) { } } - - - public class Program2 - { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + Base ReturnBase() + { + Base b = new Base(); + return b; + } - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + void PassDerived(Derived d) { } + void PassDerived(int i, Derived d) { } - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); - } - } - - - - - class Program3 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = b; - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + PassDerived({|FixAllInDocument:b|}); + PassDerived(ReturnBase()); + PassDerived(1, b); + PassDerived(1, ReturnBase()); - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + list = new List(); ]]> + list.Add(b); - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); - } - } - - - - """; + Test t = new Test(); + t.testing(b); - var expected = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - public class Program1 + foo2 = d => d; ]]> + Derived d2 = foo2(b); + d2 = foo2(d); + } + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Test(Derived derived) - { - d = derived; - B = derived; - } - - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - - public void testing(Derived d) { } - private void testing(Base b) { } - } - - class Test2 : Test + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); + } + } + + + + + class Program3 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); + } + } + + + + """; + + var expected = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Test(Derived derived) { - public Test2(Base b) : base((Derived)b) { } + d = derived; + B = derived; } - class Test3 - { - public Test3(Derived b) { } - public Test3(int i, Base b) : this((Derived)b) { } - - public void testing(int i, Derived d) { } - private void testing(int i, Base d) { } - } + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + public void testing(Derived d) { } + private void testing(Base b) { } + } - void PassDerived(Derived d) { } - void PassDerived(int i, Derived d) { } + class Test2 : Test + { + public Test2(Base b) : base((Derived)b) { } + } - public Program1() - { - Base b; - Derived d = b; + class Test3 + { + public Test3(Derived b) { } + public Test3(int i, Base b) : this((Derived)b) { } - PassDerived((Derived)b); - PassDerived((Derived)ReturnBase()); - PassDerived(1, (Derived)b); - PassDerived(1, (Derived)ReturnBase()); + public void testing(int i, Derived d) { } + private void testing(int i, Base d) { } + } - list = new List(); ]]> - list.Add((Derived)b); + Base ReturnBase() + { + Base b = new Base(); + return b; + } - Test t = new Test(); - t.testing((Derived)b); + void PassDerived(Derived d) { } + void PassDerived(int i, Derived d) { } - foo2 = d => d; ]]> - Derived d2 = foo2((Derived)b); - d2 = foo2(d); - } - } - - - public class Program2 + public Program1() { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + Base b; + Derived d = b; - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + PassDerived((Derived)b); + PassDerived((Derived)ReturnBase()); + PassDerived(1, (Derived)b); + PassDerived(1, (Derived)ReturnBase()); - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + list = new List(); ]]> + list.Add((Derived)b); - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); - } + Test t = new Test(); + t.testing((Derived)b); + + foo2 = d => d; ]]> + Derived d2 = foo2((Derived)b); + d2 = foo2(d); } - - - - - class Program3 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); + } + } + + + + + class Program3 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); + } + } + + + + """; - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + await TestInRegularAndScriptAsync(input, expected); + } - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task CS1503TestFixAllInProject() + { + var input = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Test(Derived derived) { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); + d = derived; + B = derived; } + + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + + public void testing(Derived d) { } + private void testing(Base b) { } } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task CS1503TestFixAllInProject() - { - var input = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - public class Program1 - { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Test(Derived derived) - { - d = derived; - B = derived; - } - - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - - public void testing(Derived d) { } - private void testing(Base b) { } - } - class Test2 : Test - { - public Test2(Base b) : base(b) { } - } + class Test2 : Test + { + public Test2(Base b) : base(b) { } + } - class Test3 - { - public Test3(Derived b) { } - public Test3(int i, Base b) : this(b) { } + class Test3 + { + public Test3(Derived b) { } + public Test3(int i, Base b) : this(b) { } - public void testing(int i, Derived d) { } - private void testing(int i, Base d) { } - } + public void testing(int i, Derived d) { } + private void testing(int i, Base d) { } + } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + Base ReturnBase() + { + Base b = new Base(); + return b; + } - void PassDerived(Derived d) { } - void PassDerived(int i, Derived d) { } + void PassDerived(Derived d) { } + void PassDerived(int i, Derived d) { } - public Program1() - { - Base b; - Derived d = b; + public Program1() + { + Base b; + Derived d = b; - PassDerived({|FixAllInProject:b|}); - PassDerived(ReturnBase()); - PassDerived(1, b); - PassDerived(1, ReturnBase()); + PassDerived({|FixAllInProject:b|}); + PassDerived(ReturnBase()); + PassDerived(1, b); + PassDerived(1, ReturnBase()); - list = new List(); ]]> - list.Add(b); + list = new List(); ]]> + list.Add(b); - Test t = new Test(); - t.testing(b); + Test t = new Test(); + t.testing(b); - foo2 = d => d; ]]> - Derived d2 = foo2(b); - d2 = foo2(d); - } + foo2 = d => d; ]]> + Derived d2 = foo2(b); + d2 = foo2(d); } - - - public class Program2 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - - class Test - { - static public explicit operator Derived1(Test t) { return new Derived1(); } - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + static public explicit operator Derived1(Test t) { return new Derived1(); } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + void Foo3(Derived2 b1) { } + void Foo3(int i) { } - void Foo4(int i, string j, Derived1 d) { } - void Foo4(string j, int i, Derived1 d) { } + void Foo4(int i, string j, Derived1 d) { } + void Foo4(string j, int i, Derived1 d) { } - void Foo5(string j, int i, Derived2 d, int x = 1) { } + void Foo5(string j, int i, Derived2 d, int x = 1) { } - void Foo5(string j, int i, Derived1 d, params Derived2[] d2list) { } + void Foo5(string j, int i, Derived1 d, params Derived2[] d2list) { } - void Foo6(Derived1 d, params Derived2[] d2list) { } + void Foo6(Derived1 d, params Derived2[] d2list) { } - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1(b1); - Foo1(d1); + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Foo1(b1); + Foo1(d1); - Foo2(b1); + Foo2(b1); - Foo3(b1); + Foo3(b1); - Foo4(1, "", b1); - Foo4(i: 1, j: "", b1); // one operation, fix + Foo4(1, "", b1); + Foo4(i: 1, j: "", b1); // one operation, fix - Foo5("", 1, b1); // multiple operations, no fix-all + Foo5("", 1, b1); // multiple operations, no fix-all - Foo5(d: b1, i: 1, j: "", x: 1); // all arguments out of order - match - Foo5(1, "", x: 1, d: b1); // part of arguments out of order - mismatch + Foo5(d: b1, i: 1, j: "", x: 1); // all arguments out of order - match + Foo5(1, "", x: 1, d: b1); // part of arguments out of order - mismatch - Foo5(1, "", d: b1, b2, b3, d1); // part of arguments out of order - mismatch - Foo5("", 1, d: b1, b2, b3, d1); // part of arguments out of order - match + Foo5(1, "", d: b1, b2, b3, d1); // part of arguments out of order - mismatch + Foo5("", 1, d: b1, b2, b3, d1); // part of arguments out of order - match - var d2list = new Derived2[] { }; - Foo5(d2list: d2list, j: "", i: 1, d: b2); - var d1list = new Derived1[] { }; - Foo5(d2list: d1list, j: "", i: 1, d: b2); + var d2list = new Derived2[] { }; + Foo5(d2list: d2list, j: "", i: 1, d: b2); + var d1list = new Derived1[] { }; + Foo5(d2list: d1list, j: "", i: 1, d: b2); - Foo6(b1); + Foo6(b1); - Foo6(new Test()); // params is optional, object creation can be cast with explicit cast operator - Foo6(new Test(), new Derived1()); // object creation cannot be cast without explicit cast operator - Foo6(new Derived1(), new Test()); - } + Foo6(new Test()); // params is optional, object creation can be cast with explicit cast operator + Foo6(new Test(), new Derived1()); // object creation cannot be cast without explicit cast operator + Foo6(new Derived1(), new Test()); } - - - - - class Program3 + } + + + + + class Program3 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } - - void Foo3(Derived2 b1) { } - void Foo3(int i) { } - - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); - } + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); } - - - - """; - - var expected = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - public class Program1 + } + + + + """; + + var expected = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test { - class Base { } - class Derived : Base { } - - class Test + private Derived d; + private Base b; + public Test(Derived derived) { - private Derived d; - private Base b; - public Test(Derived derived) - { - d = derived; - B = derived; - } - - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - - public void testing(Derived d) { } - private void testing(Base b) { } + d = derived; + B = derived; } - class Test2 : Test - { - public Test2(Base b) : base((Derived)b) { } - } + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } - class Test3 - { - public Test3(Derived b) { } - public Test3(int i, Base b) : this((Derived)b) { } + public void testing(Derived d) { } + private void testing(Base b) { } + } - public void testing(int i, Derived d) { } - private void testing(int i, Base d) { } - } + class Test2 : Test + { + public Test2(Base b) : base((Derived)b) { } + } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + class Test3 + { + public Test3(Derived b) { } + public Test3(int i, Base b) : this((Derived)b) { } - void PassDerived(Derived d) { } - void PassDerived(int i, Derived d) { } + public void testing(int i, Derived d) { } + private void testing(int i, Base d) { } + } - public Program1() - { - Base b; - Derived d = b; + Base ReturnBase() + { + Base b = new Base(); + return b; + } - PassDerived((Derived)b); - PassDerived((Derived)ReturnBase()); - PassDerived(1, (Derived)b); - PassDerived(1, (Derived)ReturnBase()); + void PassDerived(Derived d) { } + void PassDerived(int i, Derived d) { } - list = new List(); ]]> - list.Add((Derived)b); + public Program1() + { + Base b; + Derived d = b; - Test t = new Test(); - t.testing((Derived)b); + PassDerived((Derived)b); + PassDerived((Derived)ReturnBase()); + PassDerived(1, (Derived)b); + PassDerived(1, (Derived)ReturnBase()); - foo2 = d => d; ]]> - Derived d2 = foo2((Derived)b); - d2 = foo2(d); - } + list = new List(); ]]> + list.Add((Derived)b); + + Test t = new Test(); + t.testing((Derived)b); + + foo2 = d => d; ]]> + Derived d2 = foo2((Derived)b); + d2 = foo2(d); } - - - public class Program2 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + class Test { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - - class Test - { - static public explicit operator Derived1(Test t) { return new Derived1(); } - static public explicit operator Derived2(Test t) { return new Derived2(); } - } + static public explicit operator Derived1(Test t) { return new Derived1(); } + static public explicit operator Derived2(Test t) { return new Derived2(); } + } - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + void Foo3(Derived2 b1) { } + void Foo3(int i) { } - void Foo4(int i, string j, Derived1 d) { } - void Foo4(string j, int i, Derived1 d) { } + void Foo4(int i, string j, Derived1 d) { } + void Foo4(string j, int i, Derived1 d) { } - void Foo5(string j, int i, Derived2 d, int x = 1) { } + void Foo5(string j, int i, Derived2 d, int x = 1) { } - void Foo5(string j, int i, Derived1 d, params Derived2[] d2list) { } + void Foo5(string j, int i, Derived1 d, params Derived2[] d2list) { } - void Foo6(Derived1 d, params Derived2[] d2list) { } + void Foo6(Derived1 d, params Derived2[] d2list) { } - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1((Derived2)b1); - Foo1((Derived2)d1); + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Foo1((Derived2)b1); + Foo1((Derived2)d1); - Foo2((Base2)b1); + Foo2((Base2)b1); - Foo3((Derived2)b1); + Foo3((Derived2)b1); - Foo4(1, "", (Derived1)b1); - Foo4(i: 1, j: "", (Derived1)b1); // one operation, fix + Foo4(1, "", (Derived1)b1); + Foo4(i: 1, j: "", (Derived1)b1); // one operation, fix - Foo5("", 1, b1); // multiple operations, no fix-all + Foo5("", 1, b1); // multiple operations, no fix-all - Foo5(d: (Derived2)b1, i: 1, j: "", x: 1); // all arguments out of order - match - Foo5(1, "", x: 1, d: b1); // part of arguments out of order - mismatch + Foo5(d: (Derived2)b1, i: 1, j: "", x: 1); // all arguments out of order - match + Foo5(1, "", x: 1, d: b1); // part of arguments out of order - mismatch - Foo5(1, "", d: b1, b2, b3, d1); // part of arguments out of order - mismatch - Foo5("", 1, d: (Derived1)b1, (Derived2)b2, (Derived2)b3, (Derived2)d1); // part of arguments out of order - match + Foo5(1, "", d: b1, b2, b3, d1); // part of arguments out of order - mismatch + Foo5("", 1, d: (Derived1)b1, (Derived2)b2, (Derived2)b3, (Derived2)d1); // part of arguments out of order - match - var d2list = new Derived2[] { }; - Foo5(d2list: d2list, j: "", i: 1, d: (Derived1)b2); - var d1list = new Derived1[] { }; - Foo5(d2list: (Derived2[])d1list, j: "", i: 1, d: (Derived1)b2); + var d2list = new Derived2[] { }; + Foo5(d2list: d2list, j: "", i: 1, d: (Derived1)b2); + var d1list = new Derived1[] { }; + Foo5(d2list: (Derived2[])d1list, j: "", i: 1, d: (Derived1)b2); - Foo6((Derived1)b1); + Foo6((Derived1)b1); - Foo6((Derived1)new Test()); // params is optional, object creation can be cast with explicit cast operator - Foo6((Derived1)new Test(), new Derived1()); // object creation cannot be cast without explicit cast operator - Foo6(new Derived1(), (Derived2)new Test()); - } + Foo6((Derived1)new Test()); // params is optional, object creation can be cast with explicit cast operator + Foo6((Derived1)new Test(), new Derived1()); // object creation cannot be cast without explicit cast operator + Foo6(new Derived1(), (Derived2)new Test()); } - - - - - class Program3 + } + + + + + class Program3 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); + } + } + + + + """; - void Foo3(Derived2 b1) { } - void Foo3(int i) { } + await TestInRegularAndScriptAsync(input, expected); + } - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task CS1503TestFixAllInSolution() + { + var input = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test + { + private Derived d; + private Base b; + public Test(Derived derived) { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); + d = derived; + B = derived; } + + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } + + public void testing(Derived d) { } + private void testing(Base b) { } } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsAddExplicitCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task CS1503TestFixAllInSolution() - { - var input = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - public class Program1 - { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Test(Derived derived) - { - d = derived; - B = derived; - } - - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - - public void testing(Derived d) { } - private void testing(Base b) { } - } - class Test2 : Test - { - public Test2(Base b) : base(b) { } - } + class Test2 : Test + { + public Test2(Base b) : base(b) { } + } - class Test3 - { - public Test3(Derived b) { } - public Test3(int i, Base b) : this(b) { } + class Test3 + { + public Test3(Derived b) { } + public Test3(int i, Base b) : this(b) { } - public void testing(int i, Derived d) { } - private void testing(int i, Base d) { } - } + public void testing(int i, Derived d) { } + private void testing(int i, Base d) { } + } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + Base ReturnBase() + { + Base b = new Base(); + return b; + } - void PassDerived(Derived d) { } - void PassDerived(int i, Derived d) { } + void PassDerived(Derived d) { } + void PassDerived(int i, Derived d) { } - public Program1() - { - Base b; - Derived d = b; + public Program1() + { + Base b; + Derived d = b; - PassDerived({|FixAllInSolution:b|}); - PassDerived(ReturnBase()); - PassDerived(1, b); - PassDerived(1, ReturnBase()); + PassDerived({|FixAllInSolution:b|}); + PassDerived(ReturnBase()); + PassDerived(1, b); + PassDerived(1, ReturnBase()); - list = new List(); ]]> - list.Add(b); + list = new List(); ]]> + list.Add(b); - Test t = new Test(); - t.testing(b); + Test t = new Test(); + t.testing(b); - foo2 = d => d; ]]> - Derived d2 = foo2(b); - d2 = foo2(d); - } + foo2 = d => d; ]]> + Derived d2 = foo2(b); + d2 = foo2(d); + } + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) + { + Foo1(b1); + Foo1(d1); + Foo2(b1); + Foo3(b1); } - - - public class Program2 + } + + + + + class Program3 + { + interface Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + + class Test { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } + public Test(string s, Base b, int i, params object[] list) : this(d: b, s: s, i: i) { } // 2 operations, no fix in fix-all + Test(string s, Derived1 d, int i) { } + Test(string s, Derived2 d, int i) { } + } - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } + void Foo(Derived1 d, int a, int b, params int[] list) { } + void Foo(Derived2 d, params int[] list) { } - void Foo3(Derived2 b1) { } - void Foo3(int i) { } - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1(b1); - Foo1(d1); - Foo2(b1); - Foo3(b1); - } + private void M2(Base b, Derived1 d1, Derived2 d2) + { + Foo(b, 1, 2); // 2 operations, no fix in fix-all + var intlist = new int[] { }; + Foo(b, 1, 2, list: intlist); // 2 operations } - - - - - class Program3 + } + + + + """; + + var expected = """ + + + + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class Program1 + { + class Base { } + class Derived : Base { } + + class Test { - interface Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - - class Test + private Derived d; + private Base b; + public Test(Derived derived) { - public Test(string s, Base b, int i, params object[] list) : this(d: b, s: s, i: i) { } // 2 operations, no fix in fix-all - Test(string s, Derived1 d, int i) { } - Test(string s, Derived2 d, int i) { } + d = derived; + B = derived; } - void Foo(Derived1 d, int a, int b, params int[] list) { } - void Foo(Derived2 d, params int[] list) { } - + public Derived D { get => d; set => d = value; } + public Base B { get => b; set => b = value; } - private void M2(Base b, Derived1 d1, Derived2 d2) - { - Foo(b, 1, 2); // 2 operations, no fix in fix-all - var intlist = new int[] { }; - Foo(b, 1, 2, list: intlist); // 2 operations - } + public void testing(Derived d) { } + private void testing(Base b) { } } - - - - """; - var expected = """ - - - - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - public class Program1 + class Test2 : Test { - class Base { } - class Derived : Base { } - - class Test - { - private Derived d; - private Base b; - public Test(Derived derived) - { - d = derived; - B = derived; - } - - public Derived D { get => d; set => d = value; } - public Base B { get => b; set => b = value; } - - public void testing(Derived d) { } - private void testing(Base b) { } - } - - class Test2 : Test - { - public Test2(Base b) : base((Derived)b) { } - } + public Test2(Base b) : base((Derived)b) { } + } - class Test3 - { - public Test3(Derived b) { } - public Test3(int i, Base b) : this((Derived)b) { } + class Test3 + { + public Test3(Derived b) { } + public Test3(int i, Base b) : this((Derived)b) { } - public void testing(int i, Derived d) { } - private void testing(int i, Base d) { } - } + public void testing(int i, Derived d) { } + private void testing(int i, Base d) { } + } - Base ReturnBase() - { - Base b = new Base(); - return b; - } + Base ReturnBase() + { + Base b = new Base(); + return b; + } - void PassDerived(Derived d) { } - void PassDerived(int i, Derived d) { } + void PassDerived(Derived d) { } + void PassDerived(int i, Derived d) { } - public Program1() - { - Base b; - Derived d = b; + public Program1() + { + Base b; + Derived d = b; - PassDerived((Derived)b); - PassDerived((Derived)ReturnBase()); - PassDerived(1, (Derived)b); - PassDerived(1, (Derived)ReturnBase()); + PassDerived((Derived)b); + PassDerived((Derived)ReturnBase()); + PassDerived(1, (Derived)b); + PassDerived(1, (Derived)ReturnBase()); - list = new List(); ]]> - list.Add((Derived)b); + list = new List(); ]]> + list.Add((Derived)b); - Test t = new Test(); - t.testing((Derived)b); + Test t = new Test(); + t.testing((Derived)b); - foo2 = d => d; ]]> - Derived d2 = foo2((Derived)b); - d2 = foo2(d); - } + foo2 = d => d; ]]> + Derived d2 = foo2((Derived)b); + d2 = foo2(d); } - - - public class Program2 + } + + + public class Program2 + { + interface Base1 { } + interface Base2 : Base1 { } + interface Base3 { } + class Derived1 : Base2, Base3 { } + class Derived2 : Derived1 { } + + void Foo1(Derived2 b) { } + void Foo2(Base2 b) { } + + void Foo3(Derived2 b1) { } + void Foo3(int i) { } + + private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) { - interface Base1 { } - interface Base2 : Base1 { } - interface Base3 { } - class Derived1 : Base2, Base3 { } - class Derived2 : Derived1 { } - - void Foo1(Derived2 b) { } - void Foo2(Base2 b) { } - - void Foo3(Derived2 b1) { } - void Foo3(int i) { } - - private void M2(Base1 b1, Base2 b2, Base3 b3, Derived1 d1, Derived2 d2) - { - Foo1((Derived2)b1); - Foo1((Derived2)d1); - Foo2((Base2)b1); - Foo3((Derived2)b1); - } + Foo1((Derived2)b1); + Foo1((Derived2)d1); + Foo2((Base2)b1); + Foo3((Derived2)b1); } - - - - - class Program3 + } + + + + + class Program3 + { + interface Base { } + class Derived1 : Base { } + class Derived2 : Derived1 { } + + class Test { - interface Base { } - class Derived1 : Base { } - class Derived2 : Derived1 { } - - class Test - { - public Test(string s, Base b, int i, params object[] list) : this(d: b, s: s, i: i) { } // 2 operations, no fix in fix-all - Test(string s, Derived1 d, int i) { } - Test(string s, Derived2 d, int i) { } - } + public Test(string s, Base b, int i, params object[] list) : this(d: b, s: s, i: i) { } // 2 operations, no fix in fix-all + Test(string s, Derived1 d, int i) { } + Test(string s, Derived2 d, int i) { } + } - void Foo(Derived1 d, int a, int b, params int[] list) { } - void Foo(Derived2 d, params int[] list) { } + void Foo(Derived1 d, int a, int b, params int[] list) { } + void Foo(Derived2 d, params int[] list) { } - private void M2(Base b, Derived1 d1, Derived2 d2) - { - Foo(b, 1, 2); // 2 operations, no fix in fix-all - var intlist = new int[] { }; - Foo(b, 1, 2, list: intlist); // 2 operations - } + private void M2(Base b, Derived1 d1, Derived2 d2) + { + Foo(b, 1, 2); // 2 operations, no fix in fix-all + var intlist = new int[] { }; + Foo(b, 1, 2, list: intlist); // 2 operations } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } - #endregion + await TestInRegularAndScriptAsync(input, expected); } + #endregion } diff --git a/src/Analyzers/CSharp/Tests/AddInheritdoc/AddInheritdocTests.cs b/src/Analyzers/CSharp/Tests/AddInheritdoc/AddInheritdocTests.cs index 5c9f8ed81ac36..78f5dc5b9a16a 100644 --- a/src/Analyzers/CSharp/Tests/AddInheritdoc/AddInheritdocTests.cs +++ b/src/Analyzers/CSharp/Tests/AddInheritdoc/AddInheritdocTests.cs @@ -9,70 +9,47 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AddInheritdoc -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - AddInheritdocCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AddInheritdoc; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + AddInheritdocCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsAddInheritdoc)] - public class AddInheritdocTests +[Trait(Traits.Feature, Traits.Features.CodeActionsAddInheritdoc)] +public class AddInheritdocTests +{ + private static async Task TestAsync(string initialMarkup, string expectedMarkup) { - private static async Task TestAsync(string initialMarkup, string expectedMarkup) + var test = new VerifyCS.Test { - var test = new VerifyCS.Test - { - TestCode = initialMarkup, - FixedCode = expectedMarkup, - CodeActionValidationMode = CodeActionValidationMode.Full, - }; - await test.RunAsync(); - } + TestCode = initialMarkup, + FixedCode = expectedMarkup, + CodeActionValidationMode = CodeActionValidationMode.Full, + }; + await test.RunAsync(); + } - private static async Task TestMissingAsync(string initialMarkup) - => await VerifyCS.VerifyCodeFixAsync(initialMarkup, initialMarkup); + private static async Task TestMissingAsync(string initialMarkup) + => await VerifyCS.VerifyCodeFixAsync(initialMarkup, initialMarkup); - [Fact] - public async Task AddMissingInheritdocOnOverridenMethod() - { - await TestAsync( - """ - /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } - /// Some doc. - public class Derived: BaseClass - { - public override void {|CS1591:M|}() { } - } - """, - """ - /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } + [Fact] + public async Task AddMissingInheritdocOnOverridenMethod() + { + await TestAsync( + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class Derived: BaseClass - { - /// - public override void M() { } - } - """); - } - - [Theory] - [InlineData("public void {|CS1591:OtherMethod|}() { }")] - [InlineData("public void {|CS1591:M|}() { }")] - [InlineData("public new void {|CS1591:M|}() { }")] - public async Task DoNotOfferOnNotOverridenMethod(string methodDefintion) - { - await TestMissingAsync( - $$""" + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + public override void {|CS1591:M|}() { } + } + """, + """ /// Some doc. public class BaseClass { @@ -82,320 +59,342 @@ public virtual void M() { } /// Some doc. public class Derived: BaseClass { - {{methodDefintion}} + /// + public override void M() { } } """); - } + } - [Fact] - public async Task AddMissingInheritdocOnImplicitInterfaceMethod() + [Theory] + [InlineData("public void {|CS1591:OtherMethod|}() { }")] + [InlineData("public void {|CS1591:M|}() { }")] + [InlineData("public new void {|CS1591:M|}() { }")] + public async Task DoNotOfferOnNotOverridenMethod(string methodDefintion) + { + await TestMissingAsync( + $$""" + /// Some doc. + public class BaseClass { - await TestAsync( - """ - /// Some doc. - public interface IInterface - { - /// Some doc. - void M(); - } - /// Some doc. - public class MyClass: IInterface - { - public void {|CS1591:M|}() { } - } - """, - """ - /// Some doc. - public interface IInterface - { - /// Some doc. - void M(); - } - /// Some doc. - public class MyClass: IInterface - { - /// - public void M() { } - } - """); + /// Some doc. + public virtual void M() { } } - - [Fact] - public async Task DoNotOfferOnExplicitInterfaceMethod() + /// Some doc. + public class Derived: BaseClass { - await TestMissingAsync( - """ - /// Some doc. - public interface IInterface - { - /// Some doc. - void M(); - } - /// Some doc. - public class MyClass: IInterface - { - void IInterface.M() { } - } - """); + {{methodDefintion}} } - [Fact] - public async Task AddMissingInheritdocOnOverridenProperty() - { - await TestAsync( - """ - /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual string P { get; set; } - } - /// Some doc. - public class Derived: BaseClass - { - public override string {|CS1591:P|} { get; set; } - } - """, - """ + """); + } + + [Fact] + public async Task AddMissingInheritdocOnImplicitInterfaceMethod() + { + await TestAsync( + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual string P { get; set; } - } + void M(); + } + /// Some doc. + public class MyClass: IInterface + { + public void {|CS1591:M|}() { } + } + """, + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public class Derived: BaseClass - { - /// - public override string P { get; set; } - } - """); - } + void M(); + } + /// Some doc. + public class MyClass: IInterface + { + /// + public void M() { } + } + """); + } - [Fact] - public async Task AddMissingInheritdocOnImplicitInterfaceProperty() - { - await TestAsync( - """ - /// Some doc. - public interface IInterface - { - /// Some doc. - string P { get; } - } + [Fact] + public async Task DoNotOfferOnExplicitInterfaceMethod() + { + await TestMissingAsync( + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public class MyClass: IInterface - { - public string {|CS1591:P|} { get; } - } - """, - """ + void M(); + } + /// Some doc. + public class MyClass: IInterface + { + void IInterface.M() { } + } + """); + } + [Fact] + public async Task AddMissingInheritdocOnOverridenProperty() + { + await TestAsync( + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public interface IInterface - { - /// Some doc. - string P { get; } - } + public virtual string P { get; set; } + } + /// Some doc. + public class Derived: BaseClass + { + public override string {|CS1591:P|} { get; set; } + } + """, + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class MyClass: IInterface - { - /// - public string P { get; } - } - """); - } + public virtual string P { get; set; } + } + /// Some doc. + public class Derived: BaseClass + { + /// + public override string P { get; set; } + } + """); + } - [Fact] - public async Task AddMissingInheritdocOnImplicitInterfaceEvent() - { - await TestAsync( - """ + [Fact] + public async Task AddMissingInheritdocOnImplicitInterfaceProperty() + { + await TestAsync( + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public interface IInterface - { - /// Some doc. - event System.Action SomeEvent; - } + string P { get; } + } + /// Some doc. + public class MyClass: IInterface + { + public string {|CS1591:P|} { get; } + } + """, + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public class MyClass: IInterface - { - public event System.Action {|CS1591:SomeEvent|}; + string P { get; } + } + /// Some doc. + public class MyClass: IInterface + { + /// + public string P { get; } + } + """); + } - void OnSomething() => SomeEvent?.Invoke(); - } - """, - """ + [Fact] + public async Task AddMissingInheritdocOnImplicitInterfaceEvent() + { + await TestAsync( + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public interface IInterface - { - /// Some doc. - event System.Action SomeEvent; - } + event System.Action SomeEvent; + } + /// Some doc. + public class MyClass: IInterface + { + public event System.Action {|CS1591:SomeEvent|}; + + void OnSomething() => SomeEvent?.Invoke(); + } + """, + """ + /// Some doc. + public interface IInterface + { /// Some doc. - public class MyClass: IInterface - { - /// - public event System.Action SomeEvent; + event System.Action SomeEvent; + } + /// Some doc. + public class MyClass: IInterface + { + /// + public event System.Action SomeEvent; - void OnSomething() => SomeEvent?.Invoke(); - } - """); - } + void OnSomething() => SomeEvent?.Invoke(); + } + """); + } - [Fact] - public async Task AddMissingInheritdocTriviaTest_1() - { - await TestAsync( - """ - /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } - /// Some doc. - public class Derived: BaseClass - { - // Comment - public override void {|CS1591:M|}() { } - } - """, - """ + [Fact] + public async Task AddMissingInheritdocTriviaTest_1() + { + await TestAsync( + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + // Comment + public override void {|CS1591:M|}() { } + } + """, + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class Derived: BaseClass - { - /// - // Comment - public override void M() { } - } - """); - } + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + /// + // Comment + public override void M() { } + } + """); + } - [Fact] - public async Task AddMissingInheritdocTriviaTest_2() - { - await TestAsync( - """ - /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } - /// Some doc. - public class Derived: BaseClass - { - // Comment 1 - /* Comment 2 */ public /* Comment 3 */ override void {|CS1591:M|} /* Comment 4 */ () /* Comment 5 */ { } /* Comment 6 */ - } - """, - """ + [Fact] + public async Task AddMissingInheritdocTriviaTest_2() + { + await TestAsync( + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + // Comment 1 + /* Comment 2 */ public /* Comment 3 */ override void {|CS1591:M|} /* Comment 4 */ () /* Comment 5 */ { } /* Comment 6 */ + } + """, + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class Derived: BaseClass - { - /// - // Comment 1 - /* Comment 2 */ public /* Comment 3 */ override void M /* Comment 4 */ () /* Comment 5 */ { } /* Comment 6 */ - } - """); - } + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + /// + // Comment 1 + /* Comment 2 */ public /* Comment 3 */ override void M /* Comment 4 */ () /* Comment 5 */ { } /* Comment 6 */ + } + """); + } - [Fact] - public async Task AddMissingInheritdocMethodWithAttribute() - { - await TestAsync( - """ - /// Some doc. - [System.AttributeUsage(System.AttributeTargets.Method)] - public sealed class DummyAttribute: System.Attribute - { - } + [Fact] + public async Task AddMissingInheritdocMethodWithAttribute() + { + await TestAsync( + """ + /// Some doc. + [System.AttributeUsage(System.AttributeTargets.Method)] + public sealed class DummyAttribute: System.Attribute + { + } + /// Some doc. + public class BaseClass + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } - /// Some doc. - public class Derived: BaseClass - { - [Dummy] - public override void {|CS1591:M|}() { } - } - """, - """ - /// Some doc. - [System.AttributeUsage(System.AttributeTargets.Method)] - public sealed class DummyAttribute: System.Attribute - { - } + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + [Dummy] + public override void {|CS1591:M|}() { } + } + """, + """ + /// Some doc. + [System.AttributeUsage(System.AttributeTargets.Method)] + public sealed class DummyAttribute: System.Attribute + { + } + /// Some doc. + public class BaseClass + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - } - /// Some doc. - public class Derived: BaseClass - { - /// - [Dummy] - public override void M() { } - } - """); - } + public virtual void M() { } + } + /// Some doc. + public class Derived: BaseClass + { + /// + [Dummy] + public override void M() { } + } + """); + } - [Fact] - public async Task AddMissingInheritdocFixAll() - { - await TestAsync( - """ + [Fact] + public async Task AddMissingInheritdocFixAll() + { + await TestAsync( + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - /// Some doc. - public virtual string P { get; } - } + public virtual void M() { } /// Some doc. - public class Derived: BaseClass - { - public override void {|CS1591:M|}() { } - public override string {|CS1591:P|} { get; } - } - """, - """ + public virtual string P { get; } + } + /// Some doc. + public class Derived: BaseClass + { + public override void {|CS1591:M|}() { } + public override string {|CS1591:P|} { get; } + } + """, + """ + /// Some doc. + public class BaseClass + { /// Some doc. - public class BaseClass - { - /// Some doc. - public virtual void M() { } - /// Some doc. - public virtual string P { get; } - } + public virtual void M() { } /// Some doc. - public class Derived: BaseClass - { - /// - public override void M() { } - /// - public override string P { get; } - } - """); - } + public virtual string P { get; } + } + /// Some doc. + public class Derived: BaseClass + { + /// + public override void M() { } + /// + public override string P { get; } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs b/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs index c1ad315deac55..fb5f1c293589f 100644 --- a/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs +++ b/src/Analyzers/CSharp/Tests/AddObsoleteAttribute/AddObsoleteAttributeTests.cs @@ -11,403 +11,402 @@ Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer, Microsoft.CodeAnalysis.CSharp.AddObsoleteAttribute.CSharpAddObsoleteAttributeCodeFixProvider>; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddObsoleteAttribute +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddObsoleteAttribute; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddObsoleteAttribute)] +public class AddObsoleteAttributeTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddObsoleteAttribute)] - public class AddObsoleteAttributeTests + [Fact] + public async Task TestObsoleteClassNoMessage() { - [Fact] - public async Task TestObsoleteClassNoMessage() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [System.Obsolete] - class Base {} + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete] + class Base {} + + class Derived : {|CS0612:Base|} { + } + """, + """ + [System.Obsolete] + class Base {} + + [System.Obsolete] + class Derived : Base { + } + """); + } - class Derived : {|CS0612:Base|} { - } - """, - """ - [System.Obsolete] - class Base {} + [Fact] + public async Task TestObsoleteClassWithMessage() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete("message")] + class Base {} + + class Derived : {|CS0618:Base|} { + } + """, + """ + [System.Obsolete("message")] + class Base {} + + [System.Obsolete] + class Derived : Base { + } + """); + } - [System.Obsolete] - class Derived : Base { - } - """); - } - - [Fact] - public async Task TestObsoleteClassWithMessage() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [System.Obsolete("message")] - class Base {} + [Fact] + public async Task TestObsoleteClassWithMessageAndErrorFalse() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete("message", error: false)] + class Base {} + + class Derived : {|CS0618:Base|} { + } + """, + """ + [System.Obsolete("message", error: false)] + class Base {} + + [System.Obsolete] + class Derived : Base { + } + """); + } - class Derived : {|CS0618:Base|} { - } - """, - """ - [System.Obsolete("message")] - class Base {} + [Fact] + public async Task TestObsoleteClassWithMessageAndErrorTrue() + { + var code = """ + [System.Obsolete("message", error: true)] + class Base {} + + class Derived : {|CS0619:Base|} { + } + """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [Fact] + public async Task TestObsoleteClassUsedInField() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete] + class Base { public static int i; } + + class Derived { + int i = {|CS0612:Base|}.i; + } + """, + """ + [System.Obsolete] + class Base { public static int i; } + + class Derived { [System.Obsolete] - class Derived : Base { - } - """); - } - - [Fact] - public async Task TestObsoleteClassWithMessageAndErrorFalse() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [System.Obsolete("message", error: false)] - class Base {} + int i = Base.i; + } + """); + } + + [Fact] + public async Task TestObsoleteClassUsedInMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete] + class Base { public static int i; } - class Derived : {|CS0618:Base|} { + class Derived { + void Goo() { + int i = {|CS0612:Base|}.i; } - """, - """ - [System.Obsolete("message", error: false)] - class Base {} + } + """, + """ + [System.Obsolete] + class Base { public static int i; } + class Derived { [System.Obsolete] - class Derived : Base { + void Goo() { + int i = Base.i; } - """); - } + } + """); + } - [Fact] - public async Task TestObsoleteClassWithMessageAndErrorTrue() - { - var code = """ - [System.Obsolete("message", error: true)] - class Base {} + [Fact] + public async Task TestObsoleteOverride() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Base { + [System.Obsolete] + protected virtual void ObMethod() { } + } + + class Derived : Base { + protected override void {|CS0672:ObMethod|}() { } + } + """, + """ + class Base { + [System.Obsolete] + protected virtual void ObMethod() { } + } - class Derived : {|CS0619:Base|} { - } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task TestObsoleteClassUsedInField() - { - await VerifyCS.VerifyCodeFixAsync( - """ + class Derived : Base { [System.Obsolete] - class Base { public static int i; } + protected override void ObMethod() { } + } + """); + } - class Derived { + [Fact] + public async Task TestObsoleteClassFixAll1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete] + class Base { public static int i; } + + class Derived { + void Goo() { int i = {|CS0612:Base|}.i; + int j = {|CS0612:Base|}.i; } - """, - """ - [System.Obsolete] - class Base { public static int i; } + } + """, + """ + [System.Obsolete] + class Base { public static int i; } - class Derived { - [System.Obsolete] + class Derived { + [System.Obsolete] + void Goo() { int i = Base.i; + int j = Base.i; } - """); - } - - [Fact] - public async Task TestObsoleteClassUsedInMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [System.Obsolete] - class Base { public static int i; } + } + """); + } - class Derived { - void Goo() { - int i = {|CS0612:Base|}.i; - } - } - """, - """ - [System.Obsolete] - class Base { public static int i; } + [Fact] + public async Task TestObsoleteClassFixAll2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete] + class Base { public static int i; } - class Derived { - [System.Obsolete] - void Goo() { - int i = Base.i; - } - } - """); - } - - [Fact] - public async Task TestObsoleteOverride() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Base { - [System.Obsolete] - protected virtual void ObMethod() { } + class Derived { + void Goo() { + int i = {|CS0612:Base|}.i; + int j = {|CS0612:Base|}.i; } + } + """, + """ + [System.Obsolete] + class Base { public static int i; } - class Derived : Base { - protected override void {|CS0672:ObMethod|}() { } - } - """, - """ - class Base { - [System.Obsolete] - protected virtual void ObMethod() { } + class Derived { + [System.Obsolete] + void Goo() { + int i = Base.i; + int j = Base.i; } + } + """); + } + + [Fact] + public async Task TestObsoleteClassFixAll3() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [System.Obsolete] + class Base { public static int i; } - class Derived : Base { - [System.Obsolete] - protected override void ObMethod() { } + class Derived { + void Goo() { + int i = {|CS0612:Base|}.i; } - """); - } - - [Fact] - public async Task TestObsoleteClassFixAll1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [System.Obsolete] - class Base { public static int i; } - class Derived { - void Goo() { - int i = {|CS0612:Base|}.i; - int j = {|CS0612:Base|}.i; - } + void Bar() { + int j = {|CS0612:Base|}.i; } - """, - """ + } + """, + """ + [System.Obsolete] + class Base { public static int i; } + + class Derived { [System.Obsolete] - class Base { public static int i; } - - class Derived { - [System.Obsolete] - void Goo() { - int i = Base.i; - int j = Base.i; - } + void Goo() { + int i = Base.i; } - """); - } - - [Fact] - public async Task TestObsoleteClassFixAll2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [System.Obsolete] - class Base { public static int i; } - class Derived { - void Goo() { - int i = {|CS0612:Base|}.i; - int j = {|CS0612:Base|}.i; - } - } - """, - """ [System.Obsolete] - class Base { public static int i; } - - class Derived { - [System.Obsolete] - void Goo() { - int i = Base.i; - int j = Base.i; - } + void Bar() { + int j = Base.i; } - """); - } - - [Fact] - public async Task TestObsoleteClassFixAll3() - { - await VerifyCS.VerifyCodeFixAsync( - """ + } + """); + } + + [Fact] + public async Task TestObsoleteCollectionAddMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Collection : System.Collections.Generic.IEnumerable { + [System.Obsolete] + public void Add(int i) { } + + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } + + class Derived { + void Goo() { + var c = new Collection { + {|CS1064:1|}, {|CS1064:2|}, {|CS1064:3|} + }; + } + } + """, + """ + class Collection : System.Collections.Generic.IEnumerable { [System.Obsolete] - class Base { public static int i; } + public void Add(int i) { } - class Derived { - void Goo() { - int i = {|CS0612:Base|}.i; - } + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } - void Bar() { - int j = {|CS0612:Base|}.i; - } - } - """, - """ + class Derived { [System.Obsolete] - class Base { public static int i; } - - class Derived { - [System.Obsolete] - void Goo() { - int i = Base.i; - } - - [System.Obsolete] - void Bar() { - int j = Base.i; - } - } - """); - } - - [Fact] - public async Task TestObsoleteCollectionAddMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + void Goo() { + var c = new Collection { + 1, 2, 3 + }; } + } + """); + } - class Derived { - void Goo() { - var c = new Collection { - {|CS1064:1|}, {|CS1064:2|}, {|CS1064:3|} - }; - } - } - """, - """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; - } + [Fact] + public async Task TestObsoleteCollectionAddMethodWithMessage() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Collection : System.Collections.Generic.IEnumerable { + [System.Obsolete("message")] + public void Add(int i) { } + + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } + + class Derived { + void Goo() { + var c = new Collection { + {|CS1062:1|}, {|CS1062:2|}, {|CS1062:3|} + }; + } + } + """, + """ + class Collection : System.Collections.Generic.IEnumerable { + [System.Obsolete("message")] + public void Add(int i) { } - class Derived { - [System.Obsolete] - void Goo() { - var c = new Collection { - 1, 2, 3 - }; - } - } - """); - } - - [Fact] - public async Task TestObsoleteCollectionAddMethodWithMessage() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete("message")] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; - } + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } - class Derived { - void Goo() { - var c = new Collection { - {|CS1062:1|}, {|CS1062:2|}, {|CS1062:3|} - }; - } - } - """, - """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete("message")] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + class Derived { + [System.Obsolete] + void Goo() { + var c = new Collection { + 1, 2, 3 + }; } + } + """); + } - class Derived { - [System.Obsolete] - void Goo() { - var c = new Collection { - 1, 2, 3 - }; - } - } - """); - } - - [Fact] - public async Task TestObsoleteCollectionAddMethodWithMessageAndErrorFalse() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete("message", error: false)] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; - } + [Fact] + public async Task TestObsoleteCollectionAddMethodWithMessageAndErrorFalse() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Collection : System.Collections.Generic.IEnumerable { + [System.Obsolete("message", error: false)] + public void Add(int i) { } + + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } + + class Derived { + void Goo() { + var c = new Collection { + {|CS1062:1|}, {|CS1062:2|}, {|CS1062:3|} + }; + } + } + """, + """ + class Collection : System.Collections.Generic.IEnumerable { + [System.Obsolete("message", error: false)] + public void Add(int i) { } - class Derived { - void Goo() { - var c = new Collection { - {|CS1062:1|}, {|CS1062:2|}, {|CS1062:3|} - }; - } - } - """, - """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete("message", error: false)] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; - } + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } - class Derived { - [System.Obsolete] - void Goo() { - var c = new Collection { - 1, 2, 3 - }; - } - } - """); - } - - [Fact] - public async Task TestObsoleteCollectionAddMethodWithMessageAndErrorTrue() - { - var code = """ - class Collection : System.Collections.Generic.IEnumerable { - [System.Obsolete("message", error: true)] - public void Add(int i) { } - - public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + class Derived { + [System.Obsolete] + void Goo() { + var c = new Collection { + 1, 2, 3 + }; } + } + """); + } + + [Fact] + public async Task TestObsoleteCollectionAddMethodWithMessageAndErrorTrue() + { + var code = """ + class Collection : System.Collections.Generic.IEnumerable { + [System.Obsolete("message", error: true)] + public void Add(int i) { } + + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + } - class Derived { - void Goo() { - var c = new Collection { - {|CS1063:1|}, {|CS1063:2|}, {|CS1063:3|} - }; - } + class Derived { + void Goo() { + var c = new Collection { + {|CS1063:1|}, {|CS1063:2|}, {|CS1063:3|} + }; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); } } diff --git a/src/Analyzers/CSharp/Tests/AddParameter/AddParameterTests.cs b/src/Analyzers/CSharp/Tests/AddParameter/AddParameterTests.cs index 5a0895da35505..2393a4185a325 100644 --- a/src/Analyzers/CSharp/Tests/AddParameter/AddParameterTests.cs +++ b/src/Analyzers/CSharp/Tests/AddParameter/AddParameterTests.cs @@ -17,3146 +17,3145 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddParameter +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddParameter; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)] +public class AddParameterTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)] - public class AddParameterTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddParameterTests(ITestOutputHelper logger) + : base(logger) { - public AddParameterTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAddParameterCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAddParameterCodeFixProvider()); - protected override ImmutableArray MassageActions(ImmutableArray actions) - => FlattenActions(actions); + protected override ImmutableArray MassageActions(ImmutableArray actions) + => FlattenActions(actions); - [Fact] - public async Task TestMissingWithImplicitConstructor() - { - await TestMissingAsync( - """ - class C - { - } + [Fact] + public async Task TestMissingWithImplicitConstructor() + { + await TestMissingAsync( + """ + class C + { + } - class D + class D + { + void M() { - void M() - { - new [|C|](1); - } + new [|C|](1); } - """); - } + } + """); + } - [Fact] - public async Task TestOnEmptyConstructor() - { - await TestInRegularAndScriptAsync( - """ - class C - { - public C() { } - } + [Fact] + public async Task TestOnEmptyConstructor() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C() { } + } + + class D + { + void M() + { + new [|C|](1); + } + } + """, + """ + class C + { + public C(int v) { } + } + + class D + { + void M() + { + new C(1); + } + } + """); + } - class D - { - void M() - { - new [|C|](1); - } - } - """, - """ - class C + [Fact] + public async Task TestNamedArg() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C() { } + } + + class D + { + void M() + { + new C([|p|]: 1); + } + } + """, + """ + class C + { + public C(int p) { } + } + + class D + { + void M() + { + new C(p: 1); + } + } + """); + } + + [Fact] + public async Task TestMissingWithConstructorWithSameNumberOfParams() + { + await TestMissingAsync( + """ + class C + { + public C(bool b) { } + } + + class D + { + void M() { - public C(int v) { } + new [|C|](1); } + } + """); + } + + [Fact] + public async Task TestAddBeforeMatchingArg() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i) { } + } + + class D + { + void M() + { + new [|C|](true, 1); + } + } + """, + """ + class C + { + public C(bool v, int i) { } + } + + class D + { + void M() + { + new C(true, 1); + } + } + """); + } + + [Fact] + public async Task TestAddAfterMatchingConstructorParam() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i) { } + } + + class D + { + void M() + { + new [|C|](1, true); + } + } + """, + """ + class C + { + public C(int i, bool v) { } + } + + class D + { + void M() + { + new C(1, true); + } + } + """); + } + + [Fact] + public async Task TestParams1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(params int[] i) { } + } + + class D + { + void M() + { + new C([|true|], 1); + } + } + """, + """ + class C + { + public C(bool v, params int[] i) { } + } + + class D + { + void M() + { + new C(true, 1); + } + } + """); + } + + [Fact] + public async Task TestParams2() + { + await TestMissingAsync( + """ + class C + { + public C(params int[] i) { } + } - class D + class D + { + void M() { - void M() - { - new C(1); - } + new [|C|](1, true); } - """); - } + } + """); + } - [Fact] - public async Task TestNamedArg() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] + public async Task TestMultiLineParameters1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i, + /* goo */ int j) { - public C() { } + } - class D + private void Goo() { - void M() - { - new C([|p|]: 1); - } + new [|C|](true, 0, 0); } - """, - """ - class C + } + """, + """ + class C + { + public C(bool v, + int i, + /* goo */ int j) { - public C(int p) { } - } - class D - { - void M() - { - new C(p: 1); - } } - """); - } - [Fact] - public async Task TestMissingWithConstructorWithSameNumberOfParams() - { - await TestMissingAsync( - """ - class C + private void Goo() { - public C(bool b) { } + new C(true, 0, 0); } + } + """); + } - class D + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] + public async Task TestMultiLineParameters2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i, + /* goo */ int j) { - void M() - { - new [|C|](1); - } - } - """); - } - [Fact] - public async Task TestAddBeforeMatchingArg() - { - await TestInRegularAndScriptAsync( - """ - class C - { - public C(int i) { } } - class D + private void Goo() { - void M() - { - new [|C|](true, 1); - } + new [|C|](0, true, 0); } - """, - """ - class C + } + """, + """ + class C + { + public C(int i, + bool v, + /* goo */ int j) { - public C(bool v, int i) { } + } - class D + private void Goo() { - void M() - { - new C(true, 1); - } + new C(0, true, 0); } - """); - } + } + """); + } - [Fact] - public async Task TestAddAfterMatchingConstructorParam() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] + public async Task TestMultiLineParameters3() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i, + /* goo */ int j) { - public C(int i) { } + } - class D + private void Goo() { - void M() - { - new [|C|](1, true); - } + new [|C|](0, 0, true); } - """, - """ - class C + } + """, + """ + class C + { + public C(int i, + /* goo */ int j, + bool v) { - public C(int i, bool v) { } + } - class D + private void Goo() { - void M() - { - new C(1, true); - } + new C(0, 0, true); } - """); - } + } + """); + } - [Fact] - public async Task TestParams1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] + public async Task TestMultiLineParameters4() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C( + int i, + /* goo */ int j) { - public C(params int[] i) { } + } - class D + private void Goo() { - void M() - { - new C([|true|], 1); - } + new [|C|](true, 0, 0); } - """, - """ - class C + } + """, + """ + class C + { + public C( + bool v, + int i, + /* goo */ int j) { - public C(bool v, params int[] i) { } - } - class D - { - void M() - { - new C(true, 1); - } } - """); - } - [Fact] - public async Task TestParams2() - { - await TestMissingAsync( - """ - class C + private void Goo() { - public C(params int[] i) { } + new C(true, 0, 0); } + } + """); + } - class D + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] + public async Task TestMultiLineParameters5() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C( + int i, + /* goo */ int j) { - void M() - { - new [|C|](1, true); - } + } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] - public async Task TestMultiLineParameters1() - { - await TestInRegularAndScriptAsync( - """ - class C + private void Goo() { - public C(int i, - /* goo */ int j) - { - - } - - private void Goo() - { - new [|C|](true, 0, 0); - } + new [|C|](0, true, 0); } - """, - """ - class C + } + """, + """ + class C + { + public C( + int i, + bool v, + /* goo */ int j) { - public C(bool v, - int i, - /* goo */ int j) - { - } - - private void Goo() - { - new C(true, 0, 0); - } } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] - public async Task TestMultiLineParameters2() - { - await TestInRegularAndScriptAsync( - """ - class C + private void Goo() { - public C(int i, - /* goo */ int j) - { - - } - - private void Goo() - { - new [|C|](0, true, 0); - } + new C(0, true, 0); } - """, - """ - class C - { - public C(int i, - bool v, - /* goo */ int j) - { + } + """); + } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] + public async Task TestMultiLineParameters6() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C( + int i, + /* goo */ int j) + { - private void Goo() - { - new C(0, true, 0); - } } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] - public async Task TestMultiLineParameters3() - { - await TestInRegularAndScriptAsync( - """ - class C + private void Goo() { - public C(int i, - /* goo */ int j) - { - - } - - private void Goo() - { - new [|C|](0, 0, true); - } + new [|C|](0, 0, true); } - """, - """ - class C + } + """, + """ + class C + { + public C( + int i, + /* goo */ int j, + bool v) { - public C(int i, - /* goo */ int j, - bool v) - { - - } - private void Goo() - { - new C(0, 0, true); - } } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] - public async Task TestMultiLineParameters4() - { - await TestInRegularAndScriptAsync( - """ - class C + private void Goo() { - public C( - int i, - /* goo */ int j) - { - - } - - private void Goo() - { - new [|C|](true, 0, 0); - } + new C(0, 0, true); } - """, - """ - class C - { - public C( - bool v, - int i, - /* goo */ int j) - { + } + """); + } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] + public async Task TestNullArg1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i) { } + } + + class D + { + void M() + { + new [|C|](null, 1); + } + } + """, + """ + class C + { + public C(object value, int i) { } + } + + class D + { + void M() + { + new C(null, 1); + } + } + """); + } - private void Goo() - { - new C(true, 0, 0); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] + public async Task TestNullArg2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(string s) { } + } + + class D + { + void M() + { + new [|C|](null, 1); + } + } + """, + """ + class C + { + public C(string s, int v) { } + } + + class D + { + void M() + { + new C(null, 1); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] - public async Task TestMultiLineParameters5() - { - await TestInRegularAndScriptAsync( - """ - class C - { - public C( - int i, - /* goo */ int j) - { + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] + public async Task TestDefaultArg1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(int i) { } + } + + class D + { + void M() + { + new [|C|](default, 1); + } + } + """, + """ + class C + { + public C(int i, int v) { } + } + + class D + { + void M() + { + new C(default, 1); + } + } + """); + } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] + public async Task TestDefaultArg2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C(string s) { } + } + + class D + { + void M() + { + new [|C|](default, 1); + } + } + """, + """ + class C + { + public C(string s, int v) { } + } + + class D + { + void M() + { + new C(default, 1); + } + } + """); + } - private void Goo() - { - new [|C|](0, true, 0); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationInstanceMethod1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M1() + { } - """, - """ - class C + void M2() { - public C( - int i, - bool v, - /* goo */ int j) - { - - } - - private void Goo() - { - new C(0, true, 0); - } + int i=0; + [|M1|](i); } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20708")] - public async Task TestMultiLineParameters6() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + void M1(int i) { - public C( - int i, - /* goo */ int j) - { - - } - - private void Goo() - { - new [|C|](0, 0, true); - } } - """, - """ - class C + void M2() { - public C( - int i, - /* goo */ int j, - bool v) - { - - } - - private void Goo() - { - new C(0, 0, true); - } + int i=0; + M1(i); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] - public async Task TestNullArg1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationInheritedMethodGetFixed() + { + await TestInRegularAndScriptAsync( + """ + class Base + { + protected void M1() { - public C(int i) { } } - - class D + } + class C1 : Base + { + void M2() { - void M() - { - new [|C|](null, 1); - } + int i = 0; + [|M1|](i); } - """, - """ - class C + } + """, + """ + class Base + { + protected void M1(int i) { - public C(object value, int i) { } } - - class D + } + class C1 : Base + { + void M2() { - void M() - { - new C(null, 1); - } + int i = 0; + M1(i); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] - public async Task TestNullArg2() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationInheritedMethodInMetadatGetsNotFixed() + { + await TestMissingAsync( + """ + class C1 + { + void M2() { - public C(string s) { } + int i = 0; + [|GetHashCode|](i); } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationLocalFunction() + { + await TestInRegularAndScriptAsync( + """ + class C1 + { + void M1() + { + int Local() => 1; + [|Local|](2); + } + } + """, + """ + class C1 + { + void M1() + { + int Local(int v) => 1; + Local(2); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + [Trait("TODO", "Fix broken")] + public async Task TestInvocationLambda1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + class C1 + { + void M1() + { + Action a = () => { }; + [|a|](2); + } + } + """); + //Should be Action a = (int v) => { }; + } - class D + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationStaticMethod() + { + await TestInRegularAndScriptAsync( + """ + class C1 + { + static void M1() { - void M() - { - new [|C|](null, 1); - } } - """, - """ - class C + void M2() { - public C(string s, int v) { } + [|M1|](1); } - - class D + } + """, + """ + class C1 + { + static void M1(int v) { - void M() - { - new C(null, 1); - } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] - public async Task TestDefaultArg1() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2() { - public C(int i) { } + M1(1); } + } + """); + } - class D + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationExtensionMethod() + { + var code = + """ + namespace N { + static class Extensions + { + public static void ExtensionM1(this object o) { - void M() - { - new [|C|](default, 1); - } } - """, - """ - class C + } + class C1 + { + void M1() { - public C(int i, int v) { } + new object().[|ExtensionM1|](1); } - - class D + }} + """; + var fix = + """ + namespace N { + static class Extensions + { + public static void ExtensionM1(this object o, int v) { - void M() - { - new C(default, 1); - } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20973")] - public async Task TestDefaultArg2() - { - await TestInRegularAndScriptAsync( - """ - class C + } + class C1 + { + void M1() { - public C(string s) { } + new object().ExtensionM1(1); } + }} + """; + await TestInRegularAndScriptAsync(code, fix); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationExtensionMethod_StaticInvocationStyle() + { + // error CS1501: No overload for method 'ExtensionM1' takes 2 arguments + var code = + """ + namespace N { + static class Extensions + { + public static void ExtensionM1(this object o) + { + } + } + class C1 + { + void M1() + { + Extensions.[|ExtensionM1|](new object(), 1); + } + }} + """; + var fix = + """ + namespace N { + static class Extensions + { + public static void ExtensionM1(this object o, int v) + { + } + } + class C1 + { + void M1() + { + Extensions.ExtensionM1(new object(), 1); + } + }} + """; + await TestInRegularAndScriptAsync(code, fix); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationOverride() + { + var code = """ + class Base + { + protected virtual void M1() { } + } + class C1 : Base + { + protected override void M1() { } + void M2() + { + [|M1|](1); + } + } + """; + var fix_DeclarationOnly = """ + class Base + { + protected virtual void M1() { } + } + class C1 : Base + { + protected override void M1(int v) { } + void M2() + { + M1(1); + } + } + """; + var fix_All = """ + class Base + { + protected virtual void M1(int v) { } + } + class C1 : Base + { + protected override void M1(int v) { } + void M2() + { + M1(1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationExplicitInterface() + { + var code = """ + interface I1 + { + void M1(); + } + class C1 : I1 + { + void I1.M1() { } + void M2() + { + ((I1)this).[|M1|](1); + } + } + """; + var fix_DeclarationOnly = """ + interface I1 + { + void M1(int v); + } + class C1 : I1 + { + void I1.M1() { } + void M2() + { + ((I1)this).M1(1); + } + } + """; + var fix_All = """ + interface I1 + { + void M1(int v); + } + class C1 : I1 + { + void I1.M1(int v) { } + void M2() + { + ((I1)this).M1(1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationImplicitInterface() + { + var code = + """ + interface I1 + { + void M1(); + } + class C1 : I1 + { + public void M1() { } + void M2() + { + [|M1|](1); + } + } + """; + var fix_DeclarationOnly = """ + interface I1 + { + void M1(); + } + class C1 : I1 + { + public void M1(int v) { } + void M2() + { + M1(1); + } + } + """; + var fix_All = """ + interface I1 + { + void M1(int v); + } + class C1 : I1 + { + public void M1(int v) { } + void M2() + { + M1(1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationImplicitInterfaces() + { + var code = + """ + interface I1 + { + void M1(); + } + interface I2 + { + void M1(); + } + class C1 : I1, I2 + { + public void M1() { } + void M2() + { + [|M1|](1); + } + } + """; + var fix_DeclarationOnly = """ + interface I1 + { + void M1(); + } + interface I2 + { + void M1(); + } + class C1 : I1, I2 + { + public void M1(int v) { } + void M2() + { + M1(1); + } + } + """; + var fix_All = """ + interface I1 + { + void M1(int v); + } + interface I2 + { + void M1(int v); + } + class C1 : I1, I2 + { + public void M1(int v) { } + void M2() + { + M1(1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } - class D + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + [Trait("TODO", "Fix broken")] + public async Task TestInvocationGenericMethod() + { + await TestInRegularAndScriptAsync( + """ + class C1 + { + void M1(T arg) { } + void M2() + { + [|M1|](1, 2); + } + } + """, + """ + class C1 + { + void M1(T arg, int v) { } + void M2() + { + M1(1, 2); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationRecursion() + { + await TestInRegularAndScriptAsync( + """ + class C1 + { + void M1() { - void M() - { - new [|C|](default, 1); - } + [|M1|](1); } - """, - """ - class C + } + """, + """ + class C1 + { + void M1(int v) { - public C(string s, int v) { } + M1(1); } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationOverloads1() + { + var code = + """ + class C1 + { + void M1(string s) { } + void M1(int i) { } + void M2() + { + [|M1|](1, 2); + } + } + """; + var fix0 = + """ + class C1 + { + void M1(string s) { } + void M1(int i, int v) { } + void M2() + { + M1(1, 2); + } + } + """; + var fix1 = + """ + class C1 + { + void M1(int v, string s) { } + void M1(int i) { } + void M2() + { + M1(1, 2); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, 0); + await TestInRegularAndScriptAsync(code, fix1, 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationOverloads2() + { + var code = + """ + class C1 + { + void M1(string s1, string s2) { } + void M1(string s) { } + void M1(int i) { } + void M2() + { + M1(1, [|2|]); + } + } + """; + var fix0 = + """ + class C1 + { + void M1(string s1, string s2) { } + void M1(string s) { } + void M1(int i, int v) { } + void M2() + { + M1(1, 2); + } + } + """; + var fix1 = + """ + class C1 + { + void M1(string s1, string s2) { } + void M1(int v, string s) { } + void M1(int i) { } + void M2() + { + M1(1, 2); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, 0); + await TestInRegularAndScriptAsync(code, fix1, 1); + } - class D + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationTuple1() + { + var code = + """ + class C1 + { + void M1((int, int) t1) { - void M() - { - new C(default, 1); - } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationInstanceMethod1() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2() { - void M1() - { - } - void M2() - { - int i=0; - [|M1|](i); - } + [|M1|]((0, 0), (1, "1")); } - """, - """ - class C + } + """; + var fix0 = + """ + class C1 + { + void M1((int, int) t1, (int, string) value) { - void M1(int i) - { - } - void M2() - { - int i=0; - M1(i); - } } - """); - } + void M2() + { + M1((0, 0), (1, "1")); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, 0); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationInheritedMethodGetFixed() - { - await TestInRegularAndScriptAsync( - """ - class Base + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationTuple2() + { + var code = + """ + class C1 + { + void M1((int, int) t1) { - protected void M1() - { - } } - class C1 : Base + void M2() { - void M2() - { - int i = 0; - [|M1|](i); - } + var tup = (1, "1"); + [|M1|]((0, 0), tup); } - """, - """ - class Base + } + """; + var fix0 = + """ + class C1 + { + void M1((int, int) t1, (int, string) tup) { - protected void M1(int i) - { - } } - class C1 : Base + void M2() { - void M2() - { - int i = 0; - M1(i); - } + var tup = (1, "1"); + M1((0, 0), tup); } - """); - } + } + """; + await TestInRegularAndScriptAsync(code, fix0, 0); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationInheritedMethodInMetadatGetsNotFixed() - { - await TestMissingAsync( - """ - class C1 + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationTuple3() + { + var code = + """ + class C1 + { + void M1((int, int) t1) { - void M2() - { - int i = 0; - [|GetHashCode|](i); - } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationLocalFunction() - { - await TestInRegularAndScriptAsync( - """ - class C1 + void M2() { - void M1() - { - int Local() => 1; - [|Local|](2); - } + var tup = (i: 1, s: "1"); + [|M1|]((0, 0), tup); } - """, - """ - class C1 + } + """; + var fix0 = + """ + class C1 + { + void M1((int, int) t1, (int i, string s) tup) { - void M1() - { - int Local(int v) => 1; - Local(2); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - [Trait("TODO", "Fix broken")] - public async Task TestInvocationLambda1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - class C1 - { - void M1() - { - Action a = () => { }; - [|a|](2); - } - } - """); - //Should be Action a = (int v) => { }; - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationStaticMethod() - { - await TestInRegularAndScriptAsync( - """ - class C1 - { - static void M1() - { - } - void M2() - { - [|M1|](1); - } } - """, - """ - class C1 + void M2() { - static void M1(int v) - { - } - void M2() - { - M1(1); - } + var tup = (i: 1, s: "1"); + M1((0, 0), tup); } - """); - } + } + """; + await TestInRegularAndScriptAsync(code, fix0, 0); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationExtensionMethod() - { - var code = - """ - namespace N { - static class Extensions - { - public static void ExtensionM1(this object o) - { - } - } - class C1 - { - void M1() - { - new object().[|ExtensionM1|](1); - } - }} - """; - var fix = - """ - namespace N { - static class Extensions - { - public static void ExtensionM1(this object o, int v) - { - } - } - class C1 - { - void M1() - { - new object().ExtensionM1(1); - } - }} - """; - await TestInRegularAndScriptAsync(code, fix); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationExtensionMethod_StaticInvocationStyle() - { - // error CS1501: No overload for method 'ExtensionM1' takes 2 arguments - var code = - """ - namespace N { - static class Extensions - { - public static void ExtensionM1(this object o) - { - } - } - class C1 - { - void M1() - { - Extensions.[|ExtensionM1|](new object(), 1); - } - }} - """; - var fix = - """ - namespace N { - static class Extensions - { - public static void ExtensionM1(this object o, int v) - { - } - } - class C1 - { - void M1() - { - Extensions.ExtensionM1(new object(), 1); - } - }} - """; - await TestInRegularAndScriptAsync(code, fix); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Missing_TypeArguments_AddingTypeArgumentAndParameter() + { + // error CS0305: Using the generic method 'C1.M1(T)' requires 1 type arguments + var code = + """ + class C1 + { + void M1(T i) { } + void M2() + { + [|M1|](1, true); + } + } + """; + // Could be fixed as void M1(T i, T1 v) { } + await TestMissingInRegularAndScriptAsync(code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationOverride() - { - var code = """ - class Base - { - protected virtual void M1() { } - } - class C1 : Base - { - protected override void M1() { } - void M2() - { - [|M1|](1); - } - } - """; - var fix_DeclarationOnly = """ - class Base - { - protected virtual void M1() { } - } - class C1 : Base - { - protected override void M1(int v) { } - void M2() - { - M1(1); - } - } - """; - var fix_All = """ - class Base - { - protected virtual void M1(int v) { } - } - class C1 : Base - { - protected override void M1(int v) { } - void M2() - { - M1(1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Missing_TypeArguments_AddingTypeArgument() + { + // error CS0308: The non-generic method 'C1.M1(int)' cannot be used with type arguments + var code = + """ + class C1 + { + void M1(int i) { } + void M2() + { + [|M1|](1, true); + } + } + """; + // Could be fixed as void M1(int i, T v) { } + await TestMissingInRegularAndScriptAsync(code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationExplicitInterface() - { - var code = """ - interface I1 - { - void M1(); - } - class C1 : I1 - { - void I1.M1() { } - void M2() - { - ((I1)this).[|M1|](1); - } - } - """; - var fix_DeclarationOnly = """ - interface I1 - { - void M1(int v); - } - class C1 : I1 - { + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + [Trait("TODO", "Fix missing")] + public async Task TestInvocation_Missing_ExplicitInterfaceImplementation() + { + // error CS0539: 'C1.M1(int)' in explicit interface declaration is not a member of interface + var code = + """ + interface I1 + { + void M1(); + } + class C1 : I1 + { void I1.M1() { } - void M2() - { - ((I1)this).M1(1); - } - } - """; - var fix_All = """ - interface I1 - { - void M1(int v); - } - class C1 : I1 - { - void I1.M1(int v) { } - void M2() - { - ((I1)this).M1(1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationImplicitInterface() - { - var code = - """ - interface I1 - { - void M1(); - } - class C1 : I1 - { - public void M1() { } - void M2() - { - [|M1|](1); - } - } - """; - var fix_DeclarationOnly = """ - interface I1 - { - void M1(); - } - class C1 : I1 - { - public void M1(int v) { } - void M2() - { - M1(1); - } - } - """; - var fix_All = """ - interface I1 - { - void M1(int v); - } - class C1 : I1 - { - public void M1(int v) { } - void M2() - { - M1(1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationImplicitInterfaces() - { - var code = - """ - interface I1 - { - void M1(); - } - interface I2 - { - void M1(); - } - class C1 : I1, I2 - { - public void M1() { } - void M2() - { - [|M1|](1); - } - } - """; - var fix_DeclarationOnly = """ - interface I1 - { - void M1(); - } - interface I2 - { - void M1(); - } - class C1 : I1, I2 - { - public void M1(int v) { } - void M2() - { - M1(1); - } - } - """; - var fix_All = """ - interface I1 - { - void M1(int v); - } - interface I2 - { - void M1(int v); - } - class C1 : I1, I2 - { - public void M1(int v) { } - void M2() - { - M1(1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - [Trait("TODO", "Fix broken")] - public async Task TestInvocationGenericMethod() - { - await TestInRegularAndScriptAsync( - """ - class C1 - { - void M1(T arg) { } - void M2() - { - [|M1|](1, 2); - } - } - """, - """ - class C1 - { - void M1(T arg, int v) { } - void M2() - { - M1(1, 2); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationRecursion() - { - await TestInRegularAndScriptAsync( - """ - class C1 - { - void M1() - { - [|M1|](1); - } - } - """, - """ - class C1 - { - void M1(int v) - { - M1(1); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationOverloads1() - { - var code = - """ - class C1 - { - void M1(string s) { } - void M1(int i) { } - void M2() - { - [|M1|](1, 2); - } - } - """; - var fix0 = - """ - class C1 - { - void M1(string s) { } - void M1(int i, int v) { } - void M2() - { - M1(1, 2); - } - } - """; - var fix1 = - """ - class C1 - { - void M1(int v, string s) { } - void M1(int i) { } - void M2() - { - M1(1, 2); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, 0); - await TestInRegularAndScriptAsync(code, fix1, 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationOverloads2() - { - var code = - """ - class C1 - { - void M1(string s1, string s2) { } - void M1(string s) { } - void M1(int i) { } - void M2() - { - M1(1, [|2|]); - } - } - """; - var fix0 = - """ - class C1 - { - void M1(string s1, string s2) { } - void M1(string s) { } - void M1(int i, int v) { } - void M2() - { - M1(1, 2); - } - } - """; - var fix1 = - """ - class C1 - { - void M1(string s1, string s2) { } - void M1(int v, string s) { } - void M1(int i) { } - void M2() - { - M1(1, 2); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, 0); - await TestInRegularAndScriptAsync(code, fix1, 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationTuple1() - { - var code = - """ - class C1 - { - void M1((int, int) t1) - { - } - void M2() - { - [|M1|]((0, 0), (1, "1")); - } - } - """; - var fix0 = - """ - class C1 - { - void M1((int, int) t1, (int, string) value) - { - } - void M2() - { - M1((0, 0), (1, "1")); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, 0); - } + void I1.[|M1|](int i) { } + } + """; + // Could apply argument to interface method: void M1(int i); + await TestMissingAsync(code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationTuple2() - { - var code = - """ - class C1 - { - void M1((int, int) t1) - { - } - void M2() - { - var tup = (1, "1"); - [|M1|]((0, 0), tup); - } - } - """; - var fix0 = - """ - class C1 - { - void M1((int, int) t1, (int, string) tup) - { - } - void M2() - { - var tup = (1, "1"); - M1((0, 0), tup); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, 0); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_OverloadResolutionFailure() + { + // error CS1503: Argument 1: cannot convert from 'double' to 'int' + var code = + """ + class C1 + { + void M1(int i1, int i2) { } + void M1(double d) { } + void M2() + { + M1([|1.0|], 1); + } + } + """; + var fix0 = + """ + class C1 + { + void M1(int i1, int i2) { } + void M1(double d, int v) { } + void M2() + { + M1(1.0, 1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationTuple3() - { - var code = - """ - class C1 - { - void M1((int, int) t1) - { - } - void M2() - { - var tup = (i: 1, s: "1"); - [|M1|]((0, 0), tup); - } - } - """; - var fix0 = - """ - class C1 - { - void M1((int, int) t1, (int i, string s) tup) - { - } - void M2() - { - var tup = (i: 1, s: "1"); - M1((0, 0), tup); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, 0); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_LambdaExpressionParameter() + { + // error CS1660: Cannot convert lambda expression to type 'int' because it is not a delegate type + var code = + """ + class C1 + { + void M1(int i1, int i2) { } + void M1(System.Action a) { } + void M2() + { + M1([|()=> { }|], 1); + } + } + """; + var fix = + """ + class C1 + { + void M1(int i1, int i2) { } + void M1(System.Action a, int v) { } + void M2() + { + M1(()=> { }, 1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Missing_TypeArguments_AddingTypeArgumentAndParameter() - { - // error CS0305: Using the generic method 'C1.M1(T)' requires 1 type arguments - var code = - """ - class C1 - { - void M1(T i) { } - void M2() - { - [|M1|](1, true); - } - } - """; - // Could be fixed as void M1(T i, T1 v) { } - await TestMissingInRegularAndScriptAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Missing_TypeArguments_AddingTypeArgument() - { - // error CS0308: The non-generic method 'C1.M1(int)' cannot be used with type arguments - var code = - """ - class C1 - { - void M1(int i) { } - void M2() - { - [|M1|](1, true); - } - } - """; - // Could be fixed as void M1(int i, T v) { } - await TestMissingInRegularAndScriptAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - [Trait("TODO", "Fix missing")] - public async Task TestInvocation_Missing_ExplicitInterfaceImplementation() - { - // error CS0539: 'C1.M1(int)' in explicit interface declaration is not a member of interface - var code = - """ - interface I1 - { - void M1(); - } - class C1 : I1 - { - void I1.M1() { } - void I1.[|M1|](int i) { } - } - """; - // Could apply argument to interface method: void M1(int i); - await TestMissingAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_OverloadResolutionFailure() - { - // error CS1503: Argument 1: cannot convert from 'double' to 'int' - var code = - """ - class C1 - { - void M1(int i1, int i2) { } - void M1(double d) { } - void M2() - { - M1([|1.0|], 1); - } - } - """; - var fix0 = - """ - class C1 - { - void M1(int i1, int i2) { } - void M1(double d, int v) { } - void M2() - { - M1(1.0, 1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_LambdaExpressionParameter() - { - // error CS1660: Cannot convert lambda expression to type 'int' because it is not a delegate type - var code = - """ - class C1 - { - void M1(int i1, int i2) { } - void M1(System.Action a) { } - void M2() - { - M1([|()=> { }|], 1); - } - } - """; - var fix = - """ - class C1 - { - void M1(int i1, int i2) { } - void M1(System.Action a, int v) { } - void M2() - { - M1(()=> { }, 1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_NamedParameter() + { + // error CS1739: The best overload for 'M1' does not have a parameter named 'i2' + var code = + """ + class C1 + { + void M1(int i1) { } + void M2() + { + M1([|i2|]: 1); + } + } + """; + var fix = + """ + class C1 + { + void M1(int i1, int i2) { } + void M2() + { + M1(i2: 1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_NamedParameter() - { - // error CS1739: The best overload for 'M1' does not have a parameter named 'i2' - var code = - """ - class C1 - { - void M1(int i1) { } - void M2() - { - M1([|i2|]: 1); - } - } - """; - var fix = - """ - class C1 - { - void M1(int i1, int i2) { } - void M2() - { - M1(i2: 1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationAddTypeParameter_AddTypeParameterIfUserSpecifiesOne_OnlyTypeArgument() + { + var code = + """ + class C1 + { + void M1() { } + void M2() + { + [|M1|](); + } + } + """; + // Could be fixed as void M1() { } + await TestMissingInRegularAndScriptAsync(code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationAddTypeParameter_AddTypeParameterIfUserSpecifiesOne_OnlyTypeArgument() - { - var code = - """ - class C1 - { - void M1() { } - void M2() - { - [|M1|](); - } - } - """; - // Could be fixed as void M1() { } - await TestMissingInRegularAndScriptAsync(code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocationAddTypeParameter_AddTypeParameterIfUserSpecifiesOne_TypeArgumentAndParameterArgument() + { + var code = + """ + class C1 + { + void M1() { } + void M2() + { + [|M1|](true); + } + } + """; + // Could be fixed to void M1(T v) { } + await TestMissingInRegularAndScriptAsync(code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocationAddTypeParameter_AddTypeParameterIfUserSpecifiesOne_TypeArgumentAndParameterArgument() - { - var code = - """ - class C1 - { - void M1() { } - void M2() - { - [|M1|](true); - } - } - """; - // Could be fixed to void M1(T v) { } - await TestMissingInRegularAndScriptAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_ExisitingTypeArgumentIsNotGeneralized() - { - var code = - """ - class C1 - { - void M1(T v) { } - void M2() - { - [|M1|](true, true); - } - } - """; - var fix0 = - """ - class C1 - { - void M1(T v, bool v1) { } - void M2() - { - M1(true, true); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_AddParameterToMethodWithParams() - { - // error CS1503: Argument 1: cannot convert from 'bool' to 'int' - var code = - """ - class C1 - { - static void M1(params int[] nums) { } - static void M2() - { - M1([|true|], 4); - } - } - """; - var fix0 = - """ - class C1 - { - static void M1(bool v, params int[] nums) { } - static void M2() - { - M1(true, 4); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_FixingVirtualFixesOverrideToo() - { - // error CS1501: No overload for method 'M1' takes 1 arguments - var code = - """ - class BaseClass - { - protected virtual void M1() { } - } - class Derived1: BaseClass - { - protected override void M1() { } - } - class Test: BaseClass - { - void M2() - { - [|M1|](1); - } - } - """; - var fix_DeclarationOnly = - """ - class BaseClass - { - protected virtual void M1(int v) { } - } - class Derived1: BaseClass - { - protected override void M1() { } - } - class Test: BaseClass - { - void M2() - { - M1(1); - } - } - """; - var fix_All = - """ - class BaseClass - { - protected virtual void M1(int v) { } - } - class Derived1: BaseClass - { - protected override void M1(int v) { } - } - class Test: BaseClass - { - void M2() - { - M1(1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_PartialMethods() - { - var code = - """ - - - - namespace N1 - { - partial class C1 - { - partial void PartialM(); - } - } - - - namespace N1 - { - partial class C1 - { - partial void PartialM() { } - void M1() - { - [|PartialM|](1); - } - } - } - - - - """; - var fix0 = - """ - - - - namespace N1 - { - partial class C1 - { - partial void PartialM(int v); - } - } - - - namespace N1 - { - partial class C1 - { - partial void PartialM(int v) { } - void M1() - { - PartialM(1); - } - } - } - - - - """; - await TestInRegularAndScriptAsync(code, fix0); - } - - [Fact] - public async Task TestInvocation_Cascading_ExtendedPartialMethods() - { - var code = - """ - - - - namespace N1 - { - partial class C1 - { - public partial void PartialM(); - } - } - - - namespace N1 - { - partial class C1 - { - public partial void PartialM() { } - void M1() - { - [|PartialM|](1); - } - } - } - - - - """; - var fix0 = - """ - - - - namespace N1 - { - partial class C1 - { - public partial void PartialM(int v); - } - } - - - namespace N1 - { - partial class C1 - { - public partial void PartialM(int v) { } - void M1() - { - PartialM(1); - } - } - } - - - - """; - await TestInRegularAndScriptAsync(code, fix0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_PartialMethodsInSameDocument() - { - var code = - """ - namespace N1 - { - partial class C1 - { - partial void PartialM(); - } - partial class C1 - { - partial void PartialM() { } - void M1() - { - [|PartialM|](1); - } - } - } - """; - var fix0 = - """ - namespace N1 - { - partial class C1 - { - partial void PartialM(int v); - } - partial class C1 - { - partial void PartialM(int v) { } - void M1() - { - PartialM(1); - } - } - } - """; - await TestInRegularAndScriptAsync(code, fix0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_BaseNotInSource() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - - - - - namespace N - { - public class BaseClass - { - public virtual void M() { } - } - } - - - - namespace N - { - public class Derived: BaseClass - { - public void M2() - { - [|M|](1); - } - } - } - - - - """; - await TestMissingAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_RootNotInSource() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - - - - namespace N - { - public class BaseClass - { - public virtual void M() { } - } - } - - namespace N - { - public class Derived: BaseClass - { - public override void M() { } - } - public class DerivedDerived: Derived - { - public void M2() - { - [|M|](1); - } - } - } - - - """; - var fixedDocumentWithoutConflictAnnotation = """ - namespace N - { - public class Derived: BaseClass - { - public override void M(int v) { } - } - public class DerivedDerived: Derived - { - public void M2() - { - M(1); - } - } - } - """; - var fixedDocumentWithConflictAnnotation = """ - namespace N - { - public class Derived: BaseClass - { - public override void M({|Conflict:int v|}) { } - } - public class DerivedDerived: Derived - { - public void M2() - { - M(1); - } - } - } - """; - await TestInRegularAndScriptAsync(code, fixedDocumentWithoutConflictAnnotation, index: 0); - await TestInRegularAndScriptAsync(code, fixedDocumentWithConflictAnnotation, index: 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_ManyReferencesInManyProjects() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - - - - namespace N - { - public class BaseClass - { - public virtual void M() { } - } - } - - - - A1 - - namespace N - { - public class Derived1: BaseClass - { - public override void M() { } - } - } - - - - A1 - - namespace N - { - public class Derived2: BaseClass - { - public override void M() { } - } - } - - - - A3 - - namespace N - { - public class T - { - public void Test() { - new Derived2().[|M|](1); - } - } - } - - - - """; - var fix_All = - """ - - - - namespace N - { - public class BaseClass - { - public virtual void M(int v) { } - } - } - - - - A1 - - namespace N - { - public class Derived1: BaseClass - { - public override void M(int v) { } - } - } - - - - A1 - - namespace N - { - public class Derived2: BaseClass - { - public override void M(int v) { } - } - } - - - - A3 - - namespace N - { - public class T - { - public void Test() { - new Derived2().M(1); - } - } - } - - - - """; - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_OfferFixCascadingForImplicitInterface() - { - // error CS1501: No overload for method 'M1' takes 1 arguments - var code = - """ - interface I1 - { - void M1(); - } - class C: I1 - { - public void M1() { } - void MTest() - { - [|M1|](1); - } - } - """; - var fix_DeclarationOnly = - """ - interface I1 - { - void M1(); - } - class C: I1 - { - public void M1(int v) { } - void MTest() - { - M1(1); - } - } - """; - var fix_All = - """ - interface I1 - { - void M1(int v); - } - class C: I1 - { - public void M1(int v) { } - void MTest() - { - M1(1); - } - } - """; - await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); - await TestInRegularAndScriptAsync(code, fix_All, index: 1); - } - -#if !CODE_STYLE - - // CodeStyle layer does not support cross language application of fixes. - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Cascading_CrossLanguage() - { - var code = - """ - - - - Namespace N - Public Class BaseClass - Public Overridable Sub M() - End Sub - End Class - End Namespace - - - - VB1 - - namespace N - { - public class Derived: BaseClass - { - public override void M() { } - } - public class T - { - public void Test() { - new Derived().[|M|](1); - } - } - } - - - - """; - var fix = - """ - - - - Namespace N - Public Class BaseClass - Public Overridable Sub M(v As Integer) - End Sub - End Class - End Namespace - - - - VB1 - - namespace N - { - public class Derived: BaseClass - { - public override void M(int v) { } - } - public class T - { - public void Test() { - new Derived().M(1); - } - } - } - - - - """; - await TestInRegularAndScriptAsync(code, fix, index: 1); - } - -#endif - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Positional_MoreThanOneArgumentToMuch() - { - var code = - """ - class C - { - void M() { } - void Test() - { - [|M|](1, 2, 3, 4); - } - } - """; - var fix0 = - """ - class C - { - void M(int v) { } - void Test() - { - M(1, 2, 3, 4); - } - } - """; - await TestActionCountAsync(code, 1); - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Positional_WithOptionalParam() - { - // error CS1501: No overload for method 'M' takes 2 arguments - var code = - """ - class C - { - void M(int i = 1) { } - void Test() - { - [|M|](1, 2); - } - } - """; - var fix0 = - """ - class C - { - void M(int i = 1, int v = 0) { } - void Test() - { - M(1, 2); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Named_WithOptionalParam() - { - // error CS1739: The best overload for 'M' does not have a parameter named 'i3' - var code = - """ - class C - { - void M(int i1, int i2 = 1) { } - void Test() - { - M(1, i2: 2, [|i3|]: 3); - } - } - """; - var fix0 = - """ - class C - { - void M(int i1, int i2 = 1, int i3 = 0) { } - void Test() - { - M(1, i2: 2, i3: 3); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Positional_WithParams() - { - // error CS1503: Argument 1: cannot convert from 'string' to 'int' - var code = - """ - class C - { - void M(params int[] ints) { } - void Test() - { - M([|"text"|]); - } - } - """; - var fix0 = - """ - class C - { - void M(string v, params int[] ints) { } - void Test() - { - M("text"); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Named_WithTypemissmatch() - { - // error CS1503: Argument 1: cannot convert from 'string' to 'int' - var code = - """ - class C - { - void M(int i) { } - void Test() - { - M(i: [|"text"|]); - } - } - """; - await TestMissingInRegularAndScriptAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_NamedAndPositional1() - { - // error CS1739: The best overload for 'M' does not have a parameter named 'i2' - var code = - """ - class C - { - void M(int i1, string s) { } - void Test() - { - M(1, s: "text", [|i2|]: 0); - } - } - """; - var fix0 = - """ - class C - { - void M(int i1, string s, int i2) { } - void Test() - { - M(1, s: "text", i2: 0); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_NamedAndPositional2() - { - // CS1744 is not yet a supported diagnostic (just declaring the diagnostic as supported does not work) - // error CS1744: Named argument 's' specifies a parameter for which a positional argument has already been given - var code = - """ - class C - { - void M(string s) { } - void Test() - { - M(1, [|s|]: "text"); - } - } - """; - await TestMissingInRegularAndScriptAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Incomplete_1() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - class C - { - void M() { } - void Test() - { - [|M|](1 - } - } - """; - var fix0 = - """ - class C - { - void M(int v) { } - void Test() - { - M(1 - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_Incomplete_2() - { - // error CS1503: Argument 1: cannot convert from 'string' to 'int' - var code = - """ - class C - { - void M(int v) { } - void Test() - { - [|M|]("text", 1 - """; - var fix0 = - """ - class C - { - void M(string v1, int v) { } - void Test() - { - M("text", 1 - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_RefParameter() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - class C - { - void M() { } - void Test() - { - int i = 0; - [|M|](ref i); - } - } - """; - var fix0 = - """ - class C - { - void M(ref int i) { } - void Test() - { - int i = 0; - M(ref i); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_OutParameter_WithTypeDeclarationOutsideArgument() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - class C - { - void M() { } - void Test() - { - int i = 0; - [|M|](out i); - } - } - """; - var fix0 = - """ - class C - { - void M(out int i) { } - void Test() - { - int i = 0; - M(out i); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_OutParameter_WithTypeDeclarationInArgument() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - class C - { - void M() { } - void Test() - { - [|M|](out int i); - } - } - """; - var fix0 = - """ - class C - { - void M(out int i) { } - void Test() - { - M(out int i); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_InvocationStyles_OutParameter_WithVarTypeDeclarationInArgument() - { - // error CS1501: No overload for method 'M' takes 1 arguments - var code = - """ - class C - { - void M() { } - void Test() - { - [|M|](out var i); - } - } - """; - var fix0 = - """ - class C - { - void M(out object i) { } - void Test() - { - M(out var i); - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] - public async Task TestInvocation_Indexer_NotSupported() - { - // Could be fixed by allowing ElementAccessExpression next to InvocationExpression - // in AbstractAddParameterCodeFixProvider.RegisterCodeFixesAsync. - // error CS1501: No overload for method 'this' takes 2 arguments - var code = - """ - public class C { - public int this[int i] - { - get => 1; - set {} - } - - public void Test() { - var i = [|this[0,0]|]; - } - } - """; - await TestMissingAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")] - public async Task TestThis_DoNotOfferToFixTheConstructorWithTheDiagnosticOnIt() - { - // error CS1729: 'C' does not contain a constructor that takes 1 arguments - var code = - """ - public class C { - - public C(): [|this|](1) - { } - } - """; - await TestMissingAsync(code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")] - public async Task TestThis_Fix_IfACandidateIsAvailable() - { - // error CS1729: 'C' does not contain a constructor that takes 2 arguments - var code = - """ - class C - { - public C(int i) { } - - public C(): [|this|](1, 1) - { } - } - """; - var fix0 = - """ - class C - { - public C(int i, int v) { } - - public C(): this(1, 1) - { } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - await TestActionCountAsync(code, 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")] - public async Task TestBase_Fix_IfACandidateIsAvailable() - { - // error CS1729: 'B' does not contain a constructor that takes 1 arguments - var code = - """ - public class B - { - B() { } - } - public class C : B - { - public C(int i) : [|base|](i) { } - } - """; - var fix0 = - """ - public class B - { - B(int i) { } - } - public class C : B - { - public C(int i) : base(i) { } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - await TestActionCountAsync(code, 1); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29753")] - public async Task LocalFunction_AddParameterToLocalFunctionWithOneParameter() - { - // CS1501 No overload for method takes 2 arguments - var code = - """ - class Rsrp - { - public void M() - { - [|Local|]("ignore this", true); - void Local(string whatever) - { - - } - } - } - """; - var fix0 = - """ - class Rsrp - { - public void M() - { - Local("ignore this", true); - void Local(string whatever, bool v) - { - - } - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29752")] - public async Task LocalFunction_AddNamedParameterToLocalFunctionWithOneParameter() - { - // CS1739: The best overload for 'Local' does not have a parameter named 'mynewparameter' - var code = - """ - class Rsrp - { - public void M() - { - Local("ignore this", [|mynewparameter|]: true); - void Local(string whatever) - { - - } - } - } - """; - var fix0 = - """ - class Rsrp - { - public void M() - { - Local("ignore this", mynewparameter: true); - void Local(string whatever, bool mynewparameter) - { + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_ExisitingTypeArgumentIsNotGeneralized() + { + var code = + """ + class C1 + { + void M1(T v) { } + void M2() + { + [|M1|](true, true); + } + } + """; + var fix0 = + """ + class C1 + { + void M1(T v, bool v1) { } + void M2() + { + M1(true, true); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0); + } - } - } - } - """; - await TestInRegularAndScriptAsync(code, fix0, index: 0); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_AddParameterToMethodWithParams() + { + // error CS1503: Argument 1: cannot convert from 'bool' to 'int' + var code = + """ + class C1 + { + static void M1(params int[] nums) { } + static void M2() + { + M1([|true|], 4); + } + } + """; + var fix0 = + """ + class C1 + { + static void M1(bool v, params int[] nums) { } + static void M2() + { + M1(true, 4); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39270")] - public async Task TestWithArgThatHasImplicitConversionToParamType1() - { - await TestInRegularAndScriptAsync( - """ - class BaseClass { } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_FixingVirtualFixesOverrideToo() + { + // error CS1501: No overload for method 'M1' takes 1 arguments + var code = + """ + class BaseClass + { + protected virtual void M1() { } + } + class Derived1: BaseClass + { + protected override void M1() { } + } + class Test: BaseClass + { + void M2() + { + [|M1|](1); + } + } + """; + var fix_DeclarationOnly = + """ + class BaseClass + { + protected virtual void M1(int v) { } + } + class Derived1: BaseClass + { + protected override void M1() { } + } + class Test: BaseClass + { + void M2() + { + M1(1); + } + } + """; + var fix_All = + """ + class BaseClass + { + protected virtual void M1(int v) { } + } + class Derived1: BaseClass + { + protected override void M1(int v) { } + } + class Test: BaseClass + { + void M2() + { + M1(1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } - class MyClass : BaseClass - { - void TestFunc() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_PartialMethods() + { + var code = + """ + + + + namespace N1 + { + partial class C1 + { + partial void PartialM(); + } + } + + + namespace N1 + { + partial class C1 + { + partial void PartialM() { } + void M1() { - MyClass param1 = new MyClass(); - int newparam = 1; - - [|MyFunc|](param1, newparam); + [|PartialM|](1); + } + } + } + + + + """; + var fix0 = + """ + + + + namespace N1 + { + partial class C1 + { + partial void PartialM(int v); + } + } + + + namespace N1 + { + partial class C1 + { + partial void PartialM(int v) { } + void M1() + { + PartialM(1); } - - void MyFunc(BaseClass param1) { } } - """, - """ - class BaseClass { } + } + + + + """; + await TestInRegularAndScriptAsync(code, fix0); + } - class MyClass : BaseClass - { - void TestFunc() + [Fact] + public async Task TestInvocation_Cascading_ExtendedPartialMethods() + { + var code = + """ + + + + namespace N1 + { + partial class C1 + { + public partial void PartialM(); + } + } + + + namespace N1 + { + partial class C1 + { + public partial void PartialM() { } + void M1() { - MyClass param1 = new MyClass(); - int newparam = 1; - - MyFunc(param1, newparam); + [|PartialM|](1); + } + } + } + + + + """; + var fix0 = + """ + + + + namespace N1 + { + partial class C1 + { + public partial void PartialM(int v); + } + } + + + namespace N1 + { + partial class C1 + { + public partial void PartialM(int v) { } + void M1() + { + PartialM(1); } - - void MyFunc(BaseClass param1, int newparam) { } } - """); - } + } + + + + """; + await TestInRegularAndScriptAsync(code, fix0); + } - [Fact] - public async Task TestOnExtensionGetEnumerator() - { - var code = - """ - using System.Collections.Generic; - namespace N { - static class Extensions + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_PartialMethodsInSameDocument() + { + var code = + """ + namespace N1 + { + partial class C1 { - public static IEnumerator GetEnumerator(this object o) - { - } + partial void PartialM(); } - class C1 + partial class C1 { + partial void PartialM() { } void M1() { - new object().[|GetEnumerator|](1); - foreach (var a in new object()); - } - }} - """; - var fix = - """ - using System.Collections.Generic; - namespace N { - static class Extensions - { - public static IEnumerator GetEnumerator(this object o, int v) - { + [|PartialM|](1); } } - class C1 + } + """; + var fix0 = + """ + namespace N1 + { + partial class C1 + { + partial void PartialM(int v); + } + partial class C1 { + partial void PartialM(int v) { } void M1() { - new object().GetEnumerator(1); - foreach (var a in new object()); - } - }} - """; - await TestInRegularAndScriptAsync(code, fix); - } - - [Fact] - public async Task TestOnExtensionGetAsyncEnumerator() - { - var code = - """ - using System.Collections.Generic; - using System.Threading.Tasks; - namespace N { - static class Extensions - { - public static IAsyncEnumerator GetAsyncEnumerator(this object o) - { + PartialM(1); } } - class C1 + } + """; + await TestInRegularAndScriptAsync(code, fix0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_BaseNotInSource() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + + + + + namespace N + { + public class BaseClass { - async Task M1() - { - new object().[|GetAsyncEnumerator|](1); - await foreach (var a in new object()); - } - }} - """ + IAsyncEnumerable; - var fix = - """ - using System.Collections.Generic; - using System.Threading.Tasks; - namespace N { - static class Extensions - { - public static IAsyncEnumerator GetAsyncEnumerator(this object o, int v) - { - } + public virtual void M() { } } - class C1 + } + + + + namespace N + { + public class Derived: BaseClass { - async Task M1() + public void M2() { - new object().GetAsyncEnumerator(1); - await foreach (var a in new object()); + [|M|](1); } - }} - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(code, fix); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44271")] - public async Task TopLevelStatement() - { - await TestInRegularAndScriptAsync(""" - [|local|](1, 2, 3); + } + } + + + + """; + await TestMissingAsync(code); + } - void local(int x, int y) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_RootNotInSource() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + + + + namespace N + { + public class BaseClass { + public virtual void M() { } } - """, - """ - [|local|](1, 2, 3); - - void local(int x, int y, int v) + } + + namespace N + { + public class Derived: BaseClass { + public override void M() { } } - """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44271")] - public async Task TopLevelStatement_Nested() - { - await TestInRegularAndScriptAsync(""" - void outer() + public class DerivedDerived: Derived { - [|local|](1, 2, 3); - - void local(int x, int y) + public void M2() { + [|M|](1); } } - """, - """ - void outer() + } + + + """; + var fixedDocumentWithoutConflictAnnotation = """ + namespace N + { + public class Derived: BaseClass { - local(1, 2, 3); - - void local(int x, int y, int v) - { - } + public override void M(int v) { } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42559")] - public async Task TestAddParameter_ImplicitObjectCreation() - { - await TestInRegularAndScriptAsync(""" - class C + public class DerivedDerived: Derived { - C(int i) { } - - void M() + public void M2() { - C c = [||]new(1, 2); + M(1); } } - """, - """ - class C + } + """; + var fixedDocumentWithConflictAnnotation = """ + namespace N + { + public class Derived: BaseClass { - C(int i, int v) { } - - void M() + public override void M({|Conflict:int v|}) { } + } + public class DerivedDerived: Derived + { + public void M2() { - C c = new(1, 2); + M(1); } } - """); - } + } + """; + await TestInRegularAndScriptAsync(code, fixedDocumentWithoutConflictAnnotation, index: 0); + await TestInRegularAndScriptAsync(code, fixedDocumentWithConflictAnnotation, index: 1); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48042")] - public async Task TestNamedArgOnExtensionMethod() - { - await TestInRegularAndScriptAsync( - """ - namespace r - { - static class AbcExtensions + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_ManyReferencesInManyProjects() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + + + + namespace N + { + public class BaseClass + { + public virtual void M() { } + } + } + + + + A1 + + namespace N + { + public class Derived1: BaseClass + { + public override void M() { } + } + } + + + + A1 + + namespace N + { + public class Derived2: BaseClass + { + public override void M() { } + } + } + + + + A3 + + namespace N + { + public class T + { + public void Test() { + new Derived2().[|M|](1); + } + } + } + + + + """; + var fix_All = + """ + + + + namespace N + { + public class BaseClass + { + public virtual void M(int v) { } + } + } + + + + A1 + + namespace N + { + public class Derived1: BaseClass + { + public override void M(int v) { } + } + } + + + + A1 + + namespace N + { + public class Derived2: BaseClass + { + public override void M(int v) { } + } + } + + + + A3 + + namespace N + { + public class T + { + public void Test() { + new Derived2().M(1); + } + } + } + + + + """; + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_OfferFixCascadingForImplicitInterface() + { + // error CS1501: No overload for method 'M1' takes 1 arguments + var code = + """ + interface I1 + { + void M1(); + } + class C: I1 + { + public void M1() { } + void MTest() + { + [|M1|](1); + } + } + """; + var fix_DeclarationOnly = + """ + interface I1 + { + void M1(); + } + class C: I1 + { + public void M1(int v) { } + void MTest() + { + M1(1); + } + } + """; + var fix_All = + """ + interface I1 + { + void M1(int v); + } + class C: I1 + { + public void M1(int v) { } + void MTest() + { + M1(1); + } + } + """; + await TestInRegularAndScriptAsync(code, fix_DeclarationOnly, index: 0); + await TestInRegularAndScriptAsync(code, fix_All, index: 1); + } + +#if !CODE_STYLE + + // CodeStyle layer does not support cross language application of fixes. + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Cascading_CrossLanguage() + { + var code = + """ + + + + Namespace N + Public Class BaseClass + Public Overridable Sub M() + End Sub + End Class + End Namespace + + + + VB1 + + namespace N + { + public class Derived: BaseClass + { + public override void M() { } + } + public class T + { + public void Test() { + new Derived().[|M|](1); + } + } + } + + + + """; + var fix = + """ + + + + Namespace N + Public Class BaseClass + Public Overridable Sub M(v As Integer) + End Sub + End Class + End Namespace + + + + VB1 + + namespace N + { + public class Derived: BaseClass + { + public override void M(int v) { } + } + public class T + { + public void Test() { + new Derived().M(1); + } + } + } + + + + """; + await TestInRegularAndScriptAsync(code, fix, index: 1); + } + +#endif + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Positional_MoreThanOneArgumentToMuch() + { + var code = + """ + class C + { + void M() { } + void Test() + { + [|M|](1, 2, 3, 4); + } + } + """; + var fix0 = + """ + class C + { + void M(int v) { } + void Test() + { + M(1, 2, 3, 4); + } + } + """; + await TestActionCountAsync(code, 1); + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Positional_WithOptionalParam() + { + // error CS1501: No overload for method 'M' takes 2 arguments + var code = + """ + class C + { + void M(int i = 1) { } + void Test() + { + [|M|](1, 2); + } + } + """; + var fix0 = + """ + class C + { + void M(int i = 1, int v = 0) { } + void Test() + { + M(1, 2); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Named_WithOptionalParam() + { + // error CS1739: The best overload for 'M' does not have a parameter named 'i3' + var code = + """ + class C + { + void M(int i1, int i2 = 1) { } + void Test() + { + M(1, i2: 2, [|i3|]: 3); + } + } + """; + var fix0 = + """ + class C + { + void M(int i1, int i2 = 1, int i3 = 0) { } + void Test() + { + M(1, i2: 2, i3: 3); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Positional_WithParams() + { + // error CS1503: Argument 1: cannot convert from 'string' to 'int' + var code = + """ + class C + { + void M(params int[] ints) { } + void Test() + { + M([|"text"|]); + } + } + """; + var fix0 = + """ + class C + { + void M(string v, params int[] ints) { } + void Test() + { + M("text"); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Named_WithTypemissmatch() + { + // error CS1503: Argument 1: cannot convert from 'string' to 'int' + var code = + """ + class C + { + void M(int i) { } + void Test() + { + M(i: [|"text"|]); + } + } + """; + await TestMissingInRegularAndScriptAsync(code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_NamedAndPositional1() + { + // error CS1739: The best overload for 'M' does not have a parameter named 'i2' + var code = + """ + class C + { + void M(int i1, string s) { } + void Test() + { + M(1, s: "text", [|i2|]: 0); + } + } + """; + var fix0 = + """ + class C + { + void M(int i1, string s, int i2) { } + void Test() + { + M(1, s: "text", i2: 0); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_NamedAndPositional2() + { + // CS1744 is not yet a supported diagnostic (just declaring the diagnostic as supported does not work) + // error CS1744: Named argument 's' specifies a parameter for which a positional argument has already been given + var code = + """ + class C + { + void M(string s) { } + void Test() + { + M(1, [|s|]: "text"); + } + } + """; + await TestMissingInRegularAndScriptAsync(code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Incomplete_1() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + class C + { + void M() { } + void Test() + { + [|M|](1 + } + } + """; + var fix0 = + """ + class C + { + void M(int v) { } + void Test() + { + M(1 + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_Incomplete_2() + { + // error CS1503: Argument 1: cannot convert from 'string' to 'int' + var code = + """ + class C + { + void M(int v) { } + void Test() + { + [|M|]("text", 1 + """; + var fix0 = + """ + class C + { + void M(string v1, int v) { } + void Test() + { + M("text", 1 + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_RefParameter() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + class C + { + void M() { } + void Test() + { + int i = 0; + [|M|](ref i); + } + } + """; + var fix0 = + """ + class C + { + void M(ref int i) { } + void Test() + { + int i = 0; + M(ref i); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_OutParameter_WithTypeDeclarationOutsideArgument() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + class C + { + void M() { } + void Test() + { + int i = 0; + [|M|](out i); + } + } + """; + var fix0 = + """ + class C + { + void M(out int i) { } + void Test() + { + int i = 0; + M(out i); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_OutParameter_WithTypeDeclarationInArgument() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + class C + { + void M() { } + void Test() + { + [|M|](out int i); + } + } + """; + var fix0 = + """ + class C + { + void M(out int i) { } + void Test() + { + M(out int i); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_InvocationStyles_OutParameter_WithVarTypeDeclarationInArgument() + { + // error CS1501: No overload for method 'M' takes 1 arguments + var code = + """ + class C + { + void M() { } + void Test() + { + [|M|](out var i); + } + } + """; + var fix0 = + """ + class C + { + void M(out object i) { } + void Test() + { + M(out var i); + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21446")] + public async Task TestInvocation_Indexer_NotSupported() + { + // Could be fixed by allowing ElementAccessExpression next to InvocationExpression + // in AbstractAddParameterCodeFixProvider.RegisterCodeFixesAsync. + // error CS1501: No overload for method 'this' takes 2 arguments + var code = + """ + public class C { + public int this[int i] + { + get => 1; + set {} + } + + public void Test() { + var i = [|this[0,0]|]; + } + } + """; + await TestMissingAsync(code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")] + public async Task TestThis_DoNotOfferToFixTheConstructorWithTheDiagnosticOnIt() + { + // error CS1729: 'C' does not contain a constructor that takes 1 arguments + var code = + """ + public class C { + + public C(): [|this|](1) + { } + } + """; + await TestMissingAsync(code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")] + public async Task TestThis_Fix_IfACandidateIsAvailable() + { + // error CS1729: 'C' does not contain a constructor that takes 2 arguments + var code = + """ + class C + { + public C(int i) { } + + public C(): [|this|](1, 1) + { } + } + """; + var fix0 = + """ + class C + { + public C(int i, int v) { } + + public C(): this(1, 1) + { } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + await TestActionCountAsync(code, 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29061")] + public async Task TestBase_Fix_IfACandidateIsAvailable() + { + // error CS1729: 'B' does not contain a constructor that takes 1 arguments + var code = + """ + public class B + { + B() { } + } + public class C : B + { + public C(int i) : [|base|](i) { } + } + """; + var fix0 = + """ + public class B + { + B(int i) { } + } + public class C : B + { + public C(int i) : base(i) { } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + await TestActionCountAsync(code, 1); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29753")] + public async Task LocalFunction_AddParameterToLocalFunctionWithOneParameter() + { + // CS1501 No overload for method takes 2 arguments + var code = + """ + class Rsrp + { + public void M() + { + [|Local|]("ignore this", true); + void Local(string whatever) + { + + } + } + } + """; + var fix0 = + """ + class Rsrp + { + public void M() + { + Local("ignore this", true); + void Local(string whatever, bool v) + { + + } + } + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29752")] + public async Task LocalFunction_AddNamedParameterToLocalFunctionWithOneParameter() + { + // CS1739: The best overload for 'Local' does not have a parameter named 'mynewparameter' + var code = + """ + class Rsrp + { + public void M() + { + Local("ignore this", [|mynewparameter|]: true); + void Local(string whatever) { - public static Abc Act(this Abc state, bool p = true) => state; - } - class Abc { - void Test() - => new Abc().Act([|param3|]: 123); + } } - """, - """ - namespace r + } + """; + var fix0 = + """ + class Rsrp + { + public void M() { - static class AbcExtensions + Local("ignore this", mynewparameter: true); + void Local(string whatever, bool mynewparameter) { - public static Abc Act(this Abc state, bool p = true, int param3 = 0) => state; - } - class Abc { - void Test() - => new Abc().Act(param3: 123); + } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54408")] - public async Task TestPositionalRecord() - { - await TestInRegularAndScriptAsync(""" - var b = "B"; - var r = [|new R(1, b)|]; + } + """; + await TestInRegularAndScriptAsync(code, fix0, index: 0); + } - record R(int A); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39270")] + public async Task TestWithArgThatHasImplicitConversionToParamType1() + { + await TestInRegularAndScriptAsync( + """ + class BaseClass { } - namespace System.Runtime.CompilerServices + class MyClass : BaseClass + { + void TestFunc() { - public static class IsExternalInit { } + MyClass param1 = new MyClass(); + int newparam = 1; + + [|MyFunc|](param1, newparam); } - """, """ - var b = "B"; - var r = new R(1, b); - record R(int A, string b); + void MyFunc(BaseClass param1) { } + } + """, + """ + class BaseClass { } - namespace System.Runtime.CompilerServices + class MyClass : BaseClass + { + void TestFunc() { - public static class IsExternalInit { } + MyClass param1 = new MyClass(); + int newparam = 1; + + MyFunc(param1, newparam); } - """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); - } - [Fact] - public async Task Test_PrimaryConstructor_Class() - { - await TestInRegularAndScriptAsync(""" - var b = "B"; - var r = [|new R(1, b)|]; + void MyFunc(BaseClass param1, int newparam) { } + } + """); + } + + [Fact] + public async Task TestOnExtensionGetEnumerator() + { + var code = + """ + using System.Collections.Generic; + namespace N { + static class Extensions + { + public static IEnumerator GetEnumerator(this object o) + { + } + } + class C1 + { + void M1() + { + new object().[|GetEnumerator|](1); + foreach (var a in new object()); + } + }} + """; + var fix = + """ + using System.Collections.Generic; + namespace N { + static class Extensions + { + public static IEnumerator GetEnumerator(this object o, int v) + { + } + } + class C1 + { + void M1() + { + new object().GetEnumerator(1); + foreach (var a in new object()); + } + }} + """; + await TestInRegularAndScriptAsync(code, fix); + } + + [Fact] + public async Task TestOnExtensionGetAsyncEnumerator() + { + var code = + """ + using System.Collections.Generic; + using System.Threading.Tasks; + namespace N { + static class Extensions + { + public static IAsyncEnumerator GetAsyncEnumerator(this object o) + { + } + } + class C1 + { + async Task M1() + { + new object().[|GetAsyncEnumerator|](1); + await foreach (var a in new object()); + } + }} + """ + IAsyncEnumerable; + var fix = + """ + using System.Collections.Generic; + using System.Threading.Tasks; + namespace N { + static class Extensions + { + public static IAsyncEnumerator GetAsyncEnumerator(this object o, int v) + { + } + } + class C1 + { + async Task M1() + { + new object().GetAsyncEnumerator(1); + await foreach (var a in new object()); + } + }} + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(code, fix); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44271")] + public async Task TopLevelStatement() + { + await TestInRegularAndScriptAsync(""" + [|local|](1, 2, 3); + + void local(int x, int y) + { + } + """, + """ + [|local|](1, 2, 3); + + void local(int x, int y, int v) + { + } + """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); + } - class R(int A); - """, """ - var b = "B"; - var r = new R(1, b); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44271")] + public async Task TopLevelStatement_Nested() + { + await TestInRegularAndScriptAsync(""" + void outer() + { + [|local|](1, 2, 3); - class R(int A, string b); - """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp12)); - } + void local(int x, int y) + { + } + } + """, + """ + void outer() + { + local(1, 2, 3); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54408")] - public async Task TestPositionalRecordStruct() - { - await TestInRegularAndScriptAsync(""" - var b = "B"; - var r = [|new R(1, b)|]; + void local(int x, int y, int v) + { + } + } + """); + } - record struct R(int A); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42559")] + public async Task TestAddParameter_ImplicitObjectCreation() + { + await TestInRegularAndScriptAsync(""" + class C + { + C(int i) { } - namespace System.Runtime.CompilerServices + void M() { - public static class IsExternalInit { } + C c = [||]new(1, 2); } - """, """ - var b = "B"; - var r = new R(1, b); + } + """, + """ + class C + { + C(int i, int v) { } - record struct R(int A, string b); + void M() + { + C c = new(1, 2); + } + } + """); + } - namespace System.Runtime.CompilerServices + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48042")] + public async Task TestNamedArgOnExtensionMethod() + { + await TestInRegularAndScriptAsync( + """ + namespace r + { + static class AbcExtensions + { + public static Abc Act(this Abc state, bool p = true) => state; + } + class Abc { + void Test() + => new Abc().Act([|param3|]: 123); + } + } + """, + """ + namespace r + { + static class AbcExtensions { - public static class IsExternalInit { } + public static Abc Act(this Abc state, bool p = true, int param3 = 0) => state; + } + class Abc { + void Test() + => new Abc().Act(param3: 123); } - """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54408")] + public async Task TestPositionalRecord() + { + await TestInRegularAndScriptAsync(""" + var b = "B"; + var r = [|new R(1, b)|]; + + record R(int A); + + namespace System.Runtime.CompilerServices + { + public static class IsExternalInit { } + } + """, """ + var b = "B"; + var r = new R(1, b); + + record R(int A, string b); + + namespace System.Runtime.CompilerServices + { + public static class IsExternalInit { } + } + """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); + } + + [Fact] + public async Task Test_PrimaryConstructor_Class() + { + await TestInRegularAndScriptAsync(""" + var b = "B"; + var r = [|new R(1, b)|]; + + class R(int A); + """, """ + var b = "B"; + var r = new R(1, b); - [Fact] - public async Task Test_PrimaryConstructor_Struct() - { - await TestInRegularAndScriptAsync(""" - var b = "B"; - var r = [|new R(1, b)|]; + class R(int A, string b); + """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp12)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54408")] + public async Task TestPositionalRecordStruct() + { + await TestInRegularAndScriptAsync(""" + var b = "B"; + var r = [|new R(1, b)|]; + + record struct R(int A); + + namespace System.Runtime.CompilerServices + { + public static class IsExternalInit { } + } + """, """ + var b = "B"; + var r = new R(1, b); + + record struct R(int A, string b); + + namespace System.Runtime.CompilerServices + { + public static class IsExternalInit { } + } + """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); + } - struct R(int A); - """, """ - var b = "B"; - var r = new R(1, b); + [Fact] + public async Task Test_PrimaryConstructor_Struct() + { + await TestInRegularAndScriptAsync(""" + var b = "B"; + var r = [|new R(1, b)|]; + + struct R(int A); + """, """ + var b = "B"; + var r = new R(1, b); - struct R(int A, string b); - """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp12)); - } + struct R(int A, string b); + """, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp12)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56952")] - public async Task TestRecordsNamingConventions() - { - await TestInRegularAndScript1Async(""" - [|new Test("repro")|]; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56952")] + public async Task TestRecordsNamingConventions() + { + await TestInRegularAndScript1Async(""" + [|new Test("repro")|]; - record Test(); + record Test(); - """, """ - new Test("repro"); + """, """ + new Test("repro"); - record Test(string V); + record Test(string V); - """); - } + """); + } - [Fact] - public async Task TestNamingConventions_PrimaryConstructor_Class() - { - await TestInRegularAndScript1Async(""" - [|new Test("repro")|]; + [Fact] + public async Task TestNamingConventions_PrimaryConstructor_Class() + { + await TestInRegularAndScript1Async(""" + [|new Test("repro")|]; - class Test(); - """, """ - new Test("repro"); + class Test(); + """, """ + new Test("repro"); - class Test(string v); - """); - } + class Test(string v); + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56952")] - public async Task TestRecordsNamingConventions_RecordStruct() - { - await TestInRegularAndScript1Async(""" - [|new Test("repro")|]; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56952")] + public async Task TestRecordsNamingConventions_RecordStruct() + { + await TestInRegularAndScript1Async(""" + [|new Test("repro")|]; - record struct Test(); + record struct Test(); - """, """ - new Test("repro"); + """, """ + new Test("repro"); - record struct Test(string V); + record struct Test(string V); - """); - } + """); + } - [Fact] - public async Task TestNamingConventions_PrimaryConstructor_Struct() - { - await TestInRegularAndScript1Async(""" - [|new Test("repro")|]; + [Fact] + public async Task TestNamingConventions_PrimaryConstructor_Struct() + { + await TestInRegularAndScript1Async(""" + [|new Test("repro")|]; - struct Test(); - """, """ - new Test("repro"); + struct Test(); + """, """ + new Test("repro"); - struct Test(string v); - """); - } + struct Test(string v); + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")] - public async Task TestMethodGroup1() - { - await TestInRegularAndScript1Async(""" - public class Example + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")] + public async Task TestMethodGroup1() + { + await TestInRegularAndScript1Async(""" + public class Example + { + public void Add(int x) { - public void Add(int x) - { - } + } - public void DoSomething() - { - } + public void DoSomething() + { + } - public void Main() - { - [|DoSomething|](Add); - } + public void Main() + { + [|DoSomething|](Add); } - """, """ - public class Example + } + """, """ + public class Example + { + public void Add(int x) { - public void Add(int x) - { - } + } - public void DoSomething(System.Action add) - { - } + public void DoSomething(System.Action add) + { + } - public void Main() - { - DoSomething(Add); - } + public void Main() + { + DoSomething(Add); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")] - public async Task TestMethodGroup2() - { - await TestInRegularAndScript1Async(""" - public class Example + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")] + public async Task TestMethodGroup2() + { + await TestInRegularAndScript1Async(""" + public class Example + { + public void Add(int x, string y) { - public void Add(int x, string y) - { - } + } - public void DoSomething() - { - } + public void DoSomething() + { + } - public void Main() - { - [|DoSomething|](Add); - } + public void Main() + { + [|DoSomething|](Add); } - """, """ - public class Example + } + """, """ + public class Example + { + public void Add(int x, string y) { - public void Add(int x, string y) - { - } + } - public void DoSomething(System.Action add) - { - } + public void DoSomething(System.Action add) + { + } - public void Main() - { - DoSomething(Add); - } + public void Main() + { + DoSomething(Add); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")] - public async Task TestMethodGroup3() - { - await TestInRegularAndScript1Async(""" - public class Example + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61715")] + public async Task TestMethodGroup3() + { + await TestInRegularAndScript1Async(""" + public class Example + { + public int Add(int x, string y) { - public int Add(int x, string y) - { - return 0; - } + return 0; + } - public void DoSomething() - { - } + public void DoSomething() + { + } - public void Main() - { - [|DoSomething|](Add); - } + public void Main() + { + [|DoSomething|](Add); } - """, """ - public class Example + } + """, """ + public class Example + { + public int Add(int x, string y) { - public int Add(int x, string y) - { - return 0; - } + return 0; + } - public void DoSomething(System.Func add) - { - } + public void DoSomething(System.Func add) + { + } - public void Main() - { - DoSomething(Add); - } + public void Main() + { + DoSomething(Add); } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredExpressionParenthesesTests.cs b/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredExpressionParenthesesTests.cs index 7cadbd077321e..de3adf61859bd 100644 --- a/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredExpressionParenthesesTests.cs +++ b/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredExpressionParenthesesTests.cs @@ -15,835 +15,834 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddRequiredParentheses +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddRequiredParentheses; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddRequiredParentheses)] +public partial class AddRequiredExpressionParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddRequiredParentheses)] - public partial class AddRequiredExpressionParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddRequiredExpressionParenthesesTests(ITestOutputHelper logger) + : base(logger) { - public AddRequiredExpressionParenthesesTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpAddRequiredExpressionParenthesesDiagnosticAnalyzer(), new AddRequiredParenthesesCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpAddRequiredExpressionParenthesesDiagnosticAnalyzer(), new AddRequiredParenthesesCodeFixProvider()); - private Task TestMissingAsync(string initialMarkup, OptionsCollection options) - => TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options)); + private Task TestMissingAsync(string initialMarkup, OptionsCollection options) + => TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options)); - private Task TestAsync(string initialMarkup, string expected, OptionsCollection options) - => TestInRegularAndScript1Async(initialMarkup, expected, parameters: new TestParameters(options: options)); + private Task TestAsync(string initialMarkup, string expected, OptionsCollection options) + => TestInRegularAndScript1Async(initialMarkup, expected, parameters: new TestParameters(options: options)); - [Fact] - public async Task TestArithmeticPrecedence() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArithmeticPrecedence() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 $$* 3; - } + int x = 1 + 2 $$* 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1 + (2 * 3); - } + int x = 1 + (2 * 3); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNoArithmeticOnLowerPrecedence() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNoArithmeticOnLowerPrecedence() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 * 3; - } + int x = 1 $$+ 2 * 3; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfArithmeticPrecedenceStaysTheSame() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfArithmeticPrecedenceStaysTheSame() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 $$+ 3; - } + int x = 1 + 2 $$+ 3; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfArithmeticPrecedenceIsNotEnforced1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfArithmeticPrecedenceIsNotEnforced1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 $$+ 3; - } + int x = 1 + 2 $$+ 3; } - """, RequireOtherBinaryParenthesesForClarity); - } + } + """, RequireOtherBinaryParenthesesForClarity); + } - [Fact] - public async Task TestNotIfArithmeticPrecedenceIsNotEnforced2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfArithmeticPrecedenceIsNotEnforced2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 $$* 3; - } + int x = 1 + 2 $$* 3; } - """, RequireOtherBinaryParenthesesForClarity); - } + } + """, RequireOtherBinaryParenthesesForClarity); + } - [Fact] - public async Task TestRelationalPrecedence() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestRelationalPrecedence() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = a $$> b == c; - } + int x = a $$> b == c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (a > b) == c; - } + int x = (a > b) == c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestLogicalPrecedence() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalPrecedence() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = a || b $$&& c; - } + int x = a || b $$&& c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a || (b && c); - } + int x = a || (b && c); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNoLogicalOnLowerPrecedence() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNoLogicalOnLowerPrecedence() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a $$|| b && c; - } + int x = a $$|| b && c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfLogicalPrecedenceStaysTheSame() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfLogicalPrecedenceStaysTheSame() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a || b $$|| c; - } + int x = a || b $$|| c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfLogicalPrecedenceIsNotEnforced() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfLogicalPrecedenceIsNotEnforced() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a || b $$|| c; - } + int x = a || b $$|| c; } - """, RequireArithmeticBinaryParenthesesForClarity); - } + } + """, RequireArithmeticBinaryParenthesesForClarity); + } - [Fact] - public async Task TestMixedArithmeticAndLogical() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMixedArithmeticAndLogical() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a == b $$&& c == d; - } + int x = a == b $$&& c == d; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = a || b $$&& c && d; - } + int x = a || b $$&& c && d; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a || (b && c && d); - } + int x = a || (b && c && d); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = a || b && c $$&& d; - } + int x = a || b && c $$&& d; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a || (b && c && d); - } + int x = a || (b && c && d); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestShiftPrecedence1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestShiftPrecedence1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 << 3; - } + int x = 1 $$+ 2 << 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (1 + 2) << 3; - } + int x = (1 + 2) << 3; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestShiftPrecedence2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestShiftPrecedence2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 << 3; - } + int x = 1 $$+ 2 << 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (1 + 2) << 3; - } + int x = (1 + 2) << 3; } - """, RequireArithmeticBinaryParenthesesForClarity); - } + } + """, RequireArithmeticBinaryParenthesesForClarity); + } - [Fact] - public async Task TestShiftPrecedence3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestShiftPrecedence3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 << 3; - } + int x = 1 $$+ 2 << 3; } - """, RequireOtherBinaryParenthesesForClarity); - } + } + """, RequireOtherBinaryParenthesesForClarity); + } - [Fact] - public async Task TestNotIfShiftPrecedenceStaysTheSame1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfShiftPrecedenceStaysTheSame1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$<< 2 << 3; - } + int x = 1 $$<< 2 << 3; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfShiftPrecedenceStaysTheSame2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfShiftPrecedenceStaysTheSame2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 << 2 $$<< 3; - } + int x = 1 << 2 $$<< 3; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestEqualityPrecedence1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestEqualityPrecedence1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 == 2 + 3; - } + int x = 1 $$+ 2 == 2 + 3; } - """, RequireOtherBinaryParenthesesForClarity); - } + } + """, RequireOtherBinaryParenthesesForClarity); + } - [Fact] - public async Task TestEqualityPrecedence2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestEqualityPrecedence2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 == 2 $$+ 3; - } + int x = 1 + 2 == 2 $$+ 3; } - """, RequireOtherBinaryParenthesesForClarity); - } + } + """, RequireOtherBinaryParenthesesForClarity); + } - [Fact] - public async Task TestEqualityPrecedence3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestEqualityPrecedence3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 == 2 + 3; - } + int x = 1 $$+ 2 == 2 + 3; } - """, RequireRelationalBinaryParenthesesForClarity); - } + } + """, RequireRelationalBinaryParenthesesForClarity); + } - [Fact] - public async Task TestEqualityPrecedence4() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestEqualityPrecedence4() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 == 2 $$+ 3; - } + int x = 1 + 2 == 2 $$+ 3; } - """, RequireRelationalBinaryParenthesesForClarity); - } + } + """, RequireRelationalBinaryParenthesesForClarity); + } - [Fact] - public async Task TestCoalescePrecedence1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCoalescePrecedence1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a $$+ b ?? c; - } + int x = a $$+ b ?? c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestCoalescePrecedence2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCoalescePrecedence2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a $$?? b ?? c; - } + int x = a $$?? b ?? c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestCoalescePrecedence3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCoalescePrecedence3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a ?? b $$?? c; - } + int x = a ?? b $$?? c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestBitwisePrecedence1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestBitwisePrecedence1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$+ 2 & 3; - } + int x = 1 $$+ 2 & 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (1 + 2) & 3; - } + int x = (1 + 2) & 3; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestBitwisePrecedence2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestBitwisePrecedence2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a $$| b | c; - } + int x = a $$| b | c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestBitwisePrecedence3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestBitwisePrecedence3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = a | b $$& c; - } + int x = a | b $$& c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a | (b & c); - } + int x = a | (b & c); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestBitwisePrecedence4() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestBitwisePrecedence4() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a $$| b & c; - } + int x = a $$| b & c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotForEqualityAfterEquals() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotForEqualityAfterEquals() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 $$== 2; - } + int x = 1 $$== 2; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotForAssignmentEqualsAfterLocal() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotForAssignmentEqualsAfterLocal() + { + await TestMissingAsync( + """ + class C + { + void M(int a) { - void M(int a) - { - int x = a $$+= 2; - } + int x = a $$+= 2; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestForAssignmentAndEquality1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestForAssignmentAndEquality1() + { + await TestMissingAsync( + """ + class C + { + void M(bool x, bool y, bool z) { - void M(bool x, bool y, bool z) - { - x $$= y == z; - } + x $$= y == z; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestMissingForAssignmentAndEquality2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMissingForAssignmentAndEquality2() + { + await TestMissingAsync( + """ + class C + { + void M(bool x, bool y, bool z) { - void M(bool x, bool y, bool z) - { - x = y $$== z; - } + x = y $$== z; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestUnclearCast1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestUnclearCast1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$-y; - } + int x = (int)$$-y; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestUnclearCast_NotOfferedWithIgnore() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestUnclearCast_NotOfferedWithIgnore() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$-y; - } + int x = (int)$$-y; } - """, IgnoreAllParentheses); - } + } + """, IgnoreAllParentheses); + } - [Fact] - public async Task TestUnclearCast_NotOfferedWithRemoveForClarity() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestUnclearCast_NotOfferedWithRemoveForClarity() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$-y; - } + int x = (int)$$-y; } - """, RemoveAllUnnecessaryParentheses); - } + } + """, RemoveAllUnnecessaryParentheses); + } - [Fact] - public async Task TestUnclearCast2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestUnclearCast2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$+y; - } + int x = (int)$$+y; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestUnclearCast3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestUnclearCast3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$&y; - } + int x = (int)$$&y; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestUnclearCast4() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestUnclearCast4() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$*y; - } + int x = (int)$$*y; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotForPrimary() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotForPrimary() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$y; - } + int x = (int)$$y; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotForMemberAccess() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotForMemberAccess() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$y.z; - } + int x = (int)$$y.z; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotForCastOfCast() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotForCastOfCast() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$(y); - } + int x = (int)$$(y); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotForNonAmbiguousUnary() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotForNonAmbiguousUnary() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$!y; - } + int x = (int)$$!y; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestFixAll1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestFixAll1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + if (0 {|FixAllInDocument:>=|} 3 * 2 + 4) { - if (0 {|FixAllInDocument:>=|} 3 * 2 + 4) - { - } } } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (3 * 2 + 4 >= 3 {|FixAllInDocument:*|} 2 + 4) { - if (3 * 2 + 4 >= 3 {|FixAllInDocument:*|} 2 + 4) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if ((3 * 2) + 4 >= (3 * 2) + 4) { - if ((3 * 2) + 4 >= (3 * 2) + 4) - { - } } } - """, options: RequireAllParenthesesForClarity); - } + } + """, options: RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestFixAll3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestFixAll3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + if (3 * 2 + 4 >= 3 * 2 {|FixAllInDocument:+|} 4) { - if (3 * 2 + 4 >= 3 * 2 {|FixAllInDocument:+|} 4) - { - } } } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestSeams1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestSeams1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 {|FixAllInDocument:*|} 3 == 1 + 2 * 3; - } + int x = 1 + 2 {|FixAllInDocument:*|} 3 == 1 + 2 * 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1 + (2 * 3) == 1 + (2 * 3); - } + int x = 1 + (2 * 3) == 1 + (2 * 3); } - """, options: RequireAllParenthesesForClarity); - } + } + """, options: RequireAllParenthesesForClarity); } } diff --git a/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredPatternParenthesesTests.cs b/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredPatternParenthesesTests.cs index a9421737c6ae2..2526f648b1f61 100644 --- a/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredPatternParenthesesTests.cs +++ b/src/Analyzers/CSharp/Tests/AddRequiredParentheses/AddRequiredPatternParenthesesTests.cs @@ -15,140 +15,139 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddRequiredParentheses +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddRequiredParentheses; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddRequiredParentheses)] +public partial class AddRequiredPatternParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddRequiredParentheses)] - public partial class AddRequiredPatternParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AddRequiredPatternParenthesesTests(ITestOutputHelper logger) + : base(logger) { - public AddRequiredPatternParenthesesTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpAddRequiredPatternParenthesesDiagnosticAnalyzer(), new AddRequiredParenthesesCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpAddRequiredPatternParenthesesDiagnosticAnalyzer(), new AddRequiredParenthesesCodeFixProvider()); - private Task TestMissingAsync(string initialMarkup, OptionsCollection options) - => TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options)); + private Task TestMissingAsync(string initialMarkup, OptionsCollection options) + => TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options)); - private Task TestAsync(string initialMarkup, string expected, OptionsCollection options) - => TestInRegularAndScript1Async(initialMarkup, expected, parameters: new TestParameters(options: options)); + private Task TestAsync(string initialMarkup, string expected, OptionsCollection options) + => TestInRegularAndScript1Async(initialMarkup, expected, parameters: new TestParameters(options: options)); - [Fact] - public async Task TestLogicalPrecedence() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalPrecedence() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or b $$and c; - } + object x = o is a or b $$and c; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or (b and c); - } + object x = o is a or (b and c); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNoLogicalOnLowerPrecedence() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNoLogicalOnLowerPrecedence() + { + await TestMissingAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a $$or b and c; - } + object x = o is a $$or b and c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfLogicalPrecedenceStaysTheSame() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfLogicalPrecedenceStaysTheSame() + { + await TestMissingAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or b $$or c; - } + object x = o is a or b $$or c; } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestNotIfLogicalPrecedenceIsNotEnforced() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNotIfLogicalPrecedenceIsNotEnforced() + { + await TestMissingAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or b $$or c; - } + object x = o is a or b $$or c; } - """, RequireArithmeticBinaryParenthesesForClarity); - } + } + """, RequireArithmeticBinaryParenthesesForClarity); + } - [Fact] - public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts1() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or b $$and c and d; - } + object x = o is a or b $$and c and d; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or (b and c and d); - } + object x = o is a or (b and c and d); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); + } - [Fact] - public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalPrecedenceMultipleEqualPrecedenceParts2() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or b and c $$and d; - } + object x = o is a or b and c $$and d; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - object x = o is a or (b and c and d); - } + object x = o is a or (b and c and d); } - """, RequireAllParenthesesForClarity); - } + } + """, RequireAllParenthesesForClarity); } } diff --git a/src/Analyzers/CSharp/Tests/AliasAmbiguousType/AliasAmbiguousTypeTests.cs b/src/Analyzers/CSharp/Tests/AliasAmbiguousType/AliasAmbiguousTypeTests.cs index f9e810d9572f0..d1c4beb82299f 100644 --- a/src/Analyzers/CSharp/Tests/AliasAmbiguousType/AliasAmbiguousTypeTests.cs +++ b/src/Analyzers/CSharp/Tests/AliasAmbiguousType/AliasAmbiguousTypeTests.cs @@ -16,24 +16,24 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AliasAmbiguousType +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AliasAmbiguousType; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAliasAmbiguousType)] +public class AliasAmbiguousTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAliasAmbiguousType)] - public class AliasAmbiguousTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public AliasAmbiguousTypeTests(ITestOutputHelper logger) + : base(logger) { - public AliasAmbiguousTypeTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAliasAmbiguousTypeCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAliasAmbiguousTypeCodeFixProvider()); - protected override ImmutableArray MassageActions(ImmutableArray actions) - => FlattenActions(actions); + protected override ImmutableArray MassageActions(ImmutableArray actions) + => FlattenActions(actions); - private static string GetAmbiguousDefinition(string typeDefinion, string ns1Name = "N1", string ns2Name = "N2") - => $@" + private static string GetAmbiguousDefinition(string typeDefinion, string ns1Name = "N1", string ns2Name = "N2") + => $@" namespace {ns1Name} {{ {typeDefinion} @@ -43,11 +43,11 @@ namespace {ns2Name} {typeDefinion} }}"; - [Fact] - public async Task TestAmbiguousClassObjectCreationUsingsInNamespace() - { - var classDef = GetAmbiguousDefinition("public class Ambiguous { }"); - var initialMarkup = classDef + @" + [Fact] + public async Task TestAmbiguousClassObjectCreationUsingsInNamespace() + { + var classDef = GetAmbiguousDefinition("public class Ambiguous { }"); + var initialMarkup = classDef + @" namespace Test { using N1; @@ -60,7 +60,7 @@ void M() } } }"; - var expectedMarkup0 = classDef + @" + var expectedMarkup0 = classDef + @" namespace Test { using N1; @@ -75,7 +75,7 @@ void M() } } }"; - var expectedMarkup1 = classDef + @" + var expectedMarkup1 = classDef + @" namespace Test { using N1; @@ -90,16 +90,16 @@ void M() } } }"; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, index: 0); - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, index: 1); - await TestSmartTagTextAsync(initialMarkup, "using Ambiguous = N1.Ambiguous;"); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, index: 0); + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, index: 1); + await TestSmartTagTextAsync(initialMarkup, "using Ambiguous = N1.Ambiguous;"); + } - [Fact] - public async Task TestAmbiguousClassObjectCreationUsingsInCompilationUnit() - { - var classDef = GetAmbiguousDefinition("public class Ambiguous { }"); - await TestInRegularAndScriptAsync(@" + [Fact] + public async Task TestAmbiguousClassObjectCreationUsingsInCompilationUnit() + { + var classDef = GetAmbiguousDefinition("public class Ambiguous { }"); + await TestInRegularAndScriptAsync(@" using N1; using N2; " + classDef + @" @@ -127,13 +127,13 @@ void M() } } }"); - } + } - [Fact] - public async Task TestAmbiguousClassObjectCreationGenericsDoNotOfferDiagnostic() - { - var genericAmbiguousClassDefinition = GetAmbiguousDefinition("public class Ambiguous { }"); - await TestMissingAsync(@" + [Fact] + public async Task TestAmbiguousClassObjectCreationGenericsDoNotOfferDiagnostic() + { + var genericAmbiguousClassDefinition = GetAmbiguousDefinition("public class Ambiguous { }"); + await TestMissingAsync(@" using N1; using N2; " + genericAmbiguousClassDefinition + @" @@ -147,13 +147,13 @@ void M() } } }"); - } + } - [Fact] - public async Task TestAmbiguousAttribute() - { - var classDef = GetAmbiguousDefinition("public class AmbiguousAttribute: System.Attribute { }"); - await TestInRegularAndScriptAsync(@" + [Fact] + public async Task TestAmbiguousAttribute() + { + var classDef = GetAmbiguousDefinition("public class AmbiguousAttribute: System.Attribute { }"); + await TestInRegularAndScriptAsync(@" using N1; using N2; " + classDef + @" @@ -175,15 +175,15 @@ class C { } }"); - } + } - [Fact] - public async Task TestNamespaceAndTypenameIdenticalOffersNoDiagnostics() - { - // This gives CS0433: The type 'Ambiguous' exists in both 'Assembly1' and 'Assembly2' - // Couldn't get a CS0104 in this situation. Keep the test anyway if someone finds a way to force CS0104 here - // or CS0433 is added as a supported diagnostic for this fix. - await TestMissingAsync(@" + [Fact] + public async Task TestNamespaceAndTypenameIdenticalOffersNoDiagnostics() + { + // This gives CS0433: The type 'Ambiguous' exists in both 'Assembly1' and 'Assembly2' + // Couldn't get a CS0104 in this situation. Keep the test anyway if someone finds a way to force CS0104 here + // or CS0433 is added as a supported diagnostic for this fix. + await TestMissingAsync(@" @@ -223,24 +223,24 @@ void M() "); - } + } - [Fact] - public async Task TestAmbiguousAliasNoDiagnostics() - { - await TestMissingAsync(@" + [Fact] + public async Task TestAmbiguousAliasNoDiagnostics() + { + await TestMissingAsync(@" extern alias alias; using alias=alias; class myClass : [|alias|]::Uri { } "); - } + } - [Fact] - public async Task TestAmbiguousNestedClass() - { - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousNestedClass() + { + var initialMarkup = @" using static Static; using static Static; @@ -260,7 +260,7 @@ static void Main(string[] args) c.M(); } }"; - var expectedMarkup0 = @" + var expectedMarkup0 = @" using static Static; using static Static; using Nested = Static.Nested; @@ -281,7 +281,7 @@ static void Main(string[] args) c.M(); } }"; - var expectedMarkup1 = @" + var expectedMarkup1 = @" using static Static; using static Static; using Nested = Static.Nested; @@ -302,16 +302,16 @@ static void Main(string[] args) c.M(); } }"; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, index: 0); - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, index: 1); - await TestSmartTagTextAsync(initialMarkup, "using Nested = Static.Nested;"); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, index: 0); + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, index: 1); + await TestSmartTagTextAsync(initialMarkup, "using Nested = Static.Nested;"); + } - [Fact] - public async Task TestAmbiguousClassDiagnosedAtBaseList() - { - var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousClassDiagnosedAtBaseList() + { + var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); + var initialMarkup = @" using N1; using N2; " + classDef + @" @@ -320,7 +320,7 @@ namespace NTest public class Test : [|AmbiguousClass|] { } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousClass = N1.AmbiguousClass; @@ -330,14 +330,14 @@ namespace NTest public class Test : AmbiguousClass { } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousClassDiagnosedAtTypeConstraint() - { - var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousClassDiagnosedAtTypeConstraint() + { + var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); + var initialMarkup = @" using N1; using N2; " + classDef + @" @@ -346,7 +346,7 @@ namespace NTest public class Test where T : [|AmbiguousClass|] { } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousClass = N1.AmbiguousClass; @@ -356,14 +356,14 @@ namespace NTest public class Test where T : AmbiguousClass { } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousEnumDiagnosedAtFieldDeclaration() - { - var enumDef = GetAmbiguousDefinition(@"public enum AmbiguousEnum { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousEnumDiagnosedAtFieldDeclaration() + { + var enumDef = GetAmbiguousDefinition(@"public enum AmbiguousEnum { }"); + var initialMarkup = @" using N1; using N2; " + enumDef + @" @@ -375,7 +375,7 @@ public class Test } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousEnum = N1.AmbiguousEnum; @@ -388,14 +388,14 @@ public class Test } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousStructDiagnosedAtPropertyDeclaration() - { - var strcutDef = GetAmbiguousDefinition(@"public struct AmbiguousStruct { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousStructDiagnosedAtPropertyDeclaration() + { + var strcutDef = GetAmbiguousDefinition(@"public struct AmbiguousStruct { }"); + var initialMarkup = @" using N1; using N2; " + strcutDef + @" @@ -407,7 +407,7 @@ public class Test } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousStruct = N1.AmbiguousStruct; @@ -420,14 +420,14 @@ public class Test } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousClassDiagnosedAtTypeArgument() - { - var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousClassDiagnosedAtTypeArgument() + { + var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); + var initialMarkup = @" using N1; using N2; " + classDef + @" @@ -442,7 +442,7 @@ public void M() } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousClass = N1.AmbiguousClass; @@ -458,14 +458,14 @@ public void M() } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousClassDiagnosedAtIdentifierOfIncompleteExpression() - { - var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousClassDiagnosedAtIdentifierOfIncompleteExpression() + { + var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); + var initialMarkup = @" using N1; using N2; " + classDef + @" @@ -480,7 +480,7 @@ public void M() } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousClass = N1.AmbiguousClass; @@ -496,14 +496,14 @@ public void M() } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousClassDiagnosedAtMethodParameter() - { - var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousClassDiagnosedAtMethodParameter() + { + var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); + var initialMarkup = @" using N1; using N2; " + classDef + @" @@ -517,7 +517,7 @@ public void M([|AmbiguousClass|] a) } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using AmbiguousClass = N1.AmbiguousClass; @@ -532,14 +532,14 @@ public void M(AmbiguousClass a) } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact] - public async Task TestAmbiguousClassDiagnosedAtFromClauseTypeIdentifier() - { - var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); - var initialMarkup = @" + [Fact] + public async Task TestAmbiguousClassDiagnosedAtFromClauseTypeIdentifier() + { + var classDef = GetAmbiguousDefinition(@"public class AmbiguousClass { }"); + var initialMarkup = @" using N1; using N2; using System.Linq; @@ -556,7 +556,7 @@ public void M() } } "; - var expectedMarkup = @" + var expectedMarkup = @" using N1; using N2; using System.Linq; @@ -574,14 +574,14 @@ public void M() } } "; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30838")] - public async Task TestSortSystemFirst1() - { - var classDef = GetAmbiguousDefinition("public class Ambiguous { }", "Microsoft", "System"); - var initialMarkup = classDef + @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30838")] + public async Task TestSortSystemFirst1() + { + var classDef = GetAmbiguousDefinition("public class Ambiguous { }", "Microsoft", "System"); + var initialMarkup = classDef + @" namespace Test { using System; @@ -594,7 +594,7 @@ void M() } } }"; - var expectedMarkup0 = classDef + @" + var expectedMarkup0 = classDef + @" namespace Test { using System; @@ -609,7 +609,7 @@ void M() } } }"; - var expectedMarkup1 = classDef + @" + var expectedMarkup1 = classDef + @" namespace Test { using System; @@ -624,15 +624,15 @@ void M() } } }"; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, index: 0); - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, index: 1); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, index: 0); + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, index: 1); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30838")] - public async Task TestSortSystemFirst2() - { - var classDef = GetAmbiguousDefinition("public class Ambiguous { }", "Microsoft", "System"); - var initialMarkup = classDef + @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30838")] + public async Task TestSortSystemFirst2() + { + var classDef = GetAmbiguousDefinition("public class Ambiguous { }", "Microsoft", "System"); + var initialMarkup = classDef + @" namespace Test { using System; @@ -645,7 +645,7 @@ void M() } } }"; - var expectedMarkup0 = classDef + @" + var expectedMarkup0 = classDef + @" namespace Test { using System; @@ -660,7 +660,7 @@ void M() } } }"; - var expectedMarkup1 = classDef + @" + var expectedMarkup1 = classDef + @" namespace Test { using System; @@ -675,12 +675,11 @@ void M() } } }"; - var options = new OptionsCollection(LanguageNames.CSharp) - { - { GenerationOptions.PlaceSystemNamespaceFirst, false } - }; - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, options: options, index: 0); - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, options: options, index: 1); - } + var options = new OptionsCollection(LanguageNames.CSharp) + { + { GenerationOptions.PlaceSystemNamespaceFirst, false } + }; + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup0, options: options, index: 0); + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup1, options: options, index: 1); } } diff --git a/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAboveReturnTests.cs b/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAboveReturnTests.cs index a5f9325290116..f4ea9e664ed81 100644 --- a/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAboveReturnTests.cs +++ b/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAboveReturnTests.cs @@ -9,839 +9,838 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AssignOutParameters +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AssignOutParameters; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + AssignOutParametersAboveReturnCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAssignOutParameters)] +public class AssignOutParametersAboveReturnTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - AssignOutParametersAboveReturnCodeFixProvider>; + [Fact] + public async Task TestForSimpleReturn() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) + { + {|CS0177:return 'a';|} + } + } + """, + """ + class C + { + char M(out int i) + { + i = 0; + return 'a'; + } + } + """); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsAssignOutParameters)] - public class AssignOutParametersAboveReturnTests + [Fact] + public async Task TestForSwitchSectionReturn() { - [Fact] - public async Task TestForSimpleReturn() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) { - char M(out int i) + switch (0) { - {|CS0177:return 'a';|} + default: + {|CS0177:return 'a';|} } } - """, - """ - class C + } + """, + """ + class C + { + char M(out int i) { - char M(out int i) + switch (0) { - i = 0; - return 'a'; + default: + i = 0; + return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestForSwitchSectionReturn() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestMissingWhenVariableAssigned() + { + var code = """ + class C + { + char M(out int i) { - char M(out int i) - { - switch (0) - { - default: - {|CS0177:return 'a';|} - } - } + i = 0; + return 'a'; + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestWhenNotAssignedThroughAllPaths1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i) + { + if (b) + i = 1; + + {|CS0177:return 'a';|} } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i) { - char M(out int i) - { - switch (0) - { - default: - i = 0; - return 'a'; - } - } + if (b) + i = 1; + i = 0; + return 'a'; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingWhenVariableAssigned() - { - var code = """ - class C + [Fact] + public async Task TestWhenNotAssignedThroughAllPaths2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + bool M(out int i1, out int i2) { - char M(out int i) - { - i = 0; - return 'a'; - } + {|CS0177:return Try(out i1) || Try(out i2);|} } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task TestWhenNotAssignedThroughAllPaths1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + bool Try(out int i) { - char M(bool b, out int i) - { - if (b) - i = 1; - - {|CS0177:return 'a';|} - } + i = 0; + return true; } - """, - """ - class C + } + """, + """ + class C + { + bool M(out int i1, out int i2) { - char M(bool b, out int i) - { - if (b) - i = 1; - i = 0; - return 'a'; - } + i2 = 0; + return Try(out i1) || Try(out i2); } - """); - } - [Fact] - public async Task TestWhenNotAssignedThroughAllPaths2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + bool Try(out int i) { - bool M(out int i1, out int i2) - { - {|CS0177:return Try(out i1) || Try(out i2);|} - } - - bool Try(out int i) - { - i = 0; - return true; - } + i = 0; + return true; } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestMissingWhenAssignedThroughAllPaths() + { + var code = """ + class C + { + char M(bool b, out int i) { - bool M(out int i1, out int i2) - { - i2 = 0; - return Try(out i1) || Try(out i2); - } + if (b) + i = 1; + else + i = 2; + + return 'a'; + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestMultiple() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i, out string s) + { + {|CS0177:{|CS0177:return 'a';|}|} + } + } + """, + """ + class C + { + char M(out int i, out string s) + { + i = 0; + s = null; + return 'a'; + } + } + """); + } + + [Fact] + public async Task TestMultiple_AssignedInReturn1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + string M(out int i, out string s) + { + {|CS0177:return s = "";|} + } + } + """, + """ + class C + { + string M(out int i, out string s) + { + i = 0; + return s = ""; + } + } + """); + } - bool Try(out int i) + [Fact] + public async Task TestMultiple_AssignedInReturn2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + string M(out int i, out string s) + { + {|CS0177:return (i = 0).ToString();|} + } + } + """, + """ + class C + { + string M(out int i, out string s) + { + s = null; + return (i = 0).ToString(); + } + } + """); + } + + [Fact] + public async Task TestNestedReturn() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) + { + if (true) { - i = 0; - return true; + {|CS0177:return 'a';|} } } - """); - } - - [Fact] - public async Task TestMissingWhenAssignedThroughAllPaths() - { - var code = """ - class C + } + """, + """ + class C + { + char M(out int i) { - char M(bool b, out int i) + if (true) { - if (b) - i = 1; - else - i = 2; - + i = 0; return 'a'; } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } + } + """); + } - [Fact] - public async Task TestMultiple() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestNestedReturnNoBlock() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) { - char M(out int i, out string s) - { - {|CS0177:{|CS0177:return 'a';|}|} - } + if (true) + {|CS0177:return 'a';|} } - """, - """ - class C + } + """, + """ + class C + { + char M(out int i) { - char M(out int i, out string s) + if (true) { i = 0; - s = null; return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestMultiple_AssignedInReturn1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestNestedReturnEvenWhenWrittenAfter() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i) { - string M(out int i, out string s) + if (b) { - {|CS0177:return s = "";|} + {|CS0177:return 'a';|} } + + i = 1; + throw null; } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i) { - string M(out int i, out string s) + if (b) { i = 0; - return s = ""; + return 'a'; } + + i = 1; + throw null; } - """); - } + } + """); + } - [Fact] - public async Task TestMultiple_AssignedInReturn2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestForExpressionBodyMember() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) => {|CS0177:'a'|}; + } + """, + """ + class C + { + char M(out int i) + { + i = 0; + return 'a'; + } + } + """); + } + + [Fact] + public async Task TestForLambdaExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + delegate char D(out int i); + void X() + { + D d = (out int i) => {|CS0177:'a'|}; + } + } + """, + """ + class C + { + delegate char D(out int i); + void X() + { + D d = (out int i) => { i = 0; return 'a'; }; + } + } + """); + } + + [Fact] + public async Task TestMissingForLocalFunctionExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void X() { - string M(out int i, out string s) - { - {|CS0177:return (i = 0).ToString();|} - } + char {|CS0177:D|}(out int i) => 'a'; + D(out _); } - """, - """ - class C + } + """, + """ + class C + { + void X() { - string M(out int i, out string s) - { - s = null; - return (i = 0).ToString(); - } + char D(out int i) { i = 0; return 'a'; } + + D(out _); } - """); - } + } + """); + } - [Fact] - public async Task TestNestedReturn() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestForLambdaBlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + delegate char D(out int i); + void X() { - char M(out int i) + D d = (out int i) => { - if (true) - { - {|CS0177:return 'a';|} - } - } + {|CS0177:return 'a';|} + }; } - """, - """ - class C + } + """, + """ + class C + { + delegate char D(out int i); + void X() { - char M(out int i) + D d = (out int i) => { - if (true) - { - i = 0; - return 'a'; - } - } + i = 0; + return 'a'; + }; } - """); - } + } + """); + } - [Fact] - public async Task TestNestedReturnNoBlock() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestForLocalFunctionBlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void X() { - char M(out int i) + char D(out int i) { - if (true) - {|CS0177:return 'a';|} + {|CS0177:return 'a';|} } + + D(out _); } - """, - """ - class C + } + """, + """ + class C + { + void X() { - char M(out int i) + char D(out int i) { - if (true) - { - i = 0; - return 'a'; - } + i = 0; + return 'a'; } + + D(out _); } - """); - } + } + """); + } - [Fact] - public async Task TestNestedReturnEvenWhenWrittenAfter() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestForOutParamInSinglePath() + { + var code = """ + class C + { + char M(bool b, out int i) { - char M(bool b, out int i) - { - if (b) - { - {|CS0177:return 'a';|} - } - + if (b) i = 1; - throw null; - } - } - """, - """ - class C - { - char M(bool b, out int i) - { - if (b) - { - i = 0; - return 'a'; - } + else + SomeMethod(out i); - i = 1; - throw null; - } + return 'a'; } - """); - } - [Fact] - public async Task TestForExpressionBodyMember() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + void SomeMethod(out int i) => i = 0; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(out int i) => {|CS0177:'a'|}; + if (b) + { + {|CS0177:{|CS0177:return 'a';|}|} + } + else + { + {|CS0177:{|CS0177:return 'a';|}|} + } } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(out int i) + if (b) + { + i = 0; + j = 0; + return 'a'; + } + else { i = 0; + j = 0; return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestForLambdaExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll1_MultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - delegate char D(out int i); - void X() + if (b) { - D d = (out int i) => {|CS0177:'a'|}; + {|CS0177:{|CS0177:return 'a';|}|} } - } - """, - """ - class C - { - delegate char D(out int i); - void X() + else { - D d = (out int i) => { i = 0; return 'a'; }; + {|CS0177:{|CS0177:return 'a';|}|} } } - """); - } - - [Fact] - public async Task TestMissingForLocalFunctionExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + char N(bool b, out int i, out int j) { - void X() + if (b) { - char {|CS0177:D|}(out int i) => 'a'; - D(out _); + {|CS0177:{|CS0177:return 'a';|}|} } - } - """, - """ - class C - { - void X() + else { - char D(out int i) { i = 0; return 'a'; } - - D(out _); + {|CS0177:{|CS0177:return 'a';|}|} } } - """); - } - - [Fact] - public async Task TestForLambdaBlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - delegate char D(out int i); - void X() + if (b) { - D d = (out int i) => - { - {|CS0177:return 'a';|} - }; + i = 0; + j = 0; + return 'a'; } - } - """, - """ - class C - { - delegate char D(out int i); - void X() + else { - D d = (out int i) => - { - i = 0; - return 'a'; - }; + i = 0; + j = 0; + return 'a'; } } - """); - } - - [Fact] - public async Task TestForLocalFunctionBlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + char N(bool b, out int i, out int j) { - void X() + if (b) { - char D(out int i) - { - {|CS0177:return 'a';|} - } - - D(out _); + i = 0; + j = 0; + return 'a'; } - } - """, - """ - class C - { - void X() + else { - char D(out int i) - { - i = 0; - return 'a'; - } - - D(out _); + i = 0; + j = 0; + return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestForOutParamInSinglePath() - { - var code = """ - class C + [Fact] + public async Task TestFixAll2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) + { + if (b) + {|CS0177:{|CS0177:return 'a';|}|} + else + {|CS0177:{|CS0177:return 'a';|}|} + } + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i) + if (b) { - if (b) - i = 1; - else - SomeMethod(out i); - + i = 0; + j = 0; + return 'a'; + } + else + { + i = 0; + j = 0; return 'a'; } - - void SomeMethod(out int i) => i = 0; } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll2_MultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) - { - if (b) - { - {|CS0177:{|CS0177:return 'a';|}|} - } - else - { - {|CS0177:{|CS0177:return 'a';|}|} - } - } + if (b) + {|CS0177:{|CS0177:return 'a';|}|} + else + {|CS0177:{|CS0177:return 'a';|}|} } - """, - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) - { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - i = 0; - j = 0; - return 'a'; - } - } + if (b) + {|CS0177:{|CS0177:return 'a';|}|} + else + {|CS0177:{|CS0177:return 'a';|}|} } - """); - } - - [Fact] - public async Task TestFixAll1_MultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - {|CS0177:{|CS0177:return 'a';|}|} - } - else - { - {|CS0177:{|CS0177:return 'a';|}|} - } + i = 0; + j = 0; + return 'a'; } - char N(bool b, out int i, out int j) + else { - if (b) - { - {|CS0177:{|CS0177:return 'a';|}|} - } - else - { - {|CS0177:{|CS0177:return 'a';|}|} - } + i = 0; + j = 0; + return 'a'; } } - """, - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - i = 0; - j = 0; - return 'a'; - } + i = 0; + j = 0; + return 'a'; } - char N(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - i = 0; - j = 0; - return 'a'; - } + i = 0; + j = 0; + return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll3() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - {|CS0177:{|CS0177:return 'a';|}|} - else - {|CS0177:{|CS0177:return 'a';|}|} + i = 0; + {|CS0177:return 'a';|} } - } - """, - """ - class C - { - char M(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - i = 0; - j = 0; - return 'a'; - } + j = 0; + {|CS0177:return 'a';|} } } - """); - } - - [Fact] - public async Task TestFixAll2_MultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - {|CS0177:{|CS0177:return 'a';|}|} - else - {|CS0177:{|CS0177:return 'a';|}|} + i = 0; + j = 0; + return 'a'; } - char N(bool b, out int i, out int j) + else { - if (b) - {|CS0177:{|CS0177:return 'a';|}|} - else - {|CS0177:{|CS0177:return 'a';|}|} + j = 0; + i = 0; + return 'a'; } } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestFixAll3_MultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - i = 0; - j = 0; - return 'a'; - } + i = 0; + {|CS0177:return 'a';|} } - char N(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - i = 0; - j = 0; - return 'a'; - } + j = 0; + {|CS0177:return 'a';|} } } - """); - } - - [Fact] - public async Task TestFixAll3() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - {|CS0177:return 'a';|} - } - else - { - j = 0; - {|CS0177:return 'a';|} - } + i = 0; + {|CS0177:return 'a';|} } - } - """, - """ - class C - { - char M(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - j = 0; - i = 0; - return 'a'; - } + j = 0; + {|CS0177:return 'a';|} } } - """); - } - - [Fact] - public async Task TestFixAll3_MultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - {|CS0177:return 'a';|} - } - else - { - j = 0; - {|CS0177:return 'a';|} - } + i = 0; + j = 0; + return 'a'; } - char N(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - {|CS0177:return 'a';|} - } - else - { - j = 0; - {|CS0177:return 'a';|} - } + j = 0; + i = 0; + return 'a'; } } - """, - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - j = 0; - i = 0; - return 'a'; - } + i = 0; + j = 0; + return 'a'; } - char N(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - j = 0; - return 'a'; - } - else - { - j = 0; - i = 0; - return 'a'; - } + j = 0; + i = 0; + return 'a'; } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAtStartTests.cs b/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAtStartTests.cs index 105523a8fa3e9..a9315dcd7cec7 100644 --- a/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAtStartTests.cs +++ b/src/Analyzers/CSharp/Tests/AssignOutParameters/AssignOutParametersAtStartTests.cs @@ -9,725 +9,724 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AssignOutParameters +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AssignOutParameters; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + AssignOutParametersAtStartCodeFixProvider>; + +/// +/// Note: many of these tests will validate that there is no fix offered here. That's because for many of them, that +/// fix is offered by the AssignOutParametersAboveReturnCodeFixProvider instead. These tests have been marked as +/// such. +/// +[Trait(Traits.Feature, Traits.Features.CodeActionsAssignOutParameters)] +public class AssignOutParametersAtStartTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - AssignOutParametersAtStartCodeFixProvider>; - - /// - /// Note: many of these tests will validate that there is no fix offered here. That's because for many of them, that - /// fix is offered by the AssignOutParametersAboveReturnCodeFixProvider instead. These tests have been marked as - /// such. - /// - [Trait(Traits.Feature, Traits.Features.CodeActionsAssignOutParameters)] - public class AssignOutParametersAtStartTests + [Fact] + public async Task TestForSimpleReturn() { - [Fact] - public async Task TestForSimpleReturn() - { - // Handled by other fixer - var code = """ - class C + // Handled by other fixer + var code = """ + class C + { + char M(out int i) { - char M(out int i) - { - {|CS0177:return 'a';|} - } + {|CS0177:return 'a';|} } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestForSwitchSectionReturn() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestForSwitchSectionReturn() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) { - char M(out int i) + switch (0) { - switch (0) - { - default: - {|CS0177:return 'a';|} - } + default: + {|CS0177:return 'a';|} } } - """, - """ - class C + } + """, + """ + class C + { + char M(out int i) { - char M(out int i) + i = 0; + switch (0) { - i = 0; - switch (0) - { - default: - return 'a'; - } + default: + return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingWhenVariableAssigned() - { - var code = """ - class C + [Fact] + public async Task TestMissingWhenVariableAssigned() + { + var code = """ + class C + { + char M(out int i) { - char M(out int i) - { - i = 0; - return 'a'; - } + i = 0; + return 'a'; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestWhenNotAssignedThroughAllPaths1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestWhenNotAssignedThroughAllPaths1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i) { - char M(bool b, out int i) - { - if (b) - i = 1; + if (b) + i = 1; - {|CS0177:return 'a';|} - } + {|CS0177:return 'a';|} } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i) { - char M(bool b, out int i) - { - i = 0; - if (b) - i = 1; + i = 0; + if (b) + i = 1; - return 'a'; - } + return 'a'; } - """); - } + } + """); + } - [Fact] - public async Task TestWhenNotAssignedThroughAllPaths2() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestWhenNotAssignedThroughAllPaths2() + { + // Handled by other fixer + var code = """ + class C + { + bool M(out int i1, out int i2) { - bool M(out int i1, out int i2) - { - {|CS0177:return Try(out i1) || Try(out i2);|} - } + {|CS0177:return Try(out i1) || Try(out i2);|} + } - bool Try(out int i) - { - i = 0; - return true; - } + bool Try(out int i) + { + i = 0; + return true; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingWhenAssignedThroughAllPaths() - { - var code = """ - class C + [Fact] + public async Task TestMissingWhenAssignedThroughAllPaths() + { + var code = """ + class C + { + char M(bool b, out int i) { - char M(bool b, out int i) - { - if (b) - i = 1; - else - i = 2; + if (b) + i = 1; + else + i = 2; - return 'a'; - } + return 'a'; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMultiple() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestMultiple() + { + // Handled by other fixer + var code = """ + class C + { + char M(out int i, out string s) { - char M(out int i, out string s) - { - {|CS0177:{|CS0177:return 'a';|}|} - } + {|CS0177:{|CS0177:return 'a';|}|} } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMultiple_AssignedInReturn1() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestMultiple_AssignedInReturn1() + { + // Handled by other fixer + var code = """ + class C + { + string M(out int i, out string s) { - string M(out int i, out string s) - { - {|CS0177:return s = "";|} - } + {|CS0177:return s = "";|} } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMultiple_AssignedInReturn2() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestMultiple_AssignedInReturn2() + { + // Handled by other fixer + var code = """ + class C + { + string M(out int i, out string s) { - string M(out int i, out string s) - { - {|CS0177:return (i = 0).ToString();|} - } + {|CS0177:return (i = 0).ToString();|} } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestNestedReturn() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestNestedReturn() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) { - char M(out int i) + if (true) { - if (true) - { - {|CS0177:return 'a';|} - } + {|CS0177:return 'a';|} } } - """, - """ - class C + } + """, + """ + class C + { + char M(out int i) { - char M(out int i) + i = 0; + if (true) { - i = 0; - if (true) - { - return 'a'; - } + return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestNestedReturnNoBlock() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestNestedReturnNoBlock() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(out int i) { - char M(out int i) - { - if (true) - {|CS0177:return 'a';|} - } + if (true) + {|CS0177:return 'a';|} } - """, - """ - class C + } + """, + """ + class C + { + char M(out int i) { - char M(out int i) - { - i = 0; - if (true) - return 'a'; - } + i = 0; + if (true) + return 'a'; } - """); - } + } + """); + } - [Fact] - public async Task TestNestedReturnEvenWhenWrittenAfter() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestNestedReturnEvenWhenWrittenAfter() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i) { - char M(bool b, out int i) + if (b) { - if (b) - { - {|CS0177:return 'a';|} - } - - i = 1; - throw null; + {|CS0177:return 'a';|} } + + i = 1; + throw null; } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i) { - char M(bool b, out int i) + i = 0; + if (b) { - i = 0; - if (b) - { - return 'a'; - } - - i = 1; - throw null; + return 'a'; } + + i = 1; + throw null; } - """); - } + } + """); + } - [Fact] - public async Task TestForExpressionBodyMember() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestForExpressionBodyMember() + { + // Handled by other fixer + var code = """ + class C + { + char M(out int i) => {|CS0177:'a'|}; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestForLambdaExpressionBody() + { + // Handled by other fixer + var code = """ + class C + { + delegate char D(out int i); + void X() { - char M(out int i) => {|CS0177:'a'|}; + D d = (out int i) => {|CS0177:'a'|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestForLambdaExpressionBody() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestMissingForLocalFunctionExpressionBody() + { + // Handled by other fixer + var code = """ + class C + { + void X() { - delegate char D(out int i); - void X() - { - D d = (out int i) => {|CS0177:'a'|}; - } + char {|CS0177:D|}(out int i) => 'a'; + D(out _); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingForLocalFunctionExpressionBody() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestForLambdaBlockBody() + { + // Handled by other fixer + var code = """ + class C + { + delegate char D(out int i); + void X() { - void X() + D d = (out int i) => { - char {|CS0177:D|}(out int i) => 'a'; - D(out _); - } + {|CS0177:return 'a';|} + }; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestForLambdaBlockBody() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestForLocalFunctionBlockBody() + { + // Handled by other fixer + var code = """ + class C + { + void X() { - delegate char D(out int i); - void X() + char D(out int i) { - D d = (out int i) => - { - {|CS0177:return 'a';|} - }; + {|CS0177:return 'a';|} } + + D(out _); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestForLocalFunctionBlockBody() - { - // Handled by other fixer - var code = """ - class C + [Fact] + public async Task TestForOutParamInSinglePath() + { + var code = """ + class C + { + char M(bool b, out int i) { - void X() - { - char D(out int i) - { - {|CS0177:return 'a';|} - } + if (b) + i = 1; + else + SomeMethod(out i); - D(out _); - } + return 'a'; } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + void SomeMethod(out int i) => i = 0; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestForOutParamInSinglePath() - { - var code = """ - class C + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i) + if (b) { - if (b) - i = 1; - else - SomeMethod(out i); - - return 'a'; + {|CS0177:{|CS0177:return 'a';|}|} + } + else + { + {|CS0177:{|CS0177:return 'a';|}|} } - - void SomeMethod(out int i) => i = 0; } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + i = 0; + j = 0; + if (b) { - if (b) - { - {|CS0177:{|CS0177:return 'a';|}|} - } - else - { - {|CS0177:{|CS0177:return 'a';|}|} - } + return 'a'; + } + else + { + return 'a'; } } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestFixAll1_MultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - i = 0; - j = 0; - if (b) - { - return 'a'; - } - else - { - return 'a'; - } + {|CS0177:{|CS0177:return 'a';|}|} + } + else + { + {|CS0177:{|CS0177:return 'a';|}|} } } - """); - } - - [Fact] - public async Task TestFixAll1_MultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C - { - char M(bool b, out int i, out int j) - { - if (b) - { - {|CS0177:{|CS0177:return 'a';|}|} - } - else - { - {|CS0177:{|CS0177:return 'a';|}|} - } + char N(bool b, out int i, out int j) + { + if (b) + { + {|CS0177:{|CS0177:return 'a';|}|} } - char N(bool b, out int i, out int j) - { - if (b) - { - {|CS0177:{|CS0177:return 'a';|}|} - } - else - { - {|CS0177:{|CS0177:return 'a';|}|} - } + else + { + {|CS0177:{|CS0177:return 'a';|}|} } } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + i = 0; + j = 0; + if (b) { - i = 0; - j = 0; - if (b) - { - return 'a'; - } - else - { - return 'a'; - } + return 'a'; } - - char N(bool b, out int i, out int j) + else { - i = 0; - j = 0; - if (b) - { - return 'a'; - } - else - { - return 'a'; - } + return 'a'; } } - """); - } - [Fact] - public async Task TestFixAll2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + i = 0; + j = 0; + if (b) { - if (b) - {|CS0177:{|CS0177:return 'a';|}|} - else - {|CS0177:{|CS0177:return 'a';|}|} + return 'a'; } - } - """, - """ - class C - { - char M(bool b, out int i, out int j) + else { - i = 0; - j = 0; - if (b) - return 'a'; - else - return 'a'; + return 'a'; } } - """); - } + } + """); + } + + [Fact] + public async Task TestFixAll2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) + { + if (b) + {|CS0177:{|CS0177:return 'a';|}|} + else + {|CS0177:{|CS0177:return 'a';|}|} + } + } + """, + """ + class C + { + char M(bool b, out int i, out int j) + { + i = 0; + j = 0; + if (b) + return 'a'; + else + return 'a'; + } + } + """); + } + + [Fact] + public async Task TestFixAll2_MultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) + { + if (b) + {|CS0177:{|CS0177:return 'a';|}|} + else + {|CS0177:{|CS0177:return 'a';|}|} + } + char N(bool b, out int i, out int j) + { + if (b) + {|CS0177:{|CS0177:return 'a';|}|} + else + {|CS0177:{|CS0177:return 'a';|}|} + } + } + """, + """ + class C + { + char M(bool b, out int i, out int j) + { + i = 0; + j = 0; + if (b) + return 'a'; + else + return 'a'; + } - [Fact] - public async Task TestFixAll2_MultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + i = 0; + j = 0; + if (b) + return 'a'; + else + return 'a'; + } + } + """); + } + + [Fact] + public async Task TestFixAll3() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) + { + if (b) { - if (b) - {|CS0177:{|CS0177:return 'a';|}|} - else - {|CS0177:{|CS0177:return 'a';|}|} + i = 0; + {|CS0177:return 'a';|} } - char N(bool b, out int i, out int j) + else { - if (b) - {|CS0177:{|CS0177:return 'a';|}|} - else - {|CS0177:{|CS0177:return 'a';|}|} + j = 0; + {|CS0177:return 'a';|} } } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + i = 0; + j = 0; + if (b) { i = 0; - j = 0; - if (b) - return 'a'; - else - return 'a'; + return 'a'; } - - char N(bool b, out int i, out int j) + else { - i = 0; j = 0; - if (b) - return 'a'; - else - return 'a'; + return 'a'; } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll3() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll3_MultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - {|CS0177:return 'a';|} - } - else - { - j = 0; - {|CS0177:return 'a';|} - } + i = 0; + {|CS0177:return 'a';|} } - } - """, - """ - class C - { - char M(bool b, out int i, out int j) + else { - i = 0; j = 0; - if (b) - { - i = 0; - return 'a'; - } - else - { - j = 0; - return 'a'; - } + {|CS0177:return 'a';|} } } - """); - } - - [Fact] - public async Task TestFixAll3_MultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + char N(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + if (b) { - if (b) - { - i = 0; - {|CS0177:return 'a';|} - } - else - { - j = 0; - {|CS0177:return 'a';|} - } + i = 0; + {|CS0177:return 'a';|} } - char N(bool b, out int i, out int j) + else { - if (b) - { - i = 0; - {|CS0177:return 'a';|} - } - else - { - j = 0; - {|CS0177:return 'a';|} - } + j = 0; + {|CS0177:return 'a';|} } } - """, - """ - class C + } + """, + """ + class C + { + char M(bool b, out int i, out int j) { - char M(bool b, out int i, out int j) + i = 0; + j = 0; + if (b) { i = 0; + return 'a'; + } + else + { j = 0; - if (b) - { - i = 0; - return 'a'; - } - else - { - j = 0; - return 'a'; - } + return 'a'; } + } - char N(bool b, out int i, out int j) + char N(bool b, out int i, out int j) + { + i = 0; + j = 0; + if (b) { i = 0; + return 'a'; + } + else + { j = 0; - if (b) - { - i = 0; - return 'a'; - } - else - { - j = 0; - return 'a'; - } + return 'a'; } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests.cs b/src/Analyzers/CSharp/Tests/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests.cs index b11cd30b3ecb9..b96620c99119b 100644 --- a/src/Analyzers/CSharp/Tests/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests.cs +++ b/src/Analyzers/CSharp/Tests/ConditionalExpressionInStringInterpolation/CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests.cs @@ -11,325 +11,324 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConditionalExpressionInStringInterpolation +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConditionalExpressionInStringInterpolation; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddParenthesesAroundConditionalExpressionInInterpolatedString)] +public class CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddParenthesesAroundConditionalExpressionInInterpolatedString)] - public class CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests(ITestOutputHelper logger) + : base(logger) { - public CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProviderTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAddParenthesesAroundConditionalExpressionInInterpolatedStringCodeFixProvider()); - private async Task TestInMethodAsync(string initialMethodBody, string expectedMethodBody) - { - var template = """ - class Application + private async Task TestInMethodAsync(string initialMethodBody, string expectedMethodBody) + { + var template = """ + class Application + {{ + public void M() {{ - public void M() - {{ - {0} - }} + {0} }} - """; - await TestInRegularAndScriptAsync( - string.Format(template, initialMethodBody), - string.Format(template, expectedMethodBody)).ConfigureAwait(false); - } + }} + """; + await TestInRegularAndScriptAsync( + string.Format(template, initialMethodBody), + string.Format(template, expectedMethodBody)).ConfigureAwait(false); + } - [Fact] - public async Task TestAddParenthesesSimpleConditionalExpression() - { - await TestInMethodAsync( - """var s = $"{ true ? 1 [|:|] 2}";""", - """var s = $"{ (true ? 1 : 2)}";"""); - } + [Fact] + public async Task TestAddParenthesesSimpleConditionalExpression() + { + await TestInMethodAsync( + """var s = $"{ true ? 1 [|:|] 2}";""", + """var s = $"{ (true ? 1 : 2)}";"""); + } - [Fact] - public async Task TestAddParenthesesMultiLineConditionalExpression1() - { - await TestInMethodAsync(""" - var s = $@"{ true - [|? 1|] - : 2}"; - """, """ - var s = $@"{ (true - ? 1 - : 2)}"; - """); - } + [Fact] + public async Task TestAddParenthesesMultiLineConditionalExpression1() + { + await TestInMethodAsync(""" + var s = $@"{ true + [|? 1|] + : 2}"; + """, """ + var s = $@"{ (true + ? 1 + : 2)}"; + """); + } - [Fact] - public async Task TestAddParenthesesMultiLineConditionalExpression2() - { - await TestInMethodAsync(""" - var s = $@"{ - true - ? - [|1|] - : - 2 - }"; - """, """ - var s = $@"{ - (true - ? - 1 - : - 2 - ) }"; - """); - } + [Fact] + public async Task TestAddParenthesesMultiLineConditionalExpression2() + { + await TestInMethodAsync(""" + var s = $@"{ + true + ? + [|1|] + : + 2 + }"; + """, """ + var s = $@"{ + (true + ? + 1 + : + 2 + ) }"; + """); + } - [Fact] - public async Task TestAddParenthesesWithTrivia() - { - await TestInMethodAsync( - """var s = $"{ /* Leading1 */ true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */[|:|] /* FalsePart1 */ 2 /* FalsePart2 */ }";""", - """var s = $"{ /* Leading1 */ (true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */: /* FalsePart1 */ 2) /* FalsePart2 */ }";"""); - } + [Fact] + public async Task TestAddParenthesesWithTrivia() + { + await TestInMethodAsync( + """var s = $"{ /* Leading1 */ true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */[|:|] /* FalsePart1 */ 2 /* FalsePart2 */ }";""", + """var s = $"{ /* Leading1 */ (true /* Leading2 */ ? /* TruePart1 */ 1 /* TruePart2 */: /* FalsePart1 */ 2) /* FalsePart2 */ }";"""); + } - [Fact] - public async Task TestAddParenthesesClosingBracketInFalseCondition() - { - await TestInMethodAsync( - """var s = $"{ true ? new int[0] [|:|] new int[] {} }";""", - """var s = $"{ (true ? new int[0] : new int[] {}) }";"""); - } + [Fact] + public async Task TestAddParenthesesClosingBracketInFalseCondition() + { + await TestInMethodAsync( + """var s = $"{ true ? new int[0] [|:|] new int[] {} }";""", + """var s = $"{ (true ? new int[0] : new int[] {}) }";"""); + } - [Fact] - public async Task TestAddParenthesesStringLiteralInFalseCondition() - { - await TestInMethodAsync( - """var s = $"{ true ? "1" [|:|] "2" }";""", - """var s = $"{ (true ? "1" : "2") }";"""); - } + [Fact] + public async Task TestAddParenthesesStringLiteralInFalseCondition() + { + await TestInMethodAsync( + """var s = $"{ true ? "1" [|:|] "2" }";""", + """var s = $"{ (true ? "1" : "2") }";"""); + } - [Fact] - public async Task TestAddParenthesesVerbatimStringLiteralInFalseCondition() - { - await TestInMethodAsync( - """"var s = $"{ true ? "1" [|:|] @"""2""" }";"""", - """"var s = $"{ (true ? "1" : @"""2""") }";""""); - } + [Fact] + public async Task TestAddParenthesesVerbatimStringLiteralInFalseCondition() + { + await TestInMethodAsync( + """"var s = $"{ true ? "1" [|:|] @"""2""" }";"""", + """"var s = $"{ (true ? "1" : @"""2""") }";""""); + } - [Fact] - public async Task TestAddParenthesesStringLiteralInFalseConditionWithClosingParenthesisInLiteral() - { - await TestInMethodAsync( - """var s = $"{ true ? "1" [|:|] "2)" }";""", - """var s = $"{ (true ? "1" : "2)") }";"""); - } + [Fact] + public async Task TestAddParenthesesStringLiteralInFalseConditionWithClosingParenthesisInLiteral() + { + await TestInMethodAsync( + """var s = $"{ true ? "1" [|:|] "2)" }";""", + """var s = $"{ (true ? "1" : "2)") }";"""); + } - [Fact] - public async Task TestAddParenthesesStringLiteralInFalseConditionWithEscapedDoubleQuotes() - { - await TestInMethodAsync( - """var s = $"{ true ? "1" [|:|] "2\"" }";""", - """var s = $"{ (true ? "1" : "2\"") }";"""); - } + [Fact] + public async Task TestAddParenthesesStringLiteralInFalseConditionWithEscapedDoubleQuotes() + { + await TestInMethodAsync( + """var s = $"{ true ? "1" [|:|] "2\"" }";""", + """var s = $"{ (true ? "1" : "2\"") }";"""); + } - [Fact] - public async Task TestAddParenthesesStringLiteralInFalseConditionWithCodeLikeContent() - { - await TestInMethodAsync( - """var s = $"{ true ? "1" [|:|] "M(new int[] {}, \"Parameter\");" }";""", - """var s = $"{ (true ? "1" : "M(new int[] {}, \"Parameter\");") }";"""); - } + [Fact] + public async Task TestAddParenthesesStringLiteralInFalseConditionWithCodeLikeContent() + { + await TestInMethodAsync( + """var s = $"{ true ? "1" [|:|] "M(new int[] {}, \"Parameter\");" }";""", + """var s = $"{ (true ? "1" : "M(new int[] {}, \"Parameter\");") }";"""); + } - [Fact] - public async Task TestAddParenthesesNestedConditionalExpression1() - { - await TestInMethodAsync( - """var s2 = $"{ true ? "1" [|:|] (false ? "2" : "3") };""", - """var s2 = $"{ (true ? "1" : (false ? "2" : "3")) };"""); - } + [Fact] + public async Task TestAddParenthesesNestedConditionalExpression1() + { + await TestInMethodAsync( + """var s2 = $"{ true ? "1" [|:|] (false ? "2" : "3") };""", + """var s2 = $"{ (true ? "1" : (false ? "2" : "3")) };"""); + } - [Fact] - public async Task TestAddParenthesesNestedConditionalExpression2() - { - await TestInMethodAsync( - """var s2 = $"{ true ? "1" [|:|] false ? "2" : "3" };""", - """var s2 = $"{ (true ? "1" : false ? "2" : "3") };"""); - } + [Fact] + public async Task TestAddParenthesesNestedConditionalExpression2() + { + await TestInMethodAsync( + """var s2 = $"{ true ? "1" [|:|] false ? "2" : "3" };""", + """var s2 = $"{ (true ? "1" : false ? "2" : "3") };"""); + } - [Fact] - public async Task TestAddParenthesesNestedConditionalWithNestedInterpolatedString() - { - await TestInMethodAsync( - """ - var s2 = $"{ (true ? "1" : false ? $"{ true ? "2" [|:|] "3"}" : "4") }" - """, - """ - var s2 = $"{ (true ? "1" : false ? $"{ (true ? "2" : "3")}" : "4") }" - """); - } + [Fact] + public async Task TestAddParenthesesNestedConditionalWithNestedInterpolatedString() + { + await TestInMethodAsync( + """ + var s2 = $"{ (true ? "1" : false ? $"{ true ? "2" [|:|] "3"}" : "4") }" + """, + """ + var s2 = $"{ (true ? "1" : false ? $"{ (true ? "2" : "3")}" : "4") }" + """); + } - [Fact] - public async Task TestAddParenthesesMultipleInterpolatedSections1() - { - await TestInMethodAsync( - """var s3 = $"Text1 { true ? "Text2" [|:|] "Text3"} Text4 { (true ? "Text5" : "Text6")} Text7";""", - """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { (true ? "Text5" : "Text6")} Text7";"""); - } + [Fact] + public async Task TestAddParenthesesMultipleInterpolatedSections1() + { + await TestInMethodAsync( + """var s3 = $"Text1 { true ? "Text2" [|:|] "Text3"} Text4 { (true ? "Text5" : "Text6")} Text7";""", + """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { (true ? "Text5" : "Text6")} Text7";"""); + } - [Fact] - public async Task TestAddParenthesesMultipleInterpolatedSections2() - { - await TestInMethodAsync( - """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { true ? "Text5" [|:|] "Text6"} Text7";""", - """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { (true ? "Text5" : "Text6")} Text7";"""); - } + [Fact] + public async Task TestAddParenthesesMultipleInterpolatedSections2() + { + await TestInMethodAsync( + """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { true ? "Text5" [|:|] "Text6"} Text7";""", + """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { (true ? "Text5" : "Text6")} Text7";"""); + } - [Fact] - public async Task TestAddParenthesesMultipleInterpolatedSections3() - { - await TestInMethodAsync( - """var s3 = $"Text1 { true ? "Text2" [|:|] "Text3"} Text4 { true ? "Text5" : "Text6"} Text7";""", - """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { true ? "Text5" : "Text6"} Text7";"""); - } + [Fact] + public async Task TestAddParenthesesMultipleInterpolatedSections3() + { + await TestInMethodAsync( + """var s3 = $"Text1 { true ? "Text2" [|:|] "Text3"} Text4 { true ? "Text5" : "Text6"} Text7";""", + """var s3 = $"Text1 { (true ? "Text2" : "Text3")} Text4 { true ? "Text5" : "Text6"} Text7";"""); + } - [Fact] - public async Task TestAddParenthesesWhileTyping1() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = $"Text1 { true ? "Text2" [|:|] - NextLineOfCode(); - """, - """ - PreviousLineOfCode(); - var s3 = $"Text1 { (true ? "Text2" :) - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWhileTyping1() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = $"Text1 { true ? "Text2" [|:|] + NextLineOfCode(); + """, + """ + PreviousLineOfCode(); + var s3 = $"Text1 { (true ? "Text2" :) + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesWhileTyping2() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = $"Text1 { true ? "Text2" [|:|] " - NextLineOfCode(); - """, - """ - PreviousLineOfCode(); - var s3 = $"Text1 { (true ? "Text2" : ") - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWhileTyping2() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = $"Text1 { true ? "Text2" [|:|] " + NextLineOfCode(); + """, + """ + PreviousLineOfCode(); + var s3 = $"Text1 { (true ? "Text2" : ") + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesWhileTyping3() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = $"Text1 { true ? "Text2" [|:|] "Text3 - NextLineOfCode(); - """, - """ - PreviousLineOfCode(); - var s3 = $"Text1 { (true ? "Text2" : "Text3) - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWhileTyping3() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = $"Text1 { true ? "Text2" [|:|] "Text3 + NextLineOfCode(); + """, + """ + PreviousLineOfCode(); + var s3 = $"Text1 { (true ? "Text2" : "Text3) + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesWhileTyping4() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" - NextLineOfCode(); - """, - """ - PreviousLineOfCode(); - var s3 = $"Text1 { (true ? "Text2" : "Text3") - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWhileTyping4() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" + NextLineOfCode(); + """, + """ + PreviousLineOfCode(); + var s3 = $"Text1 { (true ? "Text2" : "Text3") + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesWhileTyping5() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" } - NextLineOfCode(); - """, - """ - PreviousLineOfCode(); - var s3 = $"Text1 { (true ? "Text2" : "Text3") } - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWhileTyping5() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" } + NextLineOfCode(); + """, + """ + PreviousLineOfCode(); + var s3 = $"Text1 { (true ? "Text2" : "Text3") } + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesWithCS1026PresentBeforeFixIsApplied1() - { - await TestInMethodAsync( - """ - ( - var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" } - NextLineOfCode(); - """, - """ - ( - var s3 = $"Text1 { (true ? "Text2" : "Text3") } - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWithCS1026PresentBeforeFixIsApplied1() + { + await TestInMethodAsync( + """ + ( + var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" } + NextLineOfCode(); + """, + """ + ( + var s3 = $"Text1 { (true ? "Text2" : "Text3") } + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesWithCS1026PresentBeforeFixIsApplied2() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" } - NextLineOfCode( - """, - """ - PreviousLineOfCode(); - var s3 = $"Text1 { (true ? "Text2" : "Text3") } - NextLineOfCode( - """); - } + [Fact] + public async Task TestAddParenthesesWithCS1026PresentBeforeFixIsApplied2() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = $"Text1 { true ? "Text2" [|:|] "Text3" } + NextLineOfCode( + """, + """ + PreviousLineOfCode(); + var s3 = $"Text1 { (true ? "Text2" : "Text3") } + NextLineOfCode( + """); + } - [Fact] - public async Task TestAddParenthesesWithCS1026PresentBeforeFixIsApplied3() - { - await TestInMethodAsync( - """ - PreviousLineOfCode(); - var s3 = ($"Text1 { true ? "Text2" [|:|] "Text3" } - NextLineOfCode(); - """, - """ - PreviousLineOfCode(); - var s3 = ($"Text1 { (true ? "Text2" : "Text3") } - NextLineOfCode(); - """); - } + [Fact] + public async Task TestAddParenthesesWithCS1026PresentBeforeFixIsApplied3() + { + await TestInMethodAsync( + """ + PreviousLineOfCode(); + var s3 = ($"Text1 { true ? "Text2" [|:|] "Text3" } + NextLineOfCode(); + """, + """ + PreviousLineOfCode(); + var s3 = ($"Text1 { (true ? "Text2" : "Text3") } + NextLineOfCode(); + """); + } - [Fact] - public async Task TestAddParenthesesAddOpeningParenthesisOnly() - { - await TestInMethodAsync( - """ - var s3 = $"{ true ? 1 [|:|] 2 )}" - """, - """ - var s3 = $"{ (true ? 1 : 2 )}" - """); - } + [Fact] + public async Task TestAddParenthesesAddOpeningParenthesisOnly() + { + await TestInMethodAsync( + """ + var s3 = $"{ true ? 1 [|:|] 2 )}" + """, + """ + var s3 = $"{ (true ? 1 : 2 )}" + """); } } diff --git a/src/Analyzers/CSharp/Tests/ConflictMarkerResolution/ConflictMarkerResolutionTests.cs b/src/Analyzers/CSharp/Tests/ConflictMarkerResolution/ConflictMarkerResolutionTests.cs index 82c82e1e7f6c5..59ff1fc342f65 100644 --- a/src/Analyzers/CSharp/Tests/ConflictMarkerResolution/ConflictMarkerResolutionTests.cs +++ b/src/Analyzers/CSharp/Tests/ConflictMarkerResolution/ConflictMarkerResolutionTests.cs @@ -11,1634 +11,1633 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConflictMarkerResolution -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConflictMarkerResolution; + +using VerifyCS = CSharpCodeFixVerifier; - [Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)] - public class ConflictMarkerResolutionTests +[Trait(Traits.Feature, Traits.Features.CodeActionsResolveConflictMarker)] +public class ConflictMarkerResolutionTests +{ + [Fact] + public async Task TestTakeTop1() { - [Fact] - public async Task TestTakeTop1() - { - var source = """ - using System; + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:=======|} - class Program2 + } + {|CS8300:=======|} + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBottom1() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } - namespace N + [Fact] + public async Task TestTakeBottom1() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:=======|} - class Program2 + } + {|CS8300:=======|} + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program2 { - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBoth1() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeBoth1() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:=======|} - class Program2 + } + {|CS8300:=======|} + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - class Program2 + } + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 2, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyTop_TakeTop() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 2, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, + }.RunAsync(); + } - namespace N + [Fact] + public async Task TestEmptyTop_TakeTop() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + {|CS8300:=======|} + class Program2 { - {|CS8300:<<<<<<<|} This is mine! - {|CS8300:=======|} - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N - { - } - """; - - await new VerifyCS.Test + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyTop_TakeBottom() + } + """; + + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestEmptyTop_TakeBottom() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + {|CS8300:=======|} + class Program2 { - {|CS8300:<<<<<<<|} This is mine! - {|CS8300:=======|} - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program2 { - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyBottom_TakeTop() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestEmptyBottom_TakeTop() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:=======|} - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:=======|} + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyBottom_TakeBottom() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestEmptyBottom_TakeBottom() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:=======|} - {|CS8300:>>>>>>>|} This is theirs! - } - """; - var fixedSource = """ - using System; - - namespace N - { } - """; + {|CS8300:=======|} + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - await new VerifyCS.Test + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeTop_WhitespaceInSection() + } + """; + + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } - namespace N - { - {|CS8300:<<<<<<<|} This is mine! + [Fact] + public async Task TestTakeTop_WhitespaceInSection() + { + var source = """ + using System; - class Program - { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } - } + namespace N + { + {|CS8300:<<<<<<<|} This is mine! - {|CS8300:=======|} - class Program2 + class Program + { + static void Main(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; - namespace N + {|CS8300:=======|} + class Program2 { - - class Program + static void Main2(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program2 p; + Console.WriteLine("Their section"); } - } - """; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - await new VerifyCS.Test + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBottom1_WhitespaceInSection() - { - var source = """ - using System; - namespace N + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:=======|} + } + + } + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeBottom1_WhitespaceInSection() + { + var source = """ + using System; - class Program2 + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program + { + static void Main(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program p; + Console.WriteLine("My section"); } - - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:=======|} - namespace N + class Program2 { - - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - } - """; - await new VerifyCS.Test + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; + + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBoth_WhitespaceInSection() - { - var source = """ - using System; - namespace N + class Program2 { - {|CS8300:<<<<<<<|} This is mine! - - class Program + static void Main2(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program2 p; + Console.WriteLine("Their section"); } + } - {|CS8300:=======|} + } + """; - class Program2 - { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } - } + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } - {|CS8300:>>>>>>>|} This is theirs! - } - """; - var fixedSource = """ - using System; + [Fact] + public async Task TestTakeBoth_WhitespaceInSection() + { + var source = """ + using System; - namespace N - { + namespace N + { + {|CS8300:<<<<<<<|} This is mine! - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } + } + {|CS8300:=======|} - class Program2 + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - } - """; - await new VerifyCS.Test + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; + + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 2, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] - public async Task TestTakeTop_TopCommentedOut() - { - var source = """ - public class Class1 + + class Program { - public void M() + static void Main(string[] args) { - /* - <<<<<<< dest - * a thing - */ - {|CS8300:=======|} - * another thing - */ - {|CS8300:>>>>>>>|} source - // */ + Program p; + Console.WriteLine("My section"); } } - """; - var fixedSource = """ - public class Class1 + + + class Program2 { - public void M() + static void Main2(string[] args) { - /* - * a thing - */ - // */ + Program2 p; + Console.WriteLine("Their section"); } } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] - public async Task TestTakeTop_SecondMiddleAndBottomCommentedOut() + } + """; + + await new VerifyCS.Test { - var source = """ - public class Class1 + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 2, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] + public async Task TestTakeTop_TopCommentedOut() + { + var source = """ + public class Class1 + { + public void M() { - public void M() - { - {|CS8300:<<<<<<<|} dest - /* - * a thing - ======= - * - * another thing - >>>>>>> source - */ - } - } - """; - var fixedSource = """ - public class Class1 + /* + <<<<<<< dest + * a thing + */ + {|CS8300:=======|} + * another thing + */ + {|CS8300:>>>>>>>|} source + // */ + } + } + """; + var fixedSource = """ + public class Class1 + { + public void M() { - public void M() - { - /* - * a thing - */ - } + /* + * a thing + */ + // */ } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] - public async Task TestTakeTop_TopInString() + await new VerifyCS.Test { - var source = """ - class X { - void x() { - var x = @" - <<<<<<< working copy - a"; - {|CS8300:=======|} - b"; - {|CS8300:>>>>>>>|} merge rev - } - } - """; - var fixedSource = """ - class X { - void x() { - var x = @" - a"; - } - } - """; - - await new VerifyCS.Test + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] + public async Task TestTakeTop_SecondMiddleAndBottomCommentedOut() + { + var source = """ + public class Class1 { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] - public async Task TestTakeBottom_TopInString() - { - var source = """ - class X { - void x() { - var x = @" - <<<<<<< working copy - a"; - {|CS8300:=======|} - b"; - {|CS8300:>>>>>>>|} merge rev - } - } - """; - var fixedSource = """ - class X { - void x() { - var x = @" - b"; - } - } - """; - - await new VerifyCS.Test + public void M() + { + {|CS8300:<<<<<<<|} dest + /* + * a thing + ======= + * + * another thing + >>>>>>> source + */ + } + } + """; + var fixedSource = """ + public class Class1 { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] - public async Task TestMissingWithMiddleMarkerAtTopOfFile() - { - var source = """ - {|CS8300:=======|} - class X { + public void M() + { + /* + * a thing + */ } - {|CS8300:>>>>>>>|} merge rev - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] - public async Task TestMissingWithMiddleMarkerAtBottomOfFile() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] + public async Task TestTakeTop_TopInString() + { + var source = """ + class X { + void x() { + var x = @" + <<<<<<< working copy + a"; + {|CS8300:=======|} + b"; + {|CS8300:>>>>>>>|} merge rev + } + } + """; + var fixedSource = """ + class X { + void x() { + var x = @" + a"; + } + } + """; + + await new VerifyCS.Test { - var source = """ - {|CS8300:<<<<<<<|} working copy - class X { - } - {|CS8300:=======|} - """; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] + public async Task TestTakeBottom_TopInString() + { + var source = """ + class X { + void x() { + var x = @" + <<<<<<< working copy + a"; + {|CS8300:=======|} + b"; + {|CS8300:>>>>>>>|} merge rev + } + } + """; + var fixedSource = """ + class X { + void x() { + var x = @" + b"; + } + } + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } - [Fact] - public async Task TestMissingWithFirstMiddleMarkerAtBottomOfFile() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] + public async Task TestMissingWithMiddleMarkerAtTopOfFile() + { + var source = """ + {|CS8300:=======|} + class X { + } + {|CS8300:>>>>>>>|} merge rev + """; + + await new VerifyCS.Test { - var source = """ - {|CS8300:<<<<<<<|} working copy - class X { - } - {|CS8300:||||||||} - """; + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23847")] + public async Task TestMissingWithMiddleMarkerAtBottomOfFile() + { + var source = """ + {|CS8300:<<<<<<<|} working copy + class X { + } + {|CS8300:=======|} + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21107")] - public async Task TestFixAll1() + [Fact] + public async Task TestMissingWithFirstMiddleMarkerAtBottomOfFile() + { + var source = """ + {|CS8300:<<<<<<<|} working copy + class X { + } + {|CS8300:||||||||} + """; + + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - namespace N + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21107")] + public async Task TestFixAll1() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program - { - } - {|CS8300:=======|} - class Program2 - { - } - {|CS8300:>>>>>>>|} This is theirs! + } + {|CS8300:=======|} + class Program2 + { + } + {|CS8300:>>>>>>>|} This is theirs! - {|CS8300:<<<<<<<|} This is mine! - class Program3 - { - } - {|CS8300:=======|} - class Program4 - { - } - {|CS8300:>>>>>>>|} This is theirs! + {|CS8300:<<<<<<<|} This is mine! + class Program3 + { + } + {|CS8300:=======|} + class Program4 + { } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program - { - } + } - class Program3 - { - } + class Program3 + { } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 2, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21107")] - public async Task TestFixAll2() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 2, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } - namespace N + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21107")] + public async Task TestFixAll2() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program - { - } - {|CS8300:=======|} - class Program2 - { - } - {|CS8300:>>>>>>>|} This is theirs! + } + {|CS8300:=======|} + class Program2 + { + } + {|CS8300:>>>>>>>|} This is theirs! - {|CS8300:<<<<<<<|} This is mine! - class Program3 - { - } - {|CS8300:=======|} - class Program4 - { - } - {|CS8300:>>>>>>>|} This is theirs! + {|CS8300:<<<<<<<|} This is mine! + class Program3 + { } - """; - var fixedSource = """ - using System; + {|CS8300:=======|} + class Program4 + { + } + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program2 { - class Program2 - { - } + } - class Program4 - { - } + class Program4 + { } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 2, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21107")] - public async Task TestFixAll3() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 2, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21107")] + public async Task TestFixAll3() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program - { - } - {|CS8300:=======|} - class Program2 - { - } - {|CS8300:>>>>>>>|} This is theirs! + } + {|CS8300:=======|} + class Program2 + { + } + {|CS8300:>>>>>>>|} This is theirs! - {|CS8300:<<<<<<<|} This is mine! - class Program3 - { - } - {|CS8300:=======|} - class Program4 - { - } - {|CS8300:>>>>>>>|} This is theirs! + {|CS8300:<<<<<<<|} This is mine! + class Program3 + { + } + {|CS8300:=======|} + class Program4 + { } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program - { - } - class Program2 - { - } + } + class Program2 + { + } - class Program3 - { - } - class Program4 - { - } + class Program3 + { + } + class Program4 + { } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 2, - CodeActionIndex = 2, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeTop_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 2, + CodeActionIndex = 2, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeTop_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - class Program2 + } + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBottom1_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } - namespace N + [Fact] + public async Task TestTakeBottom1_WithBaseline() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - class Program2 + } + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program2 { - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBoth1_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeBoth1_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - class Program2 + } + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - class Program2 + } + class Program2 + { + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 2, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyTop_TakeTop_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 2, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, + }.RunAsync(); + } - namespace N + [Fact] + public async Task TestEmptyTop_TakeTop_WithBaseline() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + class Program2 { - {|CS8300:<<<<<<<|} This is mine! - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N - { - } - """; - - await new VerifyCS.Test + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyTop_TakeBottom_WithBaseline() + } + """; + + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestEmptyTop_TakeBottom_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + class Program2 { - {|CS8300:<<<<<<<|} This is mine! - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program2 { - class Program2 + static void Main2(string[] args) { - static void Main2(string[] args) - { - Program2 p; - Console.WriteLine("Their section"); - } + Program2 p; + Console.WriteLine("Their section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyBottom_TakeTop_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestEmptyBottom_TakeTop_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - {|CS8300:>>>>>>>|} This is theirs! } - """; - var fixedSource = """ - using System; + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestEmptyBottom_TakeBottom_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestEmptyBottom_TakeBottom_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Program p; - Console.WriteLine("My section"); - } + Program p; + Console.WriteLine("My section"); } - {|CS8300:||||||||} Baseline! - class Removed { } - {|CS8300:=======|} - {|CS8300:>>>>>>>|} This is theirs! - } - """; - var fixedSource = """ - using System; - - namespace N - { } - """; + {|CS8300:||||||||} Baseline! + class Removed { } + {|CS8300:=======|} + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - await new VerifyCS.Test + namespace N { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeTop_TopCommentedOut_WithBaseline() + } + """; + + await new VerifyCS.Test { - var source = """ - public class Class1 + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeTop_TopCommentedOut_WithBaseline() + { + var source = """ + public class Class1 + { + public void M() { - public void M() - { - /* - <<<<<<< dest - * a thing - */ - {|CS8300:||||||||} Baseline! - * previous thing - */ - {|CS8300:=======|} - * another thing - */ - {|CS8300:>>>>>>>|} source - // */ - } - } - """; - var fixedSource = """ - public class Class1 + /* + <<<<<<< dest + * a thing + */ + {|CS8300:||||||||} Baseline! + * previous thing + */ + {|CS8300:=======|} + * another thing + */ + {|CS8300:>>>>>>>|} source + // */ + } + } + """; + var fixedSource = """ + public class Class1 + { + public void M() { - public void M() - { - /* - * a thing - */ - // */ - } + /* + * a thing + */ + // */ } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeTop_FirstMiddleAndSecondMiddleAndBottomCommentedOut() + await new VerifyCS.Test { - var source = """ - public class Class1 + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeTop_FirstMiddleAndSecondMiddleAndBottomCommentedOut() + { + var source = """ + public class Class1 + { + public void M() { - public void M() - { - {|CS8300:<<<<<<<|} dest - /* - * a thing - |||||||| Baseline! - * previous thing - ======= - * - * another thing - >>>>>>> source - */ - } - } - """; - var fixedSource = """ - public class Class1 + {|CS8300:<<<<<<<|} dest + /* + * a thing + |||||||| Baseline! + * previous thing + ======= + * + * another thing + >>>>>>> source + */ + } + } + """; + var fixedSource = """ + public class Class1 + { + public void M() { - public void M() - { - /* - * a thing - */ - } + /* + * a thing + */ } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeTop_TopInString_WithBaseline() + await new VerifyCS.Test { - var source = """ - class X { - void x() { - var x = @" - <<<<<<< working copy - a"; - {|CS8300:||||||||} baseline - previous"; - {|CS8300:=======|} - b"; - {|CS8300:>>>>>>>|} merge rev - } - } - """; - var fixedSource = """ - class X { - void x() { - var x = @" - a"; - } - } - """; - - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestTakeBottom_TopInString_WithBaseline() - { - var source = """ - class X { - void x() { - var x = @" - <<<<<<< working copy - a"; - {|CS8300:||||||||} baseline - previous"; - {|CS8300:=======|} - b"; - {|CS8300:>>>>>>>|} merge rev - } - } - """; - var fixedSource = """ - class X { - void x() { - var x = @" - b"; - } - } - """; - - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestMissingWithFirstMiddleMarkerAtTopOfFile() + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestTakeTop_TopInString_WithBaseline() + { + var source = """ + class X { + void x() { + var x = @" + <<<<<<< working copy + a"; + {|CS8300:||||||||} baseline + previous"; + {|CS8300:=======|} + b"; + {|CS8300:>>>>>>>|} merge rev + } + } + """; + var fixedSource = """ + class X { + void x() { + var x = @" + a"; + } + } + """; + + await new VerifyCS.Test { - var source = """ - {|CS8300:||||||||} baseline - {|CS8300:=======|} - class X { - } - {|CS8300:>>>>>>>|} merge rev - """; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + [Fact] + public async Task TestTakeBottom_TopInString_WithBaseline() + { + var source = """ + class X { + void x() { + var x = @" + <<<<<<< working copy + a"; + {|CS8300:||||||||} baseline + previous"; + {|CS8300:=======|} + b"; + {|CS8300:>>>>>>>|} merge rev + } + } + """; + var fixedSource = """ + class X { + void x() { + var x = @" + b"; + } + } + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } - [Fact] - public async Task TestFixAll1_WithBaseline() + [Fact] + public async Task TestMissingWithFirstMiddleMarkerAtTopOfFile() + { + var source = """ + {|CS8300:||||||||} baseline + {|CS8300:=======|} + class X { + } + {|CS8300:>>>>>>>|} merge rev + """; + + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - namespace N + [Fact] + public async Task TestFixAll1_WithBaseline() + { + var source = """ + using System; + + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program - { - } - {|CS8300:||||||||} baseline - class Removed { } - {|CS8300:=======|} - class Program2 - { - } - {|CS8300:>>>>>>>|} This is theirs! + } + {|CS8300:||||||||} baseline + class Removed { } + {|CS8300:=======|} + class Program2 + { + } + {|CS8300:>>>>>>>|} This is theirs! - {|CS8300:<<<<<<<|} This is mine! - class Program3 - { - } - {|CS8300:||||||||} baseline - class Removed2 { } - {|CS8300:=======|} - class Program4 - { - } - {|CS8300:>>>>>>>|} This is theirs! + {|CS8300:<<<<<<<|} This is mine! + class Program3 + { } - """; - var fixedSource = """ - using System; + {|CS8300:||||||||} baseline + class Removed2 { } + {|CS8300:=======|} + class Program4 + { + } + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program - { - } + } - class Program3 - { - } + class Program3 + { } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 2, - CodeActionIndex = 0, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestFixAll2_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 2, + CodeActionIndex = 0, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeTopEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestFixAll2_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program - { - } - {|CS8300:||||||||} baseline - class Removed { } - {|CS8300:=======|} - class Program2 - { - } - {|CS8300:>>>>>>>|} This is theirs! + } + {|CS8300:||||||||} baseline + class Removed { } + {|CS8300:=======|} + class Program2 + { + } + {|CS8300:>>>>>>>|} This is theirs! - {|CS8300:<<<<<<<|} This is mine! - class Program3 - { - } - {|CS8300:||||||||} baseline - class Removed2 { } - {|CS8300:=======|} - class Program4 - { - } - {|CS8300:>>>>>>>|} This is theirs! + {|CS8300:<<<<<<<|} This is mine! + class Program3 + { } - """; - var fixedSource = """ - using System; + {|CS8300:||||||||} baseline + class Removed2 { } + {|CS8300:=======|} + class Program4 + { + } + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program2 { - class Program2 - { - } + } - class Program4 - { - } + class Program4 + { } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 2, - CodeActionIndex = 1, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, - }.RunAsync(); - } - - [Fact] - public async Task TestFixAll3_WithBaseline() + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 2, + CodeActionIndex = 1, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBottomEquivalenceKey, + }.RunAsync(); + } + + [Fact] + public async Task TestFixAll3_WithBaseline() + { + var source = """ + using System; - namespace N + namespace N + { + {|CS8300:<<<<<<<|} This is mine! + class Program { - {|CS8300:<<<<<<<|} This is mine! - class Program - { - } - {|CS8300:||||||||} baseline - class Removed { } - {|CS8300:=======|} - class Program2 - { - } - {|CS8300:>>>>>>>|} This is theirs! + } + {|CS8300:||||||||} baseline + class Removed { } + {|CS8300:=======|} + class Program2 + { + } + {|CS8300:>>>>>>>|} This is theirs! - {|CS8300:<<<<<<<|} This is mine! - class Program3 - { - } - {|CS8300:||||||||} baseline - class Removed2 { } - {|CS8300:=======|} - class Program4 - { - } - {|CS8300:>>>>>>>|} This is theirs! + {|CS8300:<<<<<<<|} This is mine! + class Program3 + { + } + {|CS8300:||||||||} baseline + class Removed2 { } + {|CS8300:=======|} + class Program4 + { } - """; - var fixedSource = """ - using System; + {|CS8300:>>>>>>>|} This is theirs! + } + """; + var fixedSource = """ + using System; - namespace N + namespace N + { + class Program { - class Program - { - } - class Program2 - { - } + } + class Program2 + { + } - class Program3 - { - } - class Program4 - { - } + class Program3 + { + } + class Program4 + { } - """; + } + """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - NumberOfIncrementalIterations = 2, - CodeActionIndex = 2, - CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + NumberOfIncrementalIterations = 2, + CodeActionIndex = 2, + CodeActionEquivalenceKey = AbstractResolveConflictMarkerCodeFixProvider.TakeBothEquivalenceKey, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToBlockScopedNamespaceAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToBlockScopedNamespaceAnalyzerTests.cs index 665886446bf68..aa486c15513a7 100644 --- a/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToBlockScopedNamespaceAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToBlockScopedNamespaceAnalyzerTests.cs @@ -13,581 +13,580 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace; + +using VerifyCS = CSharpCodeFixVerifier; - public class ConvertToBlockScopedNamespaceAnalyzerTests +public class ConvertToBlockScopedNamespaceAnalyzerTests +{ + public static IEnumerable EndOfDocumentSequences { - public static IEnumerable EndOfDocumentSequences + get { - get - { - yield return new object[] { "" }; - yield return new object[] { "\r\n" }; - } + yield return new object[] { "" }; + yield return new object[] { "\r\n" }; } + } - #region Convert To Block Scoped + #region Convert To Block Scoped - [Fact] - public async Task TestConvertToBlockScopedInCSharp9() + [Fact] + public async Task TestConvertToBlockScopedInCSharp9() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|{|CS8773:namespace|} N;|] + """, + FixedCode = """ + namespace N { - TestCode = """ - [|{|CS8773:namespace|} N;|] - """, - FixedCode = """ - namespace N - { - } - """, - LanguageVersion = LanguageVersion.CSharp9, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedInCSharp9_NotSilent() + [Fact] + public async Task TestConvertToBlockScopedInCSharp9_NotSilent() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + {|CS8773:namespace|} [|N|]; + """, + FixedCode = """ + namespace N { - TestCode = """ - {|CS8773:namespace|} [|N|]; - """, - FixedCode = """ - namespace N - { - } - """, - LanguageVersion = LanguageVersion.CSharp9, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped, NotificationOption2.Suggestion } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped, NotificationOption2.Suggestion } + } + }.RunAsync(); + } - [Fact] - public async Task TestNoConvertToBlockScopedInCSharp10WithBlockScopedPreference() + [Fact] + public async Task TestNoConvertToBlockScopedInCSharp10WithBlockScopedPreference() + { + var code = """ + namespace N {} + """; + await new VerifyCS.Test { - var code = """ - namespace N {} - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockScopedInCSharp10WithFileScopedPreference(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockScopedInCSharp10WithFileScopedPreference(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + [|namespace N;|]{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N { - TestCode = $$""" - [|namespace N;|]{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockScopedInCSharp10WithDirectives1(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockScopedInCSharp10WithDirectives1(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + [|namespace N;|] + + #if true + #endif{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N { - TestCode = $$""" - [|namespace N;|] - - #if true - #endif{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - #if true - #endif - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + #if true + #endif + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockScopedInCSharp10WithDirectives2(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockScopedInCSharp10WithDirectives2(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + [|namespace N;|] + + #region Text + #endregion{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N { - TestCode = $$""" - [|namespace N;|] - #region Text - #endregion{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - #region Text - #endregion - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + #endregion + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockWithMultipleNamespaces(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockWithMultipleNamespaces(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - [|namespace N;|] + TestCode = $$""" + [|namespace N;|] - namespace {|CS8955:N2|} - { - }{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - namespace N2 - { - } - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = + namespace {|CS8955:N2|} + { + }{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N + { + namespace N2 { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockWithNestedNamespaces1(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockWithNestedNamespaces1(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - [|namespace N;|] + TestCode = $$""" + [|namespace N;|] - [|namespace {|CS8954:N2|};|]{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - namespace N2 - { - } - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - NumberOfFixAllIterations = 2, - Options = + [|namespace {|CS8954:N2|};|]{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N + { + namespace N2 { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + NumberOfFixAllIterations = 2, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockWithNestedNamespaces2(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockWithNestedNamespaces2(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + namespace N { - TestCode = $$""" - namespace N - { - [|namespace {|CS8955:N2|};|] - }{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - namespace $$N2 - { - } - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = + [|namespace {|CS8955:N2|};|] + }{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N + { + namespace $$N2 { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockWithNestedNamespaces3(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockWithNestedNamespaces3(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + namespace N { - TestCode = $$""" - namespace N - { - [|namespace {|CS8955:N2|};|] - }{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - namespace $$N2 { - } - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }, - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue & ~NewLineBeforeOpenBracePlacement.Types }, + [|namespace {|CS8955:N2|};|] + }{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N + { + namespace $$N2 { } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped }, + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue & ~NewLineBeforeOpenBracePlacement.Types }, + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockWithNestedNamespaces4(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockWithNestedNamespaces4(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + namespace N { - TestCode = $$""" - namespace N - { - [|namespace {|CS8955:N2|};|] - - #if true - #endif - }{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - namespace $$N2 - { - #if true - #endif - } - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = + [|namespace {|CS8955:N2|};|] + + #if true + #endif + }{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N + { + namespace $$N2 { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + #if true + #endif } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Theory] - [MemberData(nameof(EndOfDocumentSequences))] - public async Task TestConvertToBlockWithNestedNamespaces5(string endOfDocumentSequence) + [Theory] + [MemberData(nameof(EndOfDocumentSequences))] + public async Task TestConvertToBlockWithNestedNamespaces5(string endOfDocumentSequence) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = $$""" + namespace N { - TestCode = $$""" - namespace N - { - [|namespace {|CS8955:N2|};|] + [|namespace {|CS8955:N2|};|] + #region Text + #endregion + }{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace N + { + namespace $$N2 + { #region Text #endregion - }{{endOfDocumentSequence}} - """, - FixedCode = $$""" - namespace N - { - namespace $$N2 - { - #region Text - #endregion - } - }{{endOfDocumentSequence}} - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } } - }.RunAsync(); - } + }{{endOfDocumentSequence}} + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockWithTopLevelStatement1() + [Fact] + public async Task TestConvertToBlockWithTopLevelStatement1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - {|CS8805:int i = 0;|} + TestCode = """ + {|CS8805:int i = 0;|} - [|namespace {|CS8956:N|};|] - """, - FixedCode = """ - {|CS8805:int i = 0;|} + [|namespace {|CS8956:N|};|] + """, + FixedCode = """ + {|CS8805:int i = 0;|} - namespace N - { - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + namespace N + { + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockWithTopLevelStatement2() + [Fact] + public async Task TestConvertToBlockWithTopLevelStatement2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N;|] + TestCode = """ + [|namespace N;|] + int {|CS0116:i|} = 0; + """, + FixedCode = """ + namespace N + { int {|CS0116:i|} = 0; - """, - FixedCode = """ - namespace N - { - int {|CS0116:i|} = 0; - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithUsing1() + [Fact] + public async Task TestConvertToBlockScopedWithUsing1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - [|namespace N;|] - """, - FixedCode = """ - using System; + [|namespace N;|] + """, + FixedCode = """ + using System; - namespace N - { - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + namespace N + { + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithUsing2() + [Fact] + public async Task TestConvertToBlockScopedWithUsing2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N;|] + TestCode = """ + [|namespace N;|] + using System; + """, + FixedCode = """ + namespace $$N + { using System; - """, - FixedCode = """ - namespace $$N - { - using System; - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithClass() + [Fact] + public async Task TestConvertToBlockScopedWithClass() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N;|] + TestCode = """ + [|namespace N;|] + class C + { + } + """, + FixedCode = """ + namespace $$N + { class C { } - """, - FixedCode = """ - namespace $$N - { - class C - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithClassWithDocComment() + [Fact] + public async Task TestConvertToBlockScopedWithClassWithDocComment() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N;|] + TestCode = """ + [|namespace N;|] + /// + class C + { + } + """, + FixedCode = """ + namespace N + { /// class C { } - """, - FixedCode = """ - namespace N - { - /// - class C - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithMissingCloseBrace() + [Fact] + public async Task TestConvertToBlockScopedWithMissingCloseBrace() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N;|] + + /// + class C + {{|CS1513:|} + """, + FixedCode = """ + namespace N { - TestCode = """ - [|namespace N;|] - /// class C - {{|CS1513:|} - """, - FixedCode = """ - namespace N { - /// - class C - { - }{|CS1513:|} - """, - LanguageVersion = LanguageVersion.CSharp10, - CodeActionValidationMode = CodeActionValidationMode.None, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + }{|CS1513:|} + """, + LanguageVersion = LanguageVersion.CSharp10, + CodeActionValidationMode = CodeActionValidationMode.None, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithCommentOnSemicolon() + [Fact] + public async Task TestConvertToBlockScopedWithCommentOnSemicolon() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N;|] // comment + TestCode = """ + [|namespace N;|] // comment + class C + { + } + """, + FixedCode = """ + namespace N + { // comment class C { } - """, - FixedCode = """ - namespace N - { // comment - class C - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToBlockScopedWithLeadingComment() + [Fact] + public async Task TestConvertToBlockScopedWithLeadingComment() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - // copyright - [|namespace N;|] + TestCode = """ + // copyright + [|namespace N;|] + class C + { + } + """, + FixedCode = """ + // copyright + namespace N + { class C { } - """, - FixedCode = """ - // copyright - namespace N - { - class C - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } - - #endregion + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); } + + #endregion } diff --git a/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs index f8649c1d1242d..1dd2c0d898974 100644 --- a/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs @@ -12,700 +12,679 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace; + +using VerifyCS = CSharpCodeFixVerifier; - public sealed class ConvertToFileScopedNamespaceAnalyzerTests +public sealed class ConvertToFileScopedNamespaceAnalyzerTests +{ + [Fact] + public async Task TestNoConvertToFileScopedInCSharp9() { - [Fact] - public async Task TestNoConvertToFileScopedInCSharp9() + var code = """ + namespace N + { + } + """; + await new VerifyCS.Test { - var code = """ - namespace N - { - } - """; - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp9, + Options = { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp9, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestNoConvertToFileScopedInCSharp10WithBlockScopedPreference() + [Fact] + public async Task TestNoConvertToFileScopedInCSharp10WithBlockScopedPreference() + { + var code = """ + namespace N + { + } + """; + await new VerifyCS.Test { - var code = """ - namespace N - { - } - """; - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + Options = { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference() + [Fact] + public async Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace N|] - { - } - """, - FixedCode = """ - namespace $$N; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference_NotSilent() + [Fact] + public async Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference_NotSilent() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + namespace [|N|] { - TestCode = """ - namespace [|N|] - { - } - """, - FixedCode = """ - namespace $$N; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped, NotificationOption2.Suggestion } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped, NotificationOption2.Suggestion } + } + }.RunAsync(); + } + + [Fact] + public async Task TestNoConvertWithMultipleNamespaces() + { + var code = """ + namespace N + { + } - [Fact] - public async Task TestNoConvertWithMultipleNamespaces() + namespace N2 + { + } + """; + await new VerifyCS.Test { - var code = """ - namespace N - { - } + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - namespace N2 - { - } - """; - await new VerifyCS.Test + [Fact] + public async Task TestNoConvertWithNestedNamespaces1() + { + var code = """ + namespace N { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - Options = + namespace N2 { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoConvertWithNestedNamespaces1() + } + """; + await new VerifyCS.Test { - var code = """ - namespace N - { - namespace N2 - { - } - } - """; - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + Options = { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestNoConvertWithTopLevelStatement1() - { - var code = """ - {|CS8805:int i = 0;|} + [Fact] + public async Task TestNoConvertWithTopLevelStatement1() + { + var code = """ + {|CS8805:int i = 0;|} - namespace N - { - } - """; - await new VerifyCS.Test + namespace N { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } - - [Fact] - public async Task TestNoConvertWithTopLevelStatement2() + } + """; + await new VerifyCS.Test { - var code = """ - namespace N - { - } + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - int i = 0; - """; - await new VerifyCS.Test + [Fact] + public async Task TestNoConvertWithTopLevelStatement2() + { + var code = """ + namespace N { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - ExpectedDiagnostics = - { - // /0/Test0.cs(6,1): error CS8803: Top-level statements must precede namespace and type declarations. - DiagnosticResult.CompilerError("CS8803").WithSpan(5, 1, 5, 11), - // /0/Test0.cs(6,1): error CS8805: Program using top-level statements must be an executable. - DiagnosticResult.CompilerError("CS8805").WithSpan(5, 1, 5, 11), - }, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } - [Fact] - public async Task TestConvertToFileScopedWithUsing1() + int i = 0; + """; + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + ExpectedDiagnostics = { - TestCode = """ - using System; + // /0/Test0.cs(6,1): error CS8803: Top-level statements must precede namespace and type declarations. + DiagnosticResult.CompilerError("CS8803").WithSpan(5, 1, 5, 11), + // /0/Test0.cs(6,1): error CS8805: Program using top-level statements must be an executable. + DiagnosticResult.CompilerError("CS8805").WithSpan(5, 1, 5, 11), + }, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [|namespace N|] - { - } - """, - FixedCode = """ - using System; + [Fact] + public async Task TestConvertToFileScopedWithUsing1() + { + await new VerifyCS.Test + { + TestCode = """ + using System; - namespace $$N; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + [|namespace N|] + { + } + """, + FixedCode = """ + using System; + + namespace $$N; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToFileScopedWithUsing2() + [Fact] + public async Task TestConvertToFileScopedWithUsing2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace N|] - { - using System; - } - """, - FixedCode = """ - namespace $$N; - using System; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; + + using System; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToFileScopedWithClass() + [Fact] + public async Task TestConvertToFileScopedWithClass() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace N|] - { - class C - { - } - } - """, - FixedCode = """ - namespace $$N; - class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithClassWithDocComment() - { - await new VerifyCS.Test + class C { - TestCode = """ - [|namespace N|] - { - /// - class C - { - } - } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithClassWithDocComment() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { /// class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithMissingCloseBrace() - { - await new VerifyCS.Test + /// + class C { - TestCode = """ - [|namespace N|] - { - /// - class C - { - }{|CS1513:|} - """, - FixedCode = """ - namespace N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithMissingCloseBrace() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { /// class C { - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + }{|CS1513:|} + """, + FixedCode = """ + namespace N; - [Fact] - public async Task TestConvertToFileScopedWithCommentOnOpenCurly() - { - await new VerifyCS.Test + /// + class C { - TestCode = """ - [|namespace N|] - { // comment - class C - { - } - } - """, - FixedCode = """ - namespace $$N; - // comment + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + + [Fact] + public async Task TestConvertToFileScopedWithCommentOnOpenCurly() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { // comment class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; + // comment + class C + { + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestConvertToFileScopedWithLeadingComment() + [Fact] + public async Task TestConvertToFileScopedWithLeadingComment() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + // copyright + [|namespace N|] { - TestCode = """ - // copyright - [|namespace N|] - { - class C - { - } - } - """, - FixedCode = """ - // copyright - namespace $$N; - class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + // copyright + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithDocComment() - { - await new VerifyCS.Test + class C { - TestCode = """ - [|namespace N|] - { - /// - class C - { - } - } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithDocComment() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { /// class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithPPDirective1() - { - await new VerifyCS.Test + /// + class C { - TestCode = """ - [|namespace N|] - { - #if X - class C - { - } - #else - class C - { - } - #endif - } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - #if X + [Fact] + public async Task TestConvertToFileScopedWithPPDirective1() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { + #if X class C { } - #else + #else class C { } - #endif + #endif + } + """, + FixedCode = """ + namespace $$N; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + #if X + class C + { + } + #else + class C + { + } + #endif - [Fact] - public async Task TestConvertToFileScopedWithBlockComment() - { - await new VerifyCS.Test + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = { - TestCode = """ - [|namespace N|] - { - /* x - * x - */ - class C - { - } - } - """, - FixedCode = """ - namespace $$N; + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithBlockComment() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { /* x * x */ class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithBlockComment2() - { - await new VerifyCS.Test + /* x + * x + */ + class C { - TestCode = """ - [|namespace N|] - { - /* x - x - */ - class C - { - } - } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithBlockComment2() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { /* x x */ class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithMultilineString() - { - await new VerifyCS.Test + /* x + x + */ + class C { - TestCode = """ - [|namespace N|] - { - class C - { - void M() - { - System.Console.WriteLine(@" - a - b - c - d - e - "); - } - } - } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithMultilineString() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { class C { void M() { System.Console.WriteLine(@" - a - b - c - d - e - "); + a + b + c + d + e + "); } } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithMultilineString2() - { - await new VerifyCS.Test + class C { - TestCode = """ - [|namespace N|] + void M() { - class C - { - void M() - { - System.Console.WriteLine($@" - a - b - c{1 + 1} - d - e - "); - } - } + System.Console.WriteLine(@" + a + b + c + d + e + "); } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithMultilineString2() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { class C { void M() { System.Console.WriteLine($@" - a - b - c{1 + 1} - d - e - "); + a + b + c{1 + 1} + d + e + "); } } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedWithMultilineString3() - { - await new VerifyCS.Test + class C { - TestCode = """ - [|namespace N|] + void M() { - class C - { - void M() - { - System.Console.WriteLine($@" - a - b - c{ - 1 + 1 - }d - e - "); - } - } + System.Console.WriteLine($@" + a + b + c{1 + 1} + d + e + "); } - """, - FixedCode = """ - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestConvertToFileScopedWithMultilineString3() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace N|] + { class C { void M() { System.Console.WriteLine($@" - a - b - c{ + a + b + c{ 1 + 1 }d - e - "); + e + "); } } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Theory, InlineData(""), InlineData("u8")] - public async Task TestConvertToFileScopedWithMultiLineRawString1(string suffix) - { - await new VerifyCS.Test + class C { - TestCode = $$"""" - [|namespace N|] + void M() { - class C - { - void M() - { - WriteLine(""" - a - b - c - d - e - """{{suffix}}); - } - - void WriteLine(string s) { } - void WriteLine(System.ReadOnlySpan s) { } - } + System.Console.WriteLine($@" + a + b + c{ + 1 + 1 + }d + e + "); } - """", - FixedCode = $$"""" - namespace $$N; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Theory, InlineData(""), InlineData("u8")] + public async Task TestConvertToFileScopedWithMultiLineRawString1(string suffix) + { + await new VerifyCS.Test + { + TestCode = $$"""" + [|namespace N|] + { class C { void M() @@ -718,443 +697,434 @@ void M() e """{{suffix}}); } - + void WriteLine(string s) { } void WriteLine(System.ReadOnlySpan s) { } } - """", - LanguageVersion = LanguageVersion.CSharp12, - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """", + FixedCode = $$"""" + namespace $$N; - [Theory, InlineData(""), InlineData("u8")] - public async Task TestConvertToFileScopedWithMultiLineRawString2(string suffix) - { - await new VerifyCS.Test + class C { - TestCode = $$"""" - [|namespace N|] - { - class C - { - void M() - { - WriteLine(""" - a - b - c - d - e - """{{suffix}}); - } - - void WriteLine(string s) { } - void WriteLine(System.ReadOnlySpan s) { } - } - } - """", - FixedCode = $$"""" - namespace $$N; + void M() + { + WriteLine(""" + a + b + c + d + e + """{{suffix}}); + } + + void WriteLine(string s) { } + void WriteLine(System.ReadOnlySpan s) { } + } + """", + LanguageVersion = LanguageVersion.CSharp12, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Theory, InlineData(""), InlineData("u8")] + public async Task TestConvertToFileScopedWithMultiLineRawString2(string suffix) + { + await new VerifyCS.Test + { + TestCode = $$"""" + [|namespace N|] + { class C { void M() { WriteLine(""" - a - b - c - d - e - """{{suffix}}); + a + b + c + d + e + """{{suffix}}); } - + void WriteLine(string s) { } void WriteLine(System.ReadOnlySpan s) { } } - """", - LanguageVersion = LanguageVersion.CSharp12, - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """", + FixedCode = $$"""" + namespace $$N; - [Theory, InlineData(""), InlineData("u8")] - public async Task TestConvertToFileScopedWithMultiLineRawString3(string suffix) - { - await new VerifyCS.Test + class C { - TestCode = $$"""" - [|namespace N|] - { - class C - { - void M() - { - System.Console.WriteLine(""" - {|CS8999:|}a // error - b - c - d - e - """{{suffix}}); - } - - void WriteLine(string s) { } - void WriteLine(System.ReadOnlySpan s) { } - } - } - """", - FixedCode = $$"""" - namespace $$N; + void M() + { + WriteLine(""" + a + b + c + d + e + """{{suffix}}); + } + + void WriteLine(string s) { } + void WriteLine(System.ReadOnlySpan s) { } + } + """", + LanguageVersion = LanguageVersion.CSharp12, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Theory, InlineData(""), InlineData("u8")] + public async Task TestConvertToFileScopedWithMultiLineRawString3(string suffix) + { + await new VerifyCS.Test + { + TestCode = $$"""" + [|namespace N|] + { class C { void M() { System.Console.WriteLine(""" - {|CS8999:|}a // error - b - c - d - e - """{{suffix}}); + {|CS8999:|}a // error + b + c + d + e + """{{suffix}}); } - + void WriteLine(string s) { } void WriteLine(System.ReadOnlySpan s) { } } - """", - LanguageVersion = LanguageVersion.CSharp12, - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } - - [Fact] - public async Task TestConvertToFileScopedSingleLineNamespace1() - { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N|] { class C { } } - """, - FixedCode = """ - namespace $$N; class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """", + FixedCode = $$"""" + namespace $$N; - [Fact] - public async Task TestConvertToFileScopedSingleLineNamespace2() - { - await new VerifyCS.Test - { - TestCode = """ - [|namespace N|] - { class C { } } - """, - FixedCode = """ - namespace $$N; - class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = + class C + { + void M() { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + System.Console.WriteLine(""" + {|CS8999:|}a // error + b + c + d + e + """{{suffix}}); } - }.RunAsync(); - } + + void WriteLine(string s) { } + void WriteLine(System.ReadOnlySpan s) { } + } + """", + LanguageVersion = LanguageVersion.CSharp12, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedWithNoNewlineAtEnd() + [Fact] + public async Task TestConvertToFileScopedSingleLineNamespace1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { class C { } } + """, + FixedCode = """ + namespace $$N; class C { } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = { - TestCode = """ - [|namespace N|] - { - class C - { - } - } - """, - FixedCode = """ - namespace $$N; - - class C - { - } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedWithNoMembersAndNoNewlineAtEnd() + [Fact] + public async Task TestConvertToFileScopedSingleLineNamespace2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] + { class C { } } + """, + FixedCode = """ + namespace $$N; + class C { } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = { - TestCode = """ - [|namespace N|] - { - } - """, - FixedCode = """ - namespace $$N; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedPreserveNewlineAtEnd() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedWithNoNewlineAtEnd() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace N|] - { - class C - { - } - } - """, - FixedCode = """ - namespace $$N; - class C { } - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedWithNoMembersPreserveNewlineAtEnd() + class C + { + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedWithNoMembersAndNoNewlineAtEnd() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace N|] - { - } - """, - FixedCode = """ - namespace $$N; - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + } + """, + FixedCode = """ + namespace $$N; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedPPDirective1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedPreserveNewlineAtEnd() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace Goo|] + class C { - #if true - class goobar { } - #endif - // There must be no CR, LF, or other character after the brace on the following line! } - """, - FixedCode = """ - namespace $$Goo; + } + """, + FixedCode = """ + namespace $$N; - #if true - class goobar { } - #endif - // There must be no CR, LF, or other character after the brace on the following line! - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + class C + { + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedPPDirective2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedWithNoMembersPreserveNewlineAtEnd() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace N|] { - TestCode = """ - [|namespace Goo|] - { - #if true - class goobar { } - #endif - // There must be no CR, LF, or other character after the brace on the following line! - } - - """, - FixedCode = """ - namespace $$Goo; + } + """, + FixedCode = """ + namespace $$N; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - #if true + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedPPDirective1() + { + await new VerifyCS.Test + { + TestCode = """ + [|namespace Goo|] + { + #if true class goobar { } - #endif - // There must be no CR, LF, or other character after the brace on the following line! - - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + #endif + // There must be no CR, LF, or other character after the brace on the following line! + } + """, + FixedCode = """ + namespace $$Goo; + + #if true + class goobar { } + #endif + // There must be no CR, LF, or other character after the brace on the following line! + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedPPDirective3() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedPPDirective2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace Goo|] { - TestCode = """ - [|namespace Goo|] - { - #if false - class goobar { } - #endif - } - """, - FixedCode = """ - namespace $$Goo; - - #if false + #if true class goobar { } - #endif - - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + #endif + // There must be no CR, LF, or other character after the brace on the following line! + } + + """, + FixedCode = """ + namespace $$Goo; + + #if true + class goobar { } + #endif + // There must be no CR, LF, or other character after the brace on the following line! + + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] - public async Task TestConvertToFileScopedPPDirective4() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedPPDirective3() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace Goo|] { - TestCode = """ - [|namespace Goo|] - { - #if false - class goobar { } - #endif - } - - """, - FixedCode = """ - namespace $$Goo; - - #if false + #if false class goobar { } - #endif - - """, - LanguageVersion = LanguageVersion.CSharp10, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } - } - }.RunAsync(); - } + #endif + } + """, + FixedCode = """ + namespace $$Goo; + + #if false + class goobar { } + #endif + + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } - [Fact] - public async Task TestInterpolatedRawString1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedPPDirective4() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + [|namespace Goo|] { - TestCode = """" - [|namespace Microsoft.CodeAnalysis.SQLite.v2|] - { - internal partial class SQLitePersistentStorage - { - private abstract class Accessor - where TDatabaseKey : struct - { - private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + #if false + class goobar { } + #endif + } - public Accessor() - { - _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - insert or replace into {0}.{1} - ({2}) - """; + """, + FixedCode = """ + namespace $$Goo; - return; + #if false + class goobar { } + #endif - string GetSelectRowIdQuery(string database) - => $""" - select rowid from {0}.{1} where - {2} - limit 1 - """; - } - } - } - } - """", - FixedCode = """" - namespace $$Microsoft.CodeAnalysis.SQLite.v2; + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestInterpolatedRawString1() + { + await new VerifyCS.Test + { + TestCode = """" + [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + { internal partial class SQLitePersistentStorage { private abstract class Accessor where TDatabaseKey : struct { private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - + public Accessor() { _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" insert or replace into {0}.{1} ({2}) """; - + return; - + string GetSelectRowIdQuery(string database) => $""" select rowid from {0}.{1} where @@ -1164,68 +1134,69 @@ limit 1 } } } - """", - LanguageVersion = LanguageVersion.CSharp11, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } } - }.RunAsync(); - } + """", + FixedCode = """" + namespace $$Microsoft.CodeAnalysis.SQLite.v2; - [Fact] - public async Task TestInterpolatedRawString2() - { - await new VerifyCS.Test - { - TestCode = """" - [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + internal partial class SQLitePersistentStorage + { + private abstract class Accessor + where TDatabaseKey : struct { - internal partial class SQLitePersistentStorage + private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + + public Accessor() { - private abstract class Accessor - where TDatabaseKey : struct - { - private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - - public Accessor() - { - _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - insert or replace into {0}.{1} - ({2}) - """; - - return; - - string GetSelectRowIdQuery(string database) => $""" - select rowid from {0}.{1} where - {2} - limit 1 - """; - } - } + _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" + insert or replace into {0}.{1} + ({2}) + """; + + return; + + string GetSelectRowIdQuery(string database) + => $""" + select rowid from {0}.{1} where + {2} + limit 1 + """; } } - """", - FixedCode = """" - namespace $$Microsoft.CodeAnalysis.SQLite.v2; + } + """", + LanguageVersion = LanguageVersion.CSharp11, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestInterpolatedRawString2() + { + await new VerifyCS.Test + { + TestCode = """" + [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + { internal partial class SQLitePersistentStorage { private abstract class Accessor where TDatabaseKey : struct { private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - + public Accessor() { _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" insert or replace into {0}.{1} ({2}) """; - + return; - + string GetSelectRowIdQuery(string database) => $""" select rowid from {0}.{1} where {2} @@ -1234,69 +1205,68 @@ limit 1 } } } - """", - LanguageVersion = LanguageVersion.CSharp11, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } } - }.RunAsync(); - } + """", + FixedCode = """" + namespace $$Microsoft.CodeAnalysis.SQLite.v2; - [Fact] - public async Task TestInterpolatedRawString3() - { - await new VerifyCS.Test - { - TestCode = """" - [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + internal partial class SQLitePersistentStorage + { + private abstract class Accessor + where TDatabaseKey : struct { - internal partial class SQLitePersistentStorage + private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + + public Accessor() { - private abstract class Accessor - where TDatabaseKey : struct - { - private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - - public Accessor() - { - _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - insert or replace into {0}.{1} - ({2}) - """; - - return; - - string GetSelectRowIdQuery(string database) => - $""" - select rowid from {0}.{1} where - {2} - limit 1 - """; - } - } + _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" + insert or replace into {0}.{1} + ({2}) + """; + + return; + + string GetSelectRowIdQuery(string database) => $""" + select rowid from {0}.{1} where + {2} + limit 1 + """; } } - """", - FixedCode = """" - namespace $$Microsoft.CodeAnalysis.SQLite.v2; + } + """", + LanguageVersion = LanguageVersion.CSharp11, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestInterpolatedRawString3() + { + await new VerifyCS.Test + { + TestCode = """" + [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + { internal partial class SQLitePersistentStorage { private abstract class Accessor where TDatabaseKey : struct { private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - + public Accessor() { _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" insert or replace into {0}.{1} ({2}) """; - + return; - + string GetSelectRowIdQuery(string database) => $""" select rowid from {0}.{1} where @@ -1306,67 +1276,60 @@ limit 1 } } } - """", - LanguageVersion = LanguageVersion.CSharp11, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } } - }.RunAsync(); - } + """", + FixedCode = """" + namespace $$Microsoft.CodeAnalysis.SQLite.v2; - [Fact] - public async Task TestInterpolatedRawString4() - { - await new VerifyCS.Test - { - TestCode = """" - [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + internal partial class SQLitePersistentStorage + { + private abstract class Accessor + where TDatabaseKey : struct { - internal partial class SQLitePersistentStorage + private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + + public Accessor() { - private abstract class Accessor - where TDatabaseKey : struct - { - private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - - public Accessor() - { - _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - - insert or replace into {0}.{1} - - ({2}) - - """; - - return; - - string GetSelectRowIdQuery(string database) - => $""" - - select rowid from {0}.{1} where - - {2} - - limit 1 - - """; - } - } + _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" + insert or replace into {0}.{1} + ({2}) + """; + + return; + + string GetSelectRowIdQuery(string database) => + $""" + select rowid from {0}.{1} where + {2} + limit 1 + """; } } - """", - FixedCode = """" - namespace $$Microsoft.CodeAnalysis.SQLite.v2; + } + """", + LanguageVersion = LanguageVersion.CSharp11, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestInterpolatedRawString4() + { + await new VerifyCS.Test + { + TestCode = """" + [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + { internal partial class SQLitePersistentStorage { private abstract class Accessor where TDatabaseKey : struct { private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - + public Accessor() { _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" @@ -1376,9 +1339,9 @@ insert or replace into {0}.{1} ({2}) """; - + return; - + string GetSelectRowIdQuery(string database) => $""" @@ -1392,69 +1355,76 @@ limit 1 } } } - """", - LanguageVersion = LanguageVersion.CSharp11, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } } - }.RunAsync(); - } + """", + FixedCode = """" + namespace $$Microsoft.CodeAnalysis.SQLite.v2; - [Fact] - public async Task TestInterpolatedRawString5() - { - await new VerifyCS.Test - { - TestCode = """" - [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + internal partial class SQLitePersistentStorage + { + private abstract class Accessor + where TDatabaseKey : struct { - internal partial class SQLitePersistentStorage + private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + + public Accessor() { - private abstract class Accessor - where TDatabaseKey : struct - { - private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - public Accessor() - { - _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - insert or replace into {0}.{1} - ({2}) - """; + insert or replace into {0}.{1} - return; + ({2}) - string GetSelectRowIdQuery(string database) - => $""" - select rowid from {0}.{1} where - {2} - limit 1 - """; - } - } + """; + + return; + + string GetSelectRowIdQuery(string database) + => $""" + + select rowid from {0}.{1} where + + {2} + + limit 1 + + """; } } - """", - FixedCode = """" - namespace $$Microsoft.CodeAnalysis.SQLite.v2; + } + """", + LanguageVersion = LanguageVersion.CSharp11, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestInterpolatedRawString5() + { + await new VerifyCS.Test + { + TestCode = """" + [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + { internal partial class SQLitePersistentStorage { private abstract class Accessor where TDatabaseKey : struct { private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - + public Accessor() { _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" insert or replace into {0}.{1} ({2}) """; - + return; - + string GetSelectRowIdQuery(string database) => $""" select rowid from {0}.{1} where @@ -1464,85 +1434,114 @@ limit 1 } } } - """", - LanguageVersion = LanguageVersion.CSharp11, - Options = - { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } } - }.RunAsync(); - } + """", + FixedCode = """" + namespace $$Microsoft.CodeAnalysis.SQLite.v2; - [Fact] - public async Task TestInterpolatedRawString6() - { - await new VerifyCS.Test - { - TestCode = """" - [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + internal partial class SQLitePersistentStorage + { + private abstract class Accessor + where TDatabaseKey : struct { - internal partial class SQLitePersistentStorage + private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + + public Accessor() { - private abstract class Accessor - where TDatabaseKey : struct - { - private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - - public Accessor() - { - _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - insert or replace into {0}.{1} - ({2}) - """; - - return; - - string GetSelectRowIdQuery(string database) - => $""" - select rowid from {0}.{1} where - {2} - limit 1 - """; - } - } + _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" + insert or replace into {0}.{1} + ({2}) + """; + + return; + + string GetSelectRowIdQuery(string database) + => $""" + select rowid from {0}.{1} where + {2} + limit 1 + """; } } - """", - FixedCode = """" - namespace $$Microsoft.CodeAnalysis.SQLite.v2; + } + """", + LanguageVersion = LanguageVersion.CSharp11, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + [Fact] + public async Task TestInterpolatedRawString6() + { + await new VerifyCS.Test + { + TestCode = """" + [|namespace Microsoft.CodeAnalysis.SQLite.v2|] + { internal partial class SQLitePersistentStorage { private abstract class Accessor where TDatabaseKey : struct { private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; - + public Accessor() { _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" - insert or replace into {0}.{1} - ({2}) - """; - + insert or replace into {0}.{1} + ({2}) + """; + return; - + string GetSelectRowIdQuery(string database) => $""" - select rowid from {0}.{1} where - {2} - limit 1 - """; + select rowid from {0}.{1} where + {2} + limit 1 + """; } } } - """", - LanguageVersion = LanguageVersion.CSharp11, - Options = + } + """", + FixedCode = """" + namespace $$Microsoft.CodeAnalysis.SQLite.v2; + + internal partial class SQLitePersistentStorage { - { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + private abstract class Accessor + where TDatabaseKey : struct + { + private string _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data; + + public Accessor() + { + _insert_or_replace_into_writecache_table_values_0primarykey_1checksum_2data = $""" + insert or replace into {0}.{1} + ({2}) + """; + + return; + + string GetSelectRowIdQuery(string database) + => $""" + select rowid from {0}.{1} where + {2} + limit 1 + """; + } + } } - }.RunAsync(); - } + """", + LanguageVersion = LanguageVersion.CSharp11, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs b/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs index ab8bde2f50f45..50f267749efe9 100644 --- a/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionFixAllTests.cs @@ -9,326 +9,325 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertSwitchStatementToExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - ConvertSwitchStatementToExpressionDiagnosticAnalyzer, - ConvertSwitchStatementToExpressionCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertSwitchStatementToExpression; + +using VerifyCS = CSharpCodeFixVerifier< + ConvertSwitchStatementToExpressionDiagnosticAnalyzer, + ConvertSwitchStatementToExpressionCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] - public class ConvertSwitchStatementToExpressionFixAllTests +[Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] +public class ConvertSwitchStatementToExpressionFixAllTests +{ + [Fact] + public async Task TestNested_01() { - [Fact] - public async Task TestNested_01() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M(int i, int j) { - int M(int i, int j) + int r; + [|switch|] (i) { - int r; - [|switch|] (i) - { - case 1: - r = 1; - break; - case 2: - r = 2; - break; - case 3: - r = 3; - break; - default: - r = 4; - break; - } - int x, y; - switch (i) - { - case 1: - x = 1; - y = 1; - break; - case 2: - x = 1; - y = 1; - break; - case 3: - x = 1; - y = 1; - break; - default: - x = 1; - y = 1; - break; - } - [|switch|] (i) - { - default: - throw null; - case 1: - [|switch|] (j) - { - case 10: - return 10; - case 20: - return 20; - case 30: - return 30; - } - return 0; - case 2: - [|switch|] (j) - { - case 10: - return 10; - case 20: - return 20; - case 30: - return 30; - case var _: - return 0; - } - case 3: - [|switch|] (j) - { - case 10: - return 10; - case 20: - return 20; - case 30: - return 30; - case var v: - return 0; - } - } + case 1: + r = 1; + break; + case 2: + r = 2; + break; + case 3: + r = 3; + break; + default: + r = 4; + break; + } + int x, y; + switch (i) + { + case 1: + x = 1; + y = 1; + break; + case 2: + x = 1; + y = 1; + break; + case 3: + x = 1; + y = 1; + break; + default: + x = 1; + y = 1; + break; + } + [|switch|] (i) + { + default: + throw null; + case 1: + [|switch|] (j) + { + case 10: + return 10; + case 20: + return 20; + case 30: + return 30; + } + return 0; + case 2: + [|switch|] (j) + { + case 10: + return 10; + case 20: + return 20; + case 30: + return 30; + case var _: + return 0; + } + case 3: + [|switch|] (j) + { + case 10: + return 10; + case 20: + return 20; + case 30: + return 30; + case var v: + return 0; + } } } - """, - """ - class Program + } + """, + """ + class Program + { + int M(int i, int j) { - int M(int i, int j) + var r = i switch { - var r = i switch + 1 => 1, + 2 => 2, + 3 => 3, + _ => 4, + }; + int x, y; + switch (i) + { + case 1: + x = 1; + y = 1; + break; + case 2: + x = 1; + y = 1; + break; + case 3: + x = 1; + y = 1; + break; + default: + x = 1; + y = 1; + break; + } + return i switch + { + 1 => j switch { - 1 => 1, - 2 => 2, - 3 => 3, - _ => 4, - }; - int x, y; - switch (i) + 10 => 10, + 20 => 20, + 30 => 30, + _ => 0, + }, + 2 => j switch { - case 1: - x = 1; - y = 1; - break; - case 2: - x = 1; - y = 1; - break; - case 3: - x = 1; - y = 1; - break; - default: - x = 1; - y = 1; - break; - } - return i switch + 10 => 10, + 20 => 20, + 30 => 30, + var _ => 0, + }, + 3 => j switch { - 1 => j switch - { - 10 => 10, - 20 => 20, - 30 => 30, - _ => 0, - }, - 2 => j switch - { - 10 => 10, - 20 => 20, - 30 => 30, - var _ => 0, - }, - 3 => j switch - { - 10 => 10, - 20 => 20, - 30 => 30, - var v => 0, - }, - _ => throw null, - }; - } + 10 => 10, + 20 => 20, + 30 => 30, + var v => 0, + }, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestNested_02() - { - var input = """ - class Program + [Fact] + public async Task TestNested_02() + { + var input = """ + class Program + { + System.Func M(int i, int j) { - System.Func M(int i, int j) + [|switch|] (i) { - [|switch|] (i) - { - // 1 - default: // 2 - return () => + // 1 + default: // 2 + return () => + { + [|switch|] (j) { - [|switch|] (j) - { - default: - return 3; - } - }; - } + default: + return 3; + } + }; } } - """; - var expected = """ - class Program + } + """; + var expected = """ + class Program + { + System.Func M(int i, int j) { - System.Func M(int i, int j) + return i switch { - return i switch - { - // 1 - // 2 - _ => () => + // 1 + // 2 + _ => () => + { + return j switch { - return j switch - { - _ => 3, - }; - } + _ => 3, + }; + } - , - }; - } + , + }; } - """; - - await new VerifyCS.Test - { - TestCode = input, - FixedCode = expected, - NumberOfFixAllIterations = 2, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37907")] - public async Task TestNested_03() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; + TestCode = input, + FixedCode = expected, + NumberOfFixAllIterations = 2, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37907")] + public async Task TestNested_03() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; - class Program + class Program + { + public static void Main() { } + public DayOfWeek StatusValue() => DayOfWeek.Monday; + public short Value => 0; + public bool ValueBoolean() { - public static void Main() { } - public DayOfWeek StatusValue() => DayOfWeek.Monday; - public short Value => 0; - public bool ValueBoolean() + bool value; + [|switch|] (StatusValue()) { - bool value; - [|switch|] (StatusValue()) - { - case DayOfWeek.Monday: - [|switch|] (Value) - { - case 0: - value = false; - break; - case 1: - value = true; - break; - default: - throw new Exception(); - } - break; - default: - throw new Exception(); - } - return value; + case DayOfWeek.Monday: + [|switch|] (Value) + { + case 0: + value = false; + break; + case 1: + value = true; + break; + default: + throw new Exception(); + } + break; + default: + throw new Exception(); } + return value; } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + public static void Main() { } + public DayOfWeek StatusValue() => DayOfWeek.Monday; + public short Value => 0; + public bool ValueBoolean() { - public static void Main() { } - public DayOfWeek StatusValue() => DayOfWeek.Monday; - public short Value => 0; - public bool ValueBoolean() + var value = StatusValue() switch { - var value = StatusValue() switch + DayOfWeek.Monday => Value switch { - DayOfWeek.Monday => Value switch - { - 0 => false, - 1 => true, - _ => throw new Exception(), - }, + 0 => false, + 1 => true, _ => throw new Exception(), - }; - return value; - } + }, + _ => throw new Exception(), + }; + return value; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44572")] - public async Task TestImplicitConversion() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; + } + """); + } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44572")] + public async Task TestImplicitConversion() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; - class C + class C + { + public C(String s) => _s = s; + private readonly String _s; + public static implicit operator String(C value) => value._s; + public static implicit operator C(String value) => new C(value); + + public bool method(C c) { - public C(String s) => _s = s; - private readonly String _s; - public static implicit operator String(C value) => value._s; - public static implicit operator C(String value) => new C(value); - - public bool method(C c) + [|switch|] (c) { - [|switch|] (c) - { - case "A": return true; - default: return false; - } + case "A": return true; + default: return false; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public C(String s) => _s = s; + private readonly String _s; + public static implicit operator String(C value) => value._s; + public static implicit operator C(String value) => new C(value); + + public bool method(C c) { - public C(String s) => _s = s; - private readonly String _s; - public static implicit operator String(C value) => value._s; - public static implicit operator C(String value) => new C(value); - - public bool method(C c) + return (string)c switch { - return (string)c switch - { - "A" => true, - _ => false, - }; - } + "A" => true, + _ => false, + }; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs b/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs index 0b0d2dd68c71a..298041054b5aa 100644 --- a/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertSwitchStatementToExpression/ConvertSwitchStatementToExpressionTests.cs @@ -15,2578 +15,2577 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertSwitchStatementToExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - ConvertSwitchStatementToExpressionDiagnosticAnalyzer, - ConvertSwitchStatementToExpressionCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertSwitchStatementToExpression; - [Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] - public class ConvertSwitchStatementToExpressionTests - { - private static readonly LanguageVersion CSharp9 = LanguageVersion.CSharp9; +using VerifyCS = CSharpCodeFixVerifier< + ConvertSwitchStatementToExpressionDiagnosticAnalyzer, + ConvertSwitchStatementToExpressionCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsConvertSwitchStatementToExpression)] +public class ConvertSwitchStatementToExpressionTests +{ + private static readonly LanguageVersion CSharp9 = LanguageVersion.CSharp9; - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); - [Fact] - public async Task TestReturn() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact] + public async Task TestReturn() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M(int i) { - int M(int i) + [|switch|] (i) { - [|switch|] (i) - { - case 1: - return 4; - case 2: - return 5; - case 3: - return 6; - default: - return 7; - } + case 1: + return 4; + case 2: + return 5; + case 3: + return 6; + default: + return 7; } } - """, - """ - class Program + } + """, + """ + class Program + { + int M(int i) { - int M(int i) + return i switch { - return i switch - { - 1 => 4, - 2 => 5, - 3 => 6, - _ => 7, - }; - } + 1 => 4, + 2 => 5, + 3 => 6, + _ => 7, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestReturnAndThrow() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact] + public async Task TestReturnAndThrow() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M(int i) { - int M(int i) + [|switch|] (i) { - [|switch|] (i) - { - case 1: - return 4; - default: - throw null; - case 2: - return 5; - case 3: - return 6; - } + case 1: + return 4; + default: + throw null; + case 2: + return 5; + case 3: + return 6; } } - """, - """ - class Program + } + """, + """ + class Program + { + int M(int i) { - int M(int i) + return i switch { - return i switch - { - 1 => 4, - 2 => 5, - 3 => 6, - _ => throw null, - }; - } + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestAssignment_Array() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program - { - int[] array = new int[1]; + [Fact] + public async Task TestAssignment_Array() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int[] array = new int[1]; - void M(int i) + void M(int i) + { + [|switch|] (i) { - [|switch|] (i) - { - case 1: - array[0] = 4; - break; - case 2: - array[0] = 5; - break; - case 3: - array[0] = 6; - break; - default: - array[0] = 7; - break; - } + case 1: + array[0] = 4; + break; + case 2: + array[0] = 5; + break; + case 3: + array[0] = 6; + break; + default: + array[0] = 7; + break; } } - """, - """ - class Program - { - int[] array = new int[1]; + } + """, + """ + class Program + { + int[] array = new int[1]; - void M(int i) + void M(int i) + { + array[0] = i switch { - array[0] = i switch - { - 1 => 4, - 2 => 5, - 3 => 6, - _ => 7, - }; - } + 1 => 4, + 2 => 5, + 3 => 6, + _ => 7, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnDifferentIndexerArgs() - { - var code = """ - class Program - { - int[] array = new int[1]; + [Fact] + public async Task TestMissingOnDifferentIndexerArgs() + { + var code = """ + class Program + { + int[] array = new int[1]; - void M(int i) + void M(int i) + { + switch (i) { - switch (i) - { - case 1: - array[1] = 4; - break; - case 2: - array[2] = 5; - break; - case 3: - array[2] = 6; - break; - default: - array[2] = 7; - break; - } + case 1: + array[1] = 4; + break; + case 2: + array[2] = 5; + break; + case 3: + array[2] = 6; + break; + default: + array[2] = 7; + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnQualifiedName() - { - var code = """ - class Program - { - int[] array = new int[1]; + [Fact] + public async Task TestMissingOnQualifiedName() + { + var code = """ + class Program + { + int[] array = new int[1]; - void M(int i) + void M(int i) + { + switch (i) { - switch (i) - { - case 1: - this.array[2] = 4; - break; - case 2: - array[2] = 5; - break; - case 3: - array[2] = 6; - break; - default: - array[2] = 7; - break; - } + case 1: + this.array[2] = 4; + break; + case 2: + array[2] = 5; + break; + case 3: + array[2] = 6; + break; + default: + array[2] = 7; + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnDefaultBreak_01() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnDefaultBreak_01() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - default: - break; - } + default: + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnDefaultBreak_02() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnDefaultBreak_02() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - case { }: - break; - } + case { }: + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnDefaultBreak_03() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnDefaultBreak_03() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - case var _: - break; - } + case var _: + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnDefaultBreak_04() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnDefaultBreak_04() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - case var x: - break; - } + case var x: + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnAllBreak() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnAllBreak() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - case 1: - break; - case 2: - break; - case 3: - break; - } + case 1: + break; + case 2: + break; + case 3: + break; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestAllThrow() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - class Program + [Fact] + public async Task TestAllThrow() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + class Program + { + void M(int i) { - void M(int i) + [|switch|] (i) { - [|switch|] (i) - { - case 1: - throw null; - default: - throw new Exception(); - } + case 1: + throw null; + default: + throw new Exception(); } } - """, - """ - using System; - class Program + } + """, + """ + using System; + class Program + { + void M(int i) { - void M(int i) + throw i switch { - throw i switch - { - 1 => null, - _ => new Exception(), - }; - } + 1 => null, + _ => new Exception(), + }; } - """); - } + } + """); + } - [Fact] - public async Task TestAssignment() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact] + public async Task TestAssignment() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + void M(int i) { - void M(int i) + int j; + [|switch|] (i) { - int j; - [|switch|] (i) - { - case 1: - j = 4; - break; - case 2: - j = 5; - break; - case 3: - j = 6; - break; - } - throw null; + case 1: + j = 4; + break; + case 2: + j = 5; + break; + case 3: + j = 6; + break; } + throw null; } - """, - """ - class Program + } + """, + """ + class Program + { + void M(int i) { - void M(int i) + var j = i switch { - var j = i switch - { - 1 => 4, - 2 => 5, - 3 => 6, - _ => throw null, - }; - } + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnNextStatementMismatch() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnNextStatementMismatch() + { + var code = """ + class Program + { + int M(int i) { - int M(int i) + int j = 0; + switch (i) { - int j = 0; - switch (i) - { - case 1: - j = 4; - break; - case 2: - j = 5; - break; - case 3: - j = 6; - break; - } - return j; + case 1: + j = 4; + break; + case 2: + j = 5; + break; + case 3: + j = 6; + break; } + return j; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnAssignmentMismatch() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnAssignmentMismatch() + { + var code = """ + class Program + { + int M(int i) { - int M(int i) + int j = 0; + switch (i) { - int j = 0; - switch (i) - { - case 1: - j = 4; - break; - case 2: - j += 5; - break; - } - return j; + case 1: + j = 4; + break; + case 2: + j += 5; + break; } + return j; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestAssignment_Compound() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact] + public async Task TestAssignment_Compound() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + void M(int i) { - void M(int i) + int j = 0; + [|switch|] (i) { - int j = 0; - [|switch|] (i) - { - case 1: - j += 4; - break; - case 2: - j += 5; - break; - case 3: - j += 6; - break; - } - throw null; + case 1: + j += 4; + break; + case 2: + j += 5; + break; + case 3: + j += 6; + break; } + throw null; } - """, - """ - class Program + } + """, + """ + class Program + { + void M(int i) { - void M(int i) + int j = 0; + j += i switch { - int j = 0; - j += i switch - { - 1 => 4, - 2 => 5, - 3 => 6, - _ => throw null, - }; - } + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestAssignment_UseBeforeAssignment() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact] + public async Task TestAssignment_UseBeforeAssignment() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + void M(int i) { - void M(int i) + int j = 123; + M(i); + [|switch|] (i) { - int j = 123; - M(i); - [|switch|] (i) - { - case 1: - j = 4; - break; - case 2: - j = 5; - break; - case 3: - j = 6; - break; - } - throw null; + case 1: + j = 4; + break; + case 2: + j = 5; + break; + case 3: + j = 6; + break; } + throw null; } - """, - """ - class Program + } + """, + """ + class Program + { + void M(int i) { - void M(int i) + int j = 123; + M(i); + j = i switch { - int j = 123; - M(i); - j = i switch - { - 1 => 4, - 2 => 5, - 3 => 6, - _ => throw null, - }; - } + 1 => 4, + 2 => 5, + 3 => 6, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnMultiAssignment() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnMultiAssignment() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + int j, k; + switch (i) { - int j, k; - switch (i) - { - case 1: - j = 4; - k = 5; - break; - case 2: - j = 6; - k = 7; - break; - case 3: - j = 8; - k = 9; - break; - } - throw null; + case 1: + j = 4; + k = 5; + break; + case 2: + j = 6; + k = 7; + break; + case 3: + j = 8; + k = 9; + break; } + throw null; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnMultiCaseSection() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnMultiCaseSection() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + int j; + switch (i) { - int j; - switch (i) - { - case 1: - case 2: - j = 4; - break; - } - throw null; + case 1: + case 2: + j = 4; + break; } + throw null; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnMultiCaseSectionWithWhenClause_CSharp9() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnMultiCaseSectionWithWhenClause_CSharp9() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + int j; + switch (i) { - int j; - switch (i) - { - case 1: - case 2 when true: - j = 4; - break; - } - throw null; + case 1: + case 2 when true: + j = 4; + break; } + throw null; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] - public async Task TestOnMultiCaseSection_CSharp9() + await new VerifyCS.Test { - var testCode = """ - class Program + TestCode = code, + FixedCode = code, + LanguageVersion = CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] + public async Task TestOnMultiCaseSection_CSharp9() + { + var testCode = """ + class Program + { + void M(int i) { - void M(int i) + int j; + [|switch|] (i) { - int j; - [|switch|] (i) - { - case 1: - case 2: - j = 4; - break; - } - throw null; + case 1: + case 2: + j = 4; + break; } + throw null; } - """; - var fixedCode = """ - class Program + } + """; + var fixedCode = """ + class Program + { + void M(int i) { - void M(int i) + var j = i switch { - var j = i switch - { - 1 or 2 => 4, - _ => throw null, - }; - } + 1 or 2 => 4, + _ => throw null, + }; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestMissingOnMultiCompoundAssignment() + await new VerifyCS.Test { - var code = """ - class Program + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestMissingOnMultiCompoundAssignment() + { + var code = """ + class Program + { + void M(int i) { - void M(int i) + int j = 0, k = 0; + switch (i) { - int j = 0, k = 0; - switch (i) - { - case 1: - j += 4; - k += 5; - break; - case 2: - j += 6; - k += 7; - break; - case 3: - j += 8; - k += 9; - break; - } - throw null; + case 1: + j += 4; + k += 5; + break; + case 2: + j += 6; + k += 7; + break; + case 3: + j += 8; + k += 9; + break; } + throw null; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnGoto() - { - var code = """ - class Program + [Fact] + public async Task TestMissingOnGoto() + { + var code = """ + class Program + { + int M(int i) { - int M(int i) + switch (i) { - switch (i) - { - case 1: - return 0; - case 2: - goto default; - default: - return 2; - } + case 1: + return 0; + case 2: + goto default; + default: + return 2; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestTrivia_01() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact] + public async Task TestTrivia_01() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M(int i) + { + // leading switch + [|switch|] (i) // trailing switch + { + // leading label + case 1: // trailing label + // leading body + return 4; // trailing body + case 2: + return 5; + case 3: + return 6; + } + + // leading next statement + throw null; // leading next statement + } + } + """, + """ + class Program + { + int M(int i) { - int M(int i) + // leading switch + return i switch // trailing switch { - // leading switch - [|switch|] (i) // trailing switch - { - // leading label - case 1: // trailing label - // leading body - return 4; // trailing body - case 2: - return 5; - case 3: - return 6; - } - + // leading label + // trailing label + 1 => 4,// leading body + // trailing body + 2 => 5, + 3 => 6, // leading next statement - throw null; // leading next statement - } + _ => throw null,// leading next statement + }; } - """, - """ - class Program - { - int M(int i) - { - // leading switch - return i switch // trailing switch - { - // leading label - // trailing label - 1 => 4,// leading body - // trailing body - 2 => 5, - 3 => 6, - // leading next statement - _ => throw null,// leading next statement - }; - } - } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37873")] - public async Task TestTrivia_02() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program - { - static int GetValue(int input) - { - [|switch|] (input) - { - case 1: - // this little piggy went to market - return 42; - case 2: - // this little piggy stayed home - return 50; - case 3: - // this little piggy had roast beef - return 79; - default: - // this little piggy had none - return 80; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37873")] + public async Task TestTrivia_02() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + static int GetValue(int input) + { + [|switch|] (input) + { + case 1: + // this little piggy went to market + return 42; + case 2: + // this little piggy stayed home + return 50; + case 3: + // this little piggy had roast beef + return 79; + default: + // this little piggy had none + return 80; } } - """, - """ - class Program + } + """, + """ + class Program + { + static int GetValue(int input) { - static int GetValue(int input) + return input switch { - return input switch - { - 1 => 42,// this little piggy went to market - 2 => 50,// this little piggy stayed home - 3 => 79,// this little piggy had roast beef - _ => 80,// this little piggy had none - }; - } + 1 => 42,// this little piggy went to market + 2 => 50,// this little piggy stayed home + 3 => 79,// this little piggy had roast beef + _ => 80,// this little piggy had none + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52258")] - public async Task TestTrivia_03() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52258")] + public async Task TestTrivia_03() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M(int i) { - int M(int i) - { - [|switch|] (i) - { // Tip-toe through the trailing trivia - case 0: return 123; - case 1: return 234; - default: throw null; - } + [|switch|] (i) + { // Tip-toe through the trailing trivia + case 0: return 123; + case 1: return 234; + default: throw null; } } - """, - """ - class Program + } + """, + """ + class Program + { + int M(int i) { - int M(int i) - { - return i switch - { // Tip-toe through the trailing trivia - 0 => 123, - 1 => 234, - _ => throw null, - }; - } + return i switch + { // Tip-toe through the trailing trivia + 0 => 123, + 1 => 234, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36086")] - public async Task TestSeverity() - { - var source = - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36086")] + public async Task TestSeverity() + { + var source = + """ + class Program + { + int M(int i) { - int M(int i) + switch (i) { - switch (i) - { - case 1: - return 4; - case 2: - return 5; - case 3: - return 6; - default: - return 7; - } + case 1: + return 4; + case 2: + return 5; + case 3: + return 6; + default: + return 7; } } - """; + } + """; - var analyzer = new ConvertSwitchStatementToExpressionDiagnosticAnalyzer(); - var descriptor = analyzer.SupportedDiagnostics.First(descriptor => descriptor.Id == IDEDiagnosticIds.ConvertSwitchStatementToExpressionDiagnosticId); - await new VerifyCS.Test + var analyzer = new ConvertSwitchStatementToExpressionDiagnosticAnalyzer(); + var descriptor = analyzer.SupportedDiagnostics.First(descriptor => descriptor.Id == IDEDiagnosticIds.ConvertSwitchStatementToExpressionDiagnosticId); + await new VerifyCS.Test + { + TestCode = source, + ExpectedDiagnostics = { - TestCode = source, - ExpectedDiagnostics = - { - // Test0.cs(5,9): warning IDE0066: Use 'switch' expression - new DiagnosticResult(descriptor).WithSeverity(DiagnosticSeverity.Warning).WithSpan(5, 9, 5, 15).WithSpan(5, 9, 15, 10), - }, - Options = - { - { CSharpCodeStyleOptions.PreferSwitchExpression, true, NotificationOption2.Warning }, - }, - }.RunAsync(); - } + // Test0.cs(5,9): warning IDE0066: Use 'switch' expression + new DiagnosticResult(descriptor).WithSeverity(DiagnosticSeverity.Warning).WithSpan(5, 9, 5, 15).WithSpan(5, 9, 15, 10), + }, + Options = + { + { CSharpCodeStyleOptions.PreferSwitchExpression, true, NotificationOption2.Warning }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36995")] - public async Task TestAddParenthesesAroundBinaryExpression() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36995")] + public async Task TestAddParenthesesAroundBinaryExpression() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + void M(int i) { - void M(int i) + int j = 123; + [|switch|] (i % 10) { - int j = 123; - [|switch|] (i % 10) - { - case 1: - j = 4; - break; - case 2: - j = 5; - break; - } - throw null; + case 1: + j = 4; + break; + case 2: + j = 5; + break; } + throw null; } - """, - """ - class Program + } + """, + """ + class Program + { + void M(int i) { - void M(int i) + int j = 123; + j = (i % 10) switch { - int j = 123; - j = (i % 10) switch - { - 1 => 4, - 2 => 5, - _ => throw null, - }; - } + 1 => 4, + 2 => 5, + _ => throw null, + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37947")] - public async Task TestMultiLabelWithDefault() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37947")] + public async Task TestMultiLabelWithDefault() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; - class Program + class Program + { + public static string FromDay(DayOfWeek dayOfWeek) { - public static string FromDay(DayOfWeek dayOfWeek) + [|switch|] (dayOfWeek) { - [|switch|] (dayOfWeek) - { - case DayOfWeek.Monday: - return "Monday"; - case DayOfWeek.Friday: - default: - return "Other"; - } + case DayOfWeek.Monday: + return "Monday"; + case DayOfWeek.Friday: + default: + return "Other"; } } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + public static string FromDay(DayOfWeek dayOfWeek) { - public static string FromDay(DayOfWeek dayOfWeek) + return dayOfWeek switch { - return dayOfWeek switch - { - DayOfWeek.Monday => "Monday", - _ => "Other", - }; - } + DayOfWeek.Monday => "Monday", + _ => "Other", + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37949")] - public async Task TestMissingOnUseInNextStatement() - { - var code = """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37949")] + public async Task TestMissingOnUseInNextStatement() + { + var code = """ + using System; - class Program + class Program + { + public static void Throw(int index) { - public static void Throw(int index) + string name = ""; + switch (index) { - string name = ""; - switch (index) - { - case 0: name = "1"; break; - case 1: name = "2"; break; - } - throw new Exception(name); + case 0: name = "1"; break; + case 1: name = "2"; break; } + throw new Exception(name); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36876")] + public async Task TestDeclarationInOuterScope() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.IO; + + class Program + { + static SeekOrigin origin; + static long offset; + static long position; + static long length; + public static void Test() + { + long target; + try + { + [|switch|] (origin) + { + case SeekOrigin.Begin: + target = offset; + break; + + case SeekOrigin.Current: + target = checked(offset + position); + break; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36876")] - public async Task TestDeclarationInOuterScope() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.IO; + case SeekOrigin.End: + target = checked(offset + length); + break; - class Program - { - static SeekOrigin origin; - static long offset; - static long position; - static long length; - public static void Test() - { - long target; - try - { - [|switch|] (origin) - { - case SeekOrigin.Begin: - target = offset; - break; - - case SeekOrigin.Current: - target = checked(offset + position); - break; - - case SeekOrigin.End: - target = checked(offset + length); - break; - - default: - throw new ArgumentOutOfRangeException(nameof(origin)); - } - } - catch (OverflowException) - { - throw new ArgumentOutOfRangeException(nameof(offset)); + default: + throw new ArgumentOutOfRangeException(nameof(origin)); } + } + catch (OverflowException) + { + throw new ArgumentOutOfRangeException(nameof(offset)); + } - if (target < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } + if (target < 0) + { + throw new ArgumentOutOfRangeException(nameof(offset)); } } - """, - """ - using System; - using System.IO; + } + """, + """ + using System; + using System.IO; - class Program + class Program + { + static SeekOrigin origin; + static long offset; + static long position; + static long length; + public static void Test() { - static SeekOrigin origin; - static long offset; - static long position; - static long length; - public static void Test() + long target; + try { - long target; - try - { - target = origin switch - { - SeekOrigin.Begin => offset, - SeekOrigin.Current => checked(offset + position), - SeekOrigin.End => checked(offset + length), - _ => throw new ArgumentOutOfRangeException(nameof(origin)), - }; - } - catch (OverflowException) + target = origin switch { - throw new ArgumentOutOfRangeException(nameof(offset)); - } + SeekOrigin.Begin => offset, + SeekOrigin.Current => checked(offset + position), + SeekOrigin.End => checked(offset + length), + _ => throw new ArgumentOutOfRangeException(nameof(origin)), + }; + } + catch (OverflowException) + { + throw new ArgumentOutOfRangeException(nameof(offset)); + } - if (target < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } + if (target < 0) + { + throw new ArgumentOutOfRangeException(nameof(offset)); } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37872")] - public async Task TestMissingFixOnDirectives() - { - var code = """ - class Program - { - static void Main() { } + } + """); + } - static int GetValue(int input) - { - [|switch|] (input) - { - case 1: - return 42; - case 2: - #if PLATFORM_UNIX - return 50; - #else - return 51; - #endif - case 3: - return 79; - default: - return 80; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37872")] + public async Task TestMissingFixOnDirectives() + { + var code = """ + class Program + { + static void Main() { } + + static int GetValue(int input) + { + [|switch|] (input) + { + case 1: + return 42; + case 2: + #if PLATFORM_UNIX + return 50; + #else + return 51; + #endif + case 3: + return 79; + default: + return 80; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37872")] - public async Task TestMissingFixAllOnDirectives() - { - var code = """ - class Program - { - static void Main() { } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37872")] + public async Task TestMissingFixAllOnDirectives() + { + var code = """ + class Program + { + static void Main() { } - static int GetValue(int input) + static int GetValue(int input) + { + [|switch|] (input) { - [|switch|] (input) - { - case 1: - return 42; - default: - return 80; - } - - [|switch|] (input) - { - case 1: - return 42; - case 2: - #if PLATFORM_UNIX - return 50; - #else - return 51; - #endif - case 3: - return 79; - default: - return 80; - } + case 1: + return 42; + default: + return 80; } - } - """; - var fixedCode = """ - class Program - { - static void Main() { } - static int GetValue(int input) + [|switch|] (input) { - return input switch - { - 1 => 42, - _ => 80, - }; - [|switch|] (input) - { - case 1: - return 42; - case 2: - #if PLATFORM_UNIX - return 50; - #else - return 51; - #endif - case 3: - return 79; - default: - return 80; - } + case 1: + return 42; + case 2: + #if PLATFORM_UNIX + return 50; + #else + return 51; + #endif + case 3: + return 79; + default: + return 80; } } - """; - - await new VerifyCS.Test + } + """; + var fixedCode = """ + class Program { - TestCode = code, - FixedState = - { - Sources = { fixedCode }, - MarkupHandling = MarkupMode.Allow, - }, - }.RunAsync(); - } + static void Main() { } + + static int GetValue(int input) + { + return input switch + { + 1 => 42, + _ => 80, + }; + [|switch|] (input) + { + case 1: + return 42; + case 2: + #if PLATFORM_UNIX + return 50; + #else + return 51; + #endif + case 3: + return 79; + default: + return 80; + } + } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37950")] - public async Task TestShouldNotCastNullOnNullableValueType_ReturnStatement() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + TestCode = code, + FixedState = + { + Sources = { fixedCode }, + MarkupHandling = MarkupMode.Allow, + }, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37950")] + public async Task TestShouldNotCastNullOnNullableValueType_ReturnStatement() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + public static bool? GetBool(string name) { - public static bool? GetBool(string name) + [|switch|] (name) { - [|switch|] (name) - { - case "a": return true; - case "b": return false; - default: return null; - } + case "a": return true; + case "b": return false; + default: return null; } } - """, - """ - class Program + } + """, + """ + class Program + { + public static bool? GetBool(string name) { - public static bool? GetBool(string name) + return name switch { - return name switch - { - "a" => true, - "b" => false, - _ => null, - }; - } + "a" => true, + "b" => false, + _ => null, + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37950")] - public async Task TestShouldNotCastNullOnNullableValueType_Assignment() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37950")] + public async Task TestShouldNotCastNullOnNullableValueType_Assignment() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + public static void Test(string name) { - public static void Test(string name) + bool? result; + [|switch|] (name) { - bool? result; - [|switch|] (name) - { - case "a": result = true; break; - case "b": result = false; break; - default: result = null; break; - } + case "a": result = true; break; + case "b": result = false; break; + default: result = null; break; } } - """, - """ - class Program + } + """, + """ + class Program + { + public static void Test(string name) { - public static void Test(string name) + bool? result = name switch { - bool? result = name switch - { - "a" => true, - "b" => false, - _ => null, - }; - } + "a" => true, + "b" => false, + _ => null, + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestExplicitDeclaration_Interfaces() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestExplicitDeclaration_Interfaces() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit, IFruit2 { } + class Apple : IFruit, IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit; + [|switch|] (name) { - IFruit2 fruit; - [|switch|] (name) - { - case "apple": - fruit = new Apple(); - break; - case "banana": - fruit = new Banana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "apple": + fruit = new Apple(); + break; + case "banana": + fruit = new Banana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit, IFruit2 { } + class Apple : IFruit, IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit = name switch { - IFruit2 fruit = name switch - { - "apple" => new Apple(), - "banana" => new Banana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "apple" => new Apple(), + "banana" => new Banana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestExplicitDeclaration_Interfaces2() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestExplicitDeclaration_Interfaces2() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit, IFruit2 { } + class Apple : IFruit, IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit; + [|switch|] (name) { - IFruit2 fruit; - [|switch|] (name) - { - case "banana": - fruit = new Banana(); - break; - case "banana2": - fruit = new Banana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "banana": + fruit = new Banana(); + break; + case "banana2": + fruit = new Banana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit, IFruit2 { } + class Apple : IFruit, IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit = name switch { - IFruit2 fruit = name switch - { - "banana" => new Banana(), - "banana2" => new Banana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "banana" => new Banana(), + "banana2" => new Banana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestExplicitDeclaration_Interfaces3() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestExplicitDeclaration_Interfaces3() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit2 { } + class Apple : IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit; + [|switch|] (name) { - IFruit2 fruit; - [|switch|] (name) - { - case "apple": - fruit = new Apple(); - break; - case "banana": - fruit = new Banana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "apple": + fruit = new Apple(); + break; + case "banana": + fruit = new Banana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit2 { } + class Apple : IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit = name switch { - IFruit2 fruit = name switch - { - "apple" => new Apple(), - "banana" => new Banana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "apple" => new Apple(), + "banana" => new Banana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestExplicitDeclaration_ClassInheritance() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestExplicitDeclaration_ClassInheritance() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit2 { } + class Apple : IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicApple : Apple { } + class OrganicApple : Apple { } - class OrganicBanana : Banana { } + class OrganicBanana : Banana { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit; + [|switch|] (name) { - IFruit2 fruit; - [|switch|] (name) - { - case "apple": - fruit = new OrganicApple(); - break; - case "banana": - fruit = new OrganicBanana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "apple": + fruit = new OrganicApple(); + break; + case "banana": + fruit = new OrganicBanana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Apple : IFruit2 { } + class Apple : IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicApple : Apple { } + class OrganicApple : Apple { } - class OrganicBanana : Banana { } + class OrganicBanana : Banana { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit = name switch { - IFruit2 fruit = name switch - { - "apple" => new OrganicApple(), - "banana" => new OrganicBanana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "apple" => new OrganicApple(), + "banana" => new OrganicBanana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestExplicitDeclaration_ClassInheritance2() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestExplicitDeclaration_ClassInheritance2() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicBanana : Banana, IFruit { } + class OrganicBanana : Banana, IFruit { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit; + [|switch|] (name) { - IFruit2 fruit; - [|switch|] (name) - { - case "banana": - fruit = new Banana(); - break; - case "organic banana": - fruit = new OrganicBanana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "banana": + fruit = new Banana(); + break; + case "organic banana": + fruit = new OrganicBanana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicBanana : Banana, IFruit { } + class OrganicBanana : Banana, IFruit { } - public static void Test(string name) + public static void Test(string name) + { + IFruit2 fruit = name switch { - IFruit2 fruit = name switch - { - "banana" => new Banana(), - "organic banana" => new OrganicBanana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "banana" => new Banana(), + "organic banana" => new OrganicBanana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestImplicitDeclaration_ClassInheritance() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestImplicitDeclaration_ClassInheritance() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicBanana : Banana { } + class OrganicBanana : Banana { } - public static void Test(string name) + public static void Test(string name) + { + Banana fruit; + [|switch|] (name) { - Banana fruit; - [|switch|] (name) - { - case "banana": - fruit = new Banana(); - break; - case "organic banana": - fruit = new OrganicBanana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "banana": + fruit = new Banana(); + break; + case "organic banana": + fruit = new OrganicBanana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicBanana : Banana { } + class OrganicBanana : Banana { } - public static void Test(string name) + public static void Test(string name) + { + var fruit = name switch { - var fruit = name switch - { - "banana" => new Banana(), - "organic banana" => new OrganicBanana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "banana" => new Banana(), + "organic banana" => new OrganicBanana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestImplicitDeclaration_ClassInheritance2() - { - var input = - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestImplicitDeclaration_ClassInheritance2() + { + var input = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicBanana : Banana, IFruit { } + class OrganicBanana : Banana, IFruit { } - public static void Test(string name) + public static void Test(string name) + { + Banana fruit; + [|switch|] (name) { - Banana fruit; - [|switch|] (name) - { - case "banana": - fruit = new Banana(); - break; - case "organic banana": - fruit = new OrganicBanana(); - break; - default: - throw new InvalidOperationException("Unknown fruit."); - } + case "banana": + fruit = new Banana(); + break; + case "organic banana": + fruit = new OrganicBanana(); + break; + default: + throw new InvalidOperationException("Unknown fruit."); } } - """; - var expected = - """ - using System; + } + """; + var expected = + """ + using System; - class Program - { - interface IFruit { } + class Program + { + interface IFruit { } - interface IFruit2 { } + interface IFruit2 { } - class Banana : IFruit, IFruit2 { } + class Banana : IFruit, IFruit2 { } - class OrganicBanana : Banana, IFruit { } + class OrganicBanana : Banana, IFruit { } - public static void Test(string name) + public static void Test(string name) + { + var fruit = name switch { - var fruit = name switch - { - "banana" => new Banana(), - "organic banana" => new OrganicBanana(), - _ => throw new InvalidOperationException("Unknown fruit."), - }; - } + "banana" => new Banana(), + "organic banana" => new OrganicBanana(), + _ => throw new InvalidOperationException("Unknown fruit."), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] - public async Task TestExplicitDeclaration_AllCasesDefaultLiteral() - { - var input = - """ - class Program - { - public static void Test() - { - var a = 0; - object o; - [|switch|] (a) - { - case 0: - o = default; - break; - default: - o = default; - break; - } - } - } - """; - var expected = - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38771")] + public async Task TestExplicitDeclaration_AllCasesDefaultLiteral() + { + var input = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o; + [|switch|] (a) { - var a = 0; - object o = a switch - { - 0 => default, - _ => default, - }; + case 0: + o = default; + break; + default: + o = default; + break; } } - """; - - await new VerifyCS.Test + } + """; + var expected = + """ + class Program { - TestCode = input, - FixedCode = expected, - Options = + public static void Test() { - { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + var a = 0; + object o = a switch + { + 0 => default, + _ => default, + }; + } + } + """; - [Fact] - public async Task TestExplicitDeclaration_MixedDefaultLiteralDefaultParameter() + await new VerifyCS.Test { - var input = - """ - class Program + TestCode = input, + FixedCode = expected, + Options = + { + { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } + + [Fact] + public async Task TestExplicitDeclaration_MixedDefaultLiteralDefaultParameter() + { + var input = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o; + [|switch|] (a) { - var a = 0; - object o; - [|switch|] (a) - { - case 0: - o = default(string); - break; - default: - o = default; - break; - } + case 0: + o = default(string); + break; + default: + o = default; + break; } } - """; - var expected = """ - class Program + } + """; + var expected = """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o = a switch { - var a = 0; - object o = a switch - { - 0 => default(string), - _ => default, - }; - } + 0 => default(string), + _ => default, + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact] - public async Task TestImplicitDeclaration_AllCasesDefaultParameter() - { - var input = - """ - class Program + [Fact] + public async Task TestImplicitDeclaration_AllCasesDefaultParameter() + { + var input = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o; + [|switch|] (a) { - var a = 0; - object o; - [|switch|] (a) - { - case 0: - o = default(object); - break; - default: - o = default(object); - break; - } + case 0: + o = default(object); + break; + default: + o = default(object); + break; } } - """; - var expected = - """ - class Program + } + """; + var expected = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + var o = a switch { - var a = 0; - var o = a switch - { - 0 => default(object), - _ => default(object), - }; - } + 0 => default(object), + _ => default(object), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact] - public async Task TestExplicitDeclaration_AllCasesDefaultParameter() - { - var input = - """ - class Program + [Fact] + public async Task TestExplicitDeclaration_AllCasesDefaultParameter() + { + var input = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o; + [|switch|] (a) { - var a = 0; - object o; - [|switch|] (a) - { - case 0: - o = default(object); - break; - default: - o = default(object); - break; - } + case 0: + o = default(object); + break; + default: + o = default(object); + break; } } - """; - var expected = - """ - class Program + } + """; + var expected = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o = a switch { - var a = 0; - object o = a switch - { - 0 => default(object), - _ => default(object), - }; - } + 0 => default(object), + _ => default(object), + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarForBuiltInTypes, false, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarForBuiltInTypes, false, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact] - public async Task TestExplicitDeclaration_DeclarationTypeDifferentFromAllCaseTypes() - { - var input = - """ - class Program + [Fact] + public async Task TestExplicitDeclaration_DeclarationTypeDifferentFromAllCaseTypes() + { + var input = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o; + [|switch|] (a) { - var a = 0; - object o; - [|switch|] (a) - { - case 0: - o = ""; - break; - default: - o = ""; - break; - } + case 0: + o = ""; + break; + default: + o = ""; + break; } } - """; - var expected = - """ - class Program + } + """; + var expected = + """ + class Program + { + public static void Test() { - public static void Test() + var a = 0; + object o = a switch { - var a = 0; - object o = a switch - { - 0 => "", - _ => "", - }; - } + 0 => "", + _ => "", + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = input, + FixedCode = expected, + Options = { - TestCode = input, - FixedCode = expected, - Options = - { - { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] - public async Task TestNotWithRefReturns() - { - var code = """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] + public async Task TestNotWithRefReturns() + { + var code = """ + using System; + class Program + { + static ref int GetRef(int[] mem, int addr, int mode) { - static ref int GetRef(int[] mem, int addr, int mode) + switch (mode) { - switch (mode) - { - case 0: return ref mem[mem[addr]]; - case 1: return ref mem[addr]; - default: throw new Exception(); - } + case 0: return ref mem[mem[addr]]; + case 1: return ref mem[addr]; + default: throw new Exception(); } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] - public async Task TestNotWithRefAssignment() - { - var code = """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] + public async Task TestNotWithRefAssignment() + { + var code = """ + using System; + class Program + { + static ref int GetRef(int[] mem, int addr, int mode) { - static ref int GetRef(int[] mem, int addr, int mode) + ref int i = ref addr; + switch (mode) { - ref int i = ref addr; - switch (mode) - { - case 0: i = ref mem[mem[addr]]; break; - default: throw new Exception(); - } - - return ref mem[addr]; + case 0: i = ref mem[mem[addr]]; break; + default: throw new Exception(); } + + return ref mem[addr]; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] - public async Task TestNotWithRefConditionalAssignment() - { - var code = """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] + public async Task TestNotWithRefConditionalAssignment() + { + var code = """ + using System; + class Program + { + static ref int GetRef(int[] mem, int addr, int mode) { - static ref int GetRef(int[] mem, int addr, int mode) + ref int i = ref addr; + switch (mode) { - ref int i = ref addr; - switch (mode) - { - case 0: i = ref true ? ref mem[mem[addr]] : ref mem[mem[addr]]; break; - default: throw new Exception(); - } - - return ref mem[addr]; + case 0: i = ref true ? ref mem[mem[addr]] : ref mem[mem[addr]]; break; + default: throw new Exception(); } + + return ref mem[addr]; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] - public async Task TestWithRefInsideConditionalAssignment() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40198")] + public async Task TestWithRefInsideConditionalAssignment() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + class Program + { + static void GetRef(int[] mem, int addr, int mode) { - static void GetRef(int[] mem, int addr, int mode) + ref int i = ref addr; + [|switch|] (mode) { - ref int i = ref addr; - [|switch|] (mode) - { - case 0: i = true ? ref mem[mem[addr]] : ref mem[mem[addr]]; break; - default: throw new Exception(); - } + case 0: i = true ? ref mem[mem[addr]] : ref mem[mem[addr]]; break; + default: throw new Exception(); } } - """, - """ - using System; - class Program + } + """, + """ + using System; + class Program + { + static void GetRef(int[] mem, int addr, int mode) { - static void GetRef(int[] mem, int addr, int mode) + ref int i = ref addr; + i = mode switch { - ref int i = ref addr; - i = mode switch - { - 0 => true ? ref mem[mem[addr]] : ref mem[mem[addr]], - _ => throw new Exception(), - }; - } - } - """); - } - - [Fact] - public async Task TopLevelStatement() - { - var source = """ - int i = 0; - [|switch|] (i) - { - case 1: - return 4; - default: - return 7; + 0 => true ? ref mem[mem[addr]] : ref mem[mem[addr]], + _ => throw new Exception(), + }; } - """; - - var fixedSource = """ - int i = 0; - return i switch - { - 1 => 4, - _ => 7, - }; - - """; + } + """); + } - var test = new VerifyCS.Test + [Fact] + public async Task TopLevelStatement() + { + var source = """ + int i = 0; + [|switch|] (i) { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - Sources = { source }, - }, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp9, + case 1: + return 4; + default: + return 7; + } + """; + + var fixedSource = """ + int i = 0; + return i switch + { + 1 => 4, + _ => 7, }; - await test.RunAsync(); - } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44449")] - public async Task TopLevelStatement_FollowedWithThrow() + var test = new VerifyCS.Test { - // We should be rewriting the declaration for 'j' to get 'var j = i switch ...' - var source = """ - int i = 0; - int j; - [|switch|] (i) - { - case 1: - j = 4; - break; - case 2: - j = 5; - break; - } - throw null; - """; - - var fixedSource = """ - int i = 0; - int j; - j = i switch - { - 1 => 4, - 2 => 5, - _ => throw null, - }; - - """; + TestState = + { + OutputKind = OutputKind.ConsoleApplication, + Sources = { source }, + }, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp9, + }; + + await test.RunAsync(); + } - var test = new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44449")] + public async Task TopLevelStatement_FollowedWithThrow() + { + // We should be rewriting the declaration for 'j' to get 'var j = i switch ...' + var source = """ + int i = 0; + int j; + [|switch|] (i) + { + case 1: + j = 4; + break; + case 2: + j = 5; + break; + } + throw null; + """; + + var fixedSource = """ + int i = 0; + int j; + j = i switch { - TestState = { - Sources = { source }, - OutputKind = OutputKind.ConsoleApplication, - }, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp9, + 1 => 4, + 2 => 5, + _ => throw null, }; - await test.RunAsync(); - } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48006")] - public async Task TestOnMultiCaseSection_String_CSharp9() + var test = new VerifyCS.Test { - var testCode = """ - class Program + TestState = { + Sources = { source }, + OutputKind = OutputKind.ConsoleApplication, + }, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp9, + }; + + await test.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48006")] + public async Task TestOnMultiCaseSection_String_CSharp9() + { + var testCode = """ + class Program + { + bool M(string s) { - bool M(string s) + [|switch|] (s) { - [|switch|] (s) - { - case "Last": - case "First": - case "Count": - return true; - default: - return false; - } + case "Last": + case "First": + case "Count": + return true; + default: + return false; } } - """; - var fixedCode = """ - class Program + } + """; + var fixedCode = """ + class Program + { + bool M(string s) { - bool M(string s) + return s switch { - return s switch - { - "Last" or "First" or "Count" => true, - _ => false, - }; - } + "Last" or "First" or "Count" => true, + _ => false, + }; } - """; - - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = CSharp9, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49788")] - public async Task TestParenthesizedExpression1() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49788")] + public async Task TestParenthesizedExpression1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M(object i) { - int M(object i) + [|switch|] (i.GetType()) { - [|switch|] (i.GetType()) - { - default: return 0; - } + default: return 0; } } - """, - """ - class Program + } + """, + """ + class Program + { + int M(object i) { - int M(object i) + return i.GetType() switch { - return i.GetType() switch - { - _ => 0, - }; - } + _ => 0, + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49788")] - public async Task TestParenthesizedExpression2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49788")] + public async Task TestParenthesizedExpression2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + int M() { - int M() + [|switch|] (1 + 1) { - [|switch|] (1 + 1) - { - default: return 0; - } + default: return 0; } } - """, - """ - class Program + } + """, + """ + class Program + { + int M() { - int M() + return (1 + 1) switch { - return (1 + 1) switch - { - _ => 0, - }; - } + _ => 0, + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] - public async Task TestRuntimeTypeConversion_Assignment1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] + public async Task TestRuntimeTypeConversion_Assignment1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + void M(string s) { - void M(string s) - { - object result; + object result; - [|switch|] (s) - { - case "a": - result = 1234; - break; - case "b": - result = 3.14; - break; - default: - throw new System.Exception(); - } + [|switch|] (s) + { + case "a": + result = 1234; + break; + case "b": + result = 3.14; + break; + default: + throw new System.Exception(); } } - """, - """ - class Program + } + """, + """ + class Program + { + void M(string s) { - void M(string s) + object result = s switch { - object result = s switch - { - "a" => 1234, - "b" => (object)3.14, - _ => throw new System.Exception(), - }; - } + "a" => 1234, + "b" => (object)3.14, + _ => throw new System.Exception(), + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] - public async Task TestRuntimeTypeConversion_Assignment2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] + public async Task TestRuntimeTypeConversion_Assignment2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + void M(string s) { - void M(string s) - { - object result; + object result; - [|switch|] (s) - { - case "a": - result = 1234; - break; - case "b": - result = 3.14; - break; - case "c": - result = true; - break; - default: - throw new System.Exception(); - } + [|switch|] (s) + { + case "a": + result = 1234; + break; + case "b": + result = 3.14; + break; + case "c": + result = true; + break; + default: + throw new System.Exception(); } } - """, - """ - class Program + } + """, + """ + class Program + { + void M(string s) { - void M(string s) + object result = s switch { - object result = s switch - { - "a" => 1234, - "b" => 3.14, - "c" => true, - _ => throw new System.Exception(), - }; - } + "a" => 1234, + "b" => 3.14, + "c" => true, + _ => throw new System.Exception(), + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] - public async Task TestRuntimeTypeConversion_Return1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] + public async Task TestRuntimeTypeConversion_Return1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + object M(string s) { - object M(string s) + [|switch|] (s) { - [|switch|] (s) - { - case "a": - return 1234; - case "b": - return 3.14; - default: - throw new System.Exception(); - } + case "a": + return 1234; + case "b": + return 3.14; + default: + throw new System.Exception(); } } - """, - """ - class Program + } + """, + """ + class Program + { + object M(string s) { - object M(string s) + return s switch { - return s switch - { - "a" => 1234, - "b" => (object)3.14, - _ => throw new System.Exception(), - }; - } + "a" => 1234, + "b" => (object)3.14, + _ => throw new System.Exception(), + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] - public async Task TestRuntimeTypeConversion_Return2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58636")] + public async Task TestRuntimeTypeConversion_Return2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class Program + { + object M(string s) { - object M(string s) + [|switch|] (s) { - [|switch|] (s) - { - case "a": - return 1234; - case "b": - return 3.14; - case "c": - return true; - default: - throw new System.Exception(); - } + case "a": + return 1234; + case "b": + return 3.14; + case "c": + return true; + default: + throw new System.Exception(); } } - """, - """ - class Program + } + """, + """ + class Program + { + object M(string s) { - object M(string s) + return s switch { - return s switch - { - "a" => 1234, - "b" => 3.14, - "c" => true, - _ => throw new System.Exception(), - }; - } + "a" => 1234, + "b" => 3.14, + "c" => true, + _ => throw new System.Exception(), + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61278")] - public async Task TestLeadingTrivia1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61278")] + public async Task TestLeadingTrivia1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - using System; + TestCode = + """ + using System; - class C + class C + { + public static int RefactorReplacementDemoMethod(int argument) { - public static int RefactorReplacementDemoMethod(int argument) - { - Console.WriteLine(nameof(RefactorReplacementDemoMethod)); + Console.WriteLine(nameof(RefactorReplacementDemoMethod)); - // This comment will get deleted, together with the blank lines around it. - // Very similar issue already filed, but no resolution to this issue so far. + // This comment will get deleted, together with the blank lines around it. + // Very similar issue already filed, but no resolution to this issue so far. - int result; - [|switch|] (argument) - { - case 1: result = 1001; break; - case 2: result = 1002; break; - default: result = -1; break; - } - return result; + int result; + [|switch|] (argument) + { + case 1: result = 1001; break; + case 2: result = 1002; break; + default: result = -1; break; } + return result; } - """, - FixedCode = - """ - using System; + } + """, + FixedCode = + """ + using System; - class C + class C + { + public static int RefactorReplacementDemoMethod(int argument) { - public static int RefactorReplacementDemoMethod(int argument) - { - Console.WriteLine(nameof(RefactorReplacementDemoMethod)); + Console.WriteLine(nameof(RefactorReplacementDemoMethod)); - // This comment will get deleted, together with the blank lines around it. - // Very similar issue already filed, but no resolution to this issue so far. + // This comment will get deleted, together with the blank lines around it. + // Very similar issue already filed, but no resolution to this issue so far. - var result = argument switch - { - 1 => 1001, - 2 => 1002, - _ => -1, - }; - return result; - } + var result = argument switch + { + 1 => 1001, + 2 => 1002, + _ => -1, + }; + return result; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61278")] - public async Task TestLeadingTrivia2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61278")] + public async Task TestLeadingTrivia2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - using System; + TestCode = + """ + using System; - class C + class C + { + public static int RefactorReplacementDemoMethod(int argument) { - public static int RefactorReplacementDemoMethod(int argument) - { - Console.WriteLine(nameof(RefactorReplacementDemoMethod)); + Console.WriteLine(nameof(RefactorReplacementDemoMethod)); - // This comment will get deleted, together with the blank lines around it. - // Very similar issue already filed, but no resolution to this issue so far. + // This comment will get deleted, together with the blank lines around it. + // Very similar issue already filed, but no resolution to this issue so far. - int result, x = 0; - [|switch|] (argument) - { - case 1: result = 1001; break; - case 2: result = 1002; break; - default: result = -1; break; - } - return result; + int result, x = 0; + [|switch|] (argument) + { + case 1: result = 1001; break; + case 2: result = 1002; break; + default: result = -1; break; } + return result; } - """, - FixedCode = - """ - using System; + } + """, + FixedCode = + """ + using System; - class C + class C + { + public static int RefactorReplacementDemoMethod(int argument) { - public static int RefactorReplacementDemoMethod(int argument) - { - Console.WriteLine(nameof(RefactorReplacementDemoMethod)); + Console.WriteLine(nameof(RefactorReplacementDemoMethod)); - // This comment will get deleted, together with the blank lines around it. - // Very similar issue already filed, but no resolution to this issue so far. + // This comment will get deleted, together with the blank lines around it. + // Very similar issue already filed, but no resolution to this issue so far. - int x = 0; - var result = argument switch - { - 1 => 1001, - 2 => 1002, - _ => -1, - }; - return result; - } + int x = 0; + var result = argument switch + { + 1 => 1001, + 2 => 1002, + _ => -1, + }; + return result; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/ConvertToAsync/ConvertToAsyncTests.cs b/src/Analyzers/CSharp/Tests/ConvertToAsync/ConvertToAsyncTests.cs index 46e5b170a2c22..b7f2be747a64c 100644 --- a/src/Analyzers/CSharp/Tests/ConvertToAsync/ConvertToAsyncTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertToAsync/ConvertToAsyncTests.cs @@ -9,53 +9,52 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertToAsync -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpConvertToAsyncMethodCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertToAsync; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpConvertToAsyncMethodCodeFixProvider>; - public sealed class ConvertToAsyncTests +public sealed class ConvertToAsyncTests +{ + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsChangeToAsync)] + public async Task CantAwaitAsyncVoid() { - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsChangeToAsync)] - public async Task CantAwaitAsyncVoid() - { - var initial = - """ - using System.Threading.Tasks; - - class Program + var initial = + """ + using System.Threading.Tasks; + + class Program + { + async Task rtrt() + { + {|CS4008:await gt()|}; + } + + async void gt() { - async Task rtrt() - { - {|CS4008:await gt()|}; - } - - async void gt() - { - } } - """; + } + """; + + var expected = + """ + using System.Threading.Tasks; - var expected = - """ - using System.Threading.Tasks; + class Program + { + async Task rtrt() + { + await gt(); + } - class Program + async + Task + gt() { - async Task rtrt() - { - await gt(); - } - - async - Task - gt() - { - } } - """; - await VerifyCS.VerifyCodeFixAsync(initial, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(initial, expected); } } diff --git a/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfFixAllTests.cs b/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfFixAllTests.cs index a70f3112cef36..0297c9be1779d 100644 --- a/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfFixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfFixAllTests.cs @@ -8,289 +8,288 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertTypeOfToNameOf -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertTypeOfToNameOf; + +using VerifyCS = CSharpCodeFixVerifier; - public partial class ConvertTypeOfToNameOfTests +public partial class ConvertTypeOfToNameOfTests +{ + [Fact] + [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task FixAllDocumentBasic() { - [Fact] - [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task FixAllDocumentBasic() - { - var input = """ - class Test + var input = """ + class Test + { + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test).Name|]; - var typeName2 = [|typeof(Test).Name|]; - var typeName3 = [|typeof(Test).Name|]; - } + var typeName1 = [|typeof(Test).Name|]; + var typeName2 = [|typeof(Test).Name|]; + var typeName3 = [|typeof(Test).Name|]; } - """; + } + """; - var expected = """ - class Test + var expected = """ + class Test + { + static void Main() { - static void Main() - { - var typeName1 = nameof(Test); - var typeName2 = nameof(Test); - var typeName3 = nameof(Test); - } + var typeName1 = nameof(Test); + var typeName2 = nameof(Test); + var typeName3 = nameof(Test); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(input, expected); - } + await VerifyCS.VerifyCodeFixAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task FixAllDocumentVariedSingleLine() - { - var input = """ - class Test + [Fact] + [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task FixAllDocumentVariedSingleLine() + { + var input = """ + class Test + { + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test).Name|]; var typeName2 = [|typeof(int).Name|]; var typeName3 = [|typeof(System.String).Name|]; - } + var typeName1 = [|typeof(Test).Name|]; var typeName2 = [|typeof(int).Name|]; var typeName3 = [|typeof(System.String).Name|]; } - """; + } + """; - var expected = """ - class Test + var expected = """ + class Test + { + static void Main() { - static void Main() - { - var typeName1 = nameof(Test); var typeName2 = nameof(System.Int32); var typeName3 = nameof(System.String); - } + var typeName1 = nameof(Test); var typeName2 = nameof(System.Int32); var typeName3 = nameof(System.String); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(input, expected); - } + await VerifyCS.VerifyCodeFixAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task FixAllDocumentVariedWithUsing() - { - var input = """ - using System; + [Fact] + [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task FixAllDocumentVariedWithUsing() + { + var input = """ + using System; - class Test + class Test + { + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test).Name|]; - var typeName2 = [|typeof(int).Name|]; - var typeName3 = [|typeof(String).Name|]; - var typeName4 = [|typeof(System.Double).Name|]; - } + var typeName1 = [|typeof(Test).Name|]; + var typeName2 = [|typeof(int).Name|]; + var typeName3 = [|typeof(String).Name|]; + var typeName4 = [|typeof(System.Double).Name|]; } - """; + } + """; - var expected = """ - using System; + var expected = """ + using System; - class Test + class Test + { + static void Main() { - static void Main() - { - var typeName1 = nameof(Test); - var typeName2 = nameof(Int32); - var typeName3 = nameof(String); - var typeName4 = nameof(Double); - } + var typeName1 = nameof(Test); + var typeName2 = nameof(Int32); + var typeName3 = nameof(String); + var typeName4 = nameof(Double); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(input, expected); - } + await VerifyCS.VerifyCodeFixAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task FixAllProject() + [Fact] + [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task FixAllProject() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestState = { - TestState = + Sources = { - Sources = + """ + class Test1 { - """ - class Test1 + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test1).Name|]; - var typeName2 = [|typeof(Test1).Name|]; - var typeName3 = [|typeof(Test1).Name|]; - } + var typeName1 = [|typeof(Test1).Name|]; + var typeName2 = [|typeof(Test1).Name|]; + var typeName3 = [|typeof(Test1).Name|]; } - """, - """ - using System; + } + """, + """ + using System; - class Test2 + class Test2 + { + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test1).Name|]; - var typeName2 = [|typeof(int).Name|]; - var typeName3 = [|typeof(System.String).Name|]; - var typeName4 = [|typeof(Double).Name|]; - } + var typeName1 = [|typeof(Test1).Name|]; + var typeName2 = [|typeof(int).Name|]; + var typeName3 = [|typeof(System.String).Name|]; + var typeName4 = [|typeof(Double).Name|]; } - """ } - }, - FixedState = + """ + } + }, + FixedState = + { + Sources = { - Sources = + """ + class Test1 { - """ - class Test1 + static void Main() { - static void Main() - { - var typeName1 = nameof(Test1); - var typeName2 = nameof(Test1); - var typeName3 = nameof(Test1); - } + var typeName1 = nameof(Test1); + var typeName2 = nameof(Test1); + var typeName3 = nameof(Test1); } - """, - """ - using System; + } + """, + """ + using System; - class Test2 + class Test2 + { + static void Main() { - static void Main() - { - var typeName1 = nameof(Test1); - var typeName2 = nameof(Int32); - var typeName3 = nameof(String); - var typeName4 = nameof(Double); - } + var typeName1 = nameof(Test1); + var typeName2 = nameof(Int32); + var typeName3 = nameof(String); + var typeName4 = nameof(Double); } - """, } + """, } - }.RunAsync(); - } + } + }.RunAsync(); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task FixAllSolution() + [Fact] + [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task FixAllSolution() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestState = { - TestState = + Sources = { - Sources = + """ + class Test1 { - """ - class Test1 + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test1).Name|]; - var typeName2 = [|typeof(Test1).Name|]; - var typeName3 = [|typeof(Test1).Name|]; - } + var typeName1 = [|typeof(Test1).Name|]; + var typeName2 = [|typeof(Test1).Name|]; + var typeName3 = [|typeof(Test1).Name|]; } - """, - """ - using System; + } + """, + """ + using System; - class Test2 + class Test2 + { + static void Main() { - static void Main() - { - var typeName1 = [|typeof(Test1).Name|]; - var typeName2 = [|typeof(int).Name|]; - var typeName3 = [|typeof(System.String).Name|]; - var typeName4 = [|typeof(Double).Name|]; - } + var typeName1 = [|typeof(Test1).Name|]; + var typeName2 = [|typeof(int).Name|]; + var typeName3 = [|typeof(System.String).Name|]; + var typeName4 = [|typeof(Double).Name|]; } - """ - }, - AdditionalProjects = + } + """ + }, + AdditionalProjects = + { + ["DependencyProject"] = { - ["DependencyProject"] = + Sources = { - Sources = + """ + class Test3 { - """ - class Test3 + static void Main() { - static void Main() - { - var typeName2 = [|typeof(int).Name|]; var typeName3 = [|typeof(System.String).Name|]; - } + var typeName2 = [|typeof(int).Name|]; var typeName3 = [|typeof(System.String).Name|]; } - """ } + """ } } - }, - FixedState = + } + }, + FixedState = + { + Sources = { - Sources = + """ + class Test1 { - """ - class Test1 + static void Main() { - static void Main() - { - var typeName1 = nameof(Test1); - var typeName2 = nameof(Test1); - var typeName3 = nameof(Test1); - } + var typeName1 = nameof(Test1); + var typeName2 = nameof(Test1); + var typeName3 = nameof(Test1); } - """, - """ - using System; + } + """, + """ + using System; - class Test2 + class Test2 + { + static void Main() { - static void Main() - { - var typeName1 = nameof(Test1); - var typeName2 = nameof(Int32); - var typeName3 = nameof(String); - var typeName4 = nameof(Double); - } + var typeName1 = nameof(Test1); + var typeName2 = nameof(Int32); + var typeName3 = nameof(String); + var typeName4 = nameof(Double); } - """ - }, - AdditionalProjects = + } + """ + }, + AdditionalProjects = + { + ["DependencyProject"] = { - ["DependencyProject"] = + Sources = { - Sources = + """ + class Test3 { - """ - class Test3 + static void Main() { - static void Main() - { - var typeName2 = nameof(System.Int32); var typeName3 = nameof(System.String); - } + var typeName2 = nameof(System.Int32); var typeName3 = nameof(System.String); } - """ } + """ } } } - }.RunAsync(); - } + } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfTests.cs b/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfTests.cs index 81fe5a0570dde..b757e5f7fdb19 100644 --- a/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertTypeOfToNameOf/ConvertTypeOfToNameOfTests.cs @@ -10,356 +10,355 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertTypeOfToNameOf -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertTypeOfToNameOf; + +using VerifyCS = CSharpCodeFixVerifier; - [Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] - public partial class ConvertTypeOfToNameOfTests +[Trait(Traits.Feature, Traits.Features.ConvertTypeOfToNameOf)] +public partial class ConvertTypeOfToNameOfTests +{ + [Fact] + public async Task BasicType() { - [Fact] - public async Task BasicType() - { - var text = """ - class Test + var text = """ + class Test + { + void Method() { - void Method() - { - var typeName = [|typeof(Test).Name|]; - } + var typeName = [|typeof(Test).Name|]; } - """; - var expected = """ - class Test + } + """; + var expected = """ + class Test + { + void Method() { - void Method() - { - var typeName = nameof(Test); - } + var typeName = nameof(Test); } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - [Fact] - public async Task ClassLibraryType() - { - var text = """ - class Test + [Fact] + public async Task ClassLibraryType() + { + var text = """ + class Test + { + void Method() { - void Method() - { - var typeName = [|typeof(System.String).Name|]; - } + var typeName = [|typeof(System.String).Name|]; } - """; - var expected = """ - class Test + } + """; + var expected = """ + class Test + { + void Method() { - void Method() - { - var typeName = nameof(System.String); - } + var typeName = nameof(System.String); } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - [Fact] - public async Task ClassLibraryTypeWithUsing() - { - var text = """ - using System; + [Fact] + public async Task ClassLibraryTypeWithUsing() + { + var text = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeName = [|typeof(String).Name|]; - } + var typeName = [|typeof(String).Name|]; } - """; - var expected = """ - using System; + } + """; + var expected = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeName = nameof(String); - } + var typeName = nameof(String); } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - [Fact] - public async Task NestedCall() - { - var text = """ - using System; + [Fact] + public async Task NestedCall() + { + var text = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeName = Foo([|typeof(System.String).Name|]); - } + var typeName = Foo([|typeof(System.String).Name|]); + } - int Foo(String typeName) { - return 0; - } + int Foo(String typeName) { + return 0; } - """; - var expected = """ - using System; + } + """; + var expected = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeName = Foo(nameof(String)); - } + var typeName = Foo(nameof(String)); + } - int Foo(String typeName) { - return 0; - } + int Foo(String typeName) { + return 0; } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - [Fact] - public async Task NotOnVariableContainingType() - { - var text = """ - using System; + [Fact] + public async Task NotOnVariableContainingType() + { + var text = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeVar = typeof(String); - var typeName = typeVar.Name; - } + var typeVar = typeof(String); + var typeName = typeVar.Name; } - """; - await VerifyCS.VerifyCodeFixAsync(text, text); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, text); + } - [Fact] - public async Task PrimitiveType() - { - var text = """ - class Test + [Fact] + public async Task PrimitiveType() + { + var text = """ + class Test + { + void Method() { - void Method() - { - var typeName = [|typeof(int).Name|]; - } + var typeName = [|typeof(int).Name|]; } - """; - var expected = """ - class Test + } + """; + var expected = """ + class Test + { + void Method() { - void Method() - { - var typeName = nameof(System.Int32); - } + var typeName = nameof(System.Int32); } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - [Fact] - public async Task PrimitiveTypeWithUsing() - { - var text = """ - using System; + [Fact] + public async Task PrimitiveTypeWithUsing() + { + var text = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeName = [|typeof(int).Name|]; - } + var typeName = [|typeof(int).Name|]; } - """; - var expected = """ - using System; + } + """; + var expected = """ + using System; - class Test + class Test + { + void Method() { - void Method() - { - var typeName = nameof(Int32); - } + var typeName = nameof(Int32); } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - [Fact] - public async Task NotOnGenericType() - { - var text = """ - class Test + [Fact] + public async Task NotOnGenericType() + { + var text = """ + class Test + { + void Method() { - void Method() - { - var typeName = typeof(T).Name; - } + var typeName = typeof(T).Name; } - """; - await VerifyCS.VerifyCodeFixAsync(text, text); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, text); + } - [Fact] - public async Task NotOnSimilarStatements() - { - var text = """ - class Test + [Fact] + public async Task NotOnSimilarStatements() + { + var text = """ + class Test + { + void Method() { - void Method() + var typeName1 = typeof(Test); + var typeName2 = typeof(Test).ToString(); + var typeName3 = typeof(Test).FullName; + } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, text); + } + + [Fact] + public async Task NotInGenericType() + { + var text = """ + class Test + { + class Goo + { + void M() { - var typeName1 = typeof(Test); - var typeName2 = typeof(Test).ToString(); - var typeName3 = typeof(Test).FullName; + _ = typeof(Goo).Name; } } - """; - await VerifyCS.VerifyCodeFixAsync(text, text); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, text); + } - [Fact] - public async Task NotInGenericType() - { - var text = """ - class Test - { - class Goo + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47129")] + public async Task NestedInGenericType() + { + var text = """ + class Test + { + class Goo + { + class Bar { void M() { - _ = typeof(Goo).Name; + _ = [|typeof(Bar).Name|]; } } } - """; - await VerifyCS.VerifyCodeFixAsync(text, text); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47129")] - public async Task NestedInGenericType() - { - var text = """ - class Test - { - class Goo + } + """; + var expected = """ + class Test + { + class Goo + { + class Bar { - class Bar - { - void M() - { - _ = [|typeof(Bar).Name|]; - } + void M() + { + _ = nameof(Bar); } } } - """; - var expected = """ - class Test + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47129")] + public async Task NestedInGenericType2() + { + var text = """ + using System; + using System.Collections.Generic; + + class Test + { + public void M() { - class Goo - { - class Bar - { - void M() - { - _ = nameof(Bar); - } - } - } + Console.WriteLine([|typeof(List.Enumerator).Name|]); } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + var expected = """ + using System; + using System.Collections.Generic; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47129")] - public async Task NestedInGenericType2() - { - var text = """ - using System; - using System.Collections.Generic; - - class Test + class Test + { + public void M() { - public void M() - { - Console.WriteLine([|typeof(List.Enumerator).Name|]); - } + Console.WriteLine(nameof(List.Enumerator)); } - """; - var expected = """ - using System; - using System.Collections.Generic; + } + """; + await VerifyCS.VerifyCodeFixAsync(text, expected); + } - class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54233")] + public async Task NotOnVoid() + { + var text = """ + class C + { + void M() { - public void M() - { - Console.WriteLine(nameof(List.Enumerator)); - } + var x = typeof(void).Name; } - """; - await VerifyCS.VerifyCodeFixAsync(text, expected); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(text, text); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54233")] - public async Task NotOnVoid() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47128")] + public async Task TestNint() + { + await new VerifyCS.Test { - var text = """ + TestCode = """ + using System; + class C { void M() { - var x = typeof(void).Name; + Console.WriteLine([|typeof(nint).Name|]); } } - """; - await VerifyCS.VerifyCodeFixAsync(text, text); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47128")] - public async Task TestNint() - { - await new VerifyCS.Test - { - TestCode = """ - using System; - - class C - { - void M() - { - Console.WriteLine([|typeof(nint).Name|]); - } - } - """, - FixedCode = """ - using System; + """, + FixedCode = """ + using System; - class C + class C + { + void M() { - void M() - { - Console.WriteLine(nameof(IntPtr)); - } + Console.WriteLine(nameof(IntPtr)); } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/DisambiguateSameVariable/DisambiguateSameVariableTests.cs b/src/Analyzers/CSharp/Tests/DisambiguateSameVariable/DisambiguateSameVariableTests.cs index 37f209f41dd98..c15f16ce070d2 100644 --- a/src/Analyzers/CSharp/Tests/DisambiguateSameVariable/DisambiguateSameVariableTests.cs +++ b/src/Analyzers/CSharp/Tests/DisambiguateSameVariable/DisambiguateSameVariableTests.cs @@ -9,400 +9,399 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DisambiguateSameVariable -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpDisambiguateSameVariableCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DisambiguateSameVariable; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpDisambiguateSameVariableCodeFixProvider>; - public class DisambiguateSameVariableTests +public class DisambiguateSameVariableTests +{ + [Fact] + public async Task TestParamToParamWithNoMatch() { - [Fact] - public async Task TestParamToParamWithNoMatch() - { - var code = """ - class C + var code = """ + class C + { + void M(int a) { - void M(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestLocalToLocalWithNoMatch() - { - var code = """ - class C + [Fact] + public async Task TestLocalToLocalWithNoMatch() + { + var code = """ + class C + { + void M() { - void M() - { - var a = 0; - {|CS1717:a = a|}; - } + var a = 0; + {|CS1717:a = a|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestFieldToFieldWithNoMatch() - { - var code = """ - class C + [Fact] + public async Task TestFieldToFieldWithNoMatch() + { + var code = """ + class C + { + int a; + void M() { - int a; - void M() - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithSameNamedField() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithSameNamedField() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int a; + void M(int a) { - int a; - void M(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + int a; + void M(int a) { - int a; - void M(int a) - { - this.a = a; - } + this.a = a; } - """); - } + } + """); + } - [Fact] - public async Task TestFieldToFieldWithNonMatchingField() - { - var code = """ - class C + [Fact] + public async Task TestFieldToFieldWithNonMatchingField() + { + var code = """ + class C + { + int x; + void M() { - int x; - void M() - { - {|CS0103:a|} = {|CS0103:a|}; - } + {|CS0103:a|} = {|CS0103:a|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithUnderscoreNamedField() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithUnderscoreNamedField() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int _a; + void M(int a) { - int _a; - void M(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + int _a; + void M(int a) { - int _a; - void M(int a) - { - _a = a; - } + _a = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithCapitalizedField() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithCapitalizedField() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int A; + void M(int a) { - int A; - void M(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + int A; + void M(int a) { - int A; - void M(int a) - { - A = a; - } + A = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithProperty() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithProperty() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int A { get; set; } + void M(int a) { - int A { get; set; } - void M(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + int A { get; set; } + void M(int a) { - int A { get; set; } - void M(int a) - { - A = a; - } + A = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithReadOnlyFieldInConstructor() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithReadOnlyFieldInConstructor() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + readonly int a; + public C(int a) { - readonly int a; - public C(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + readonly int a; + public C(int a) { - readonly int a; - public C(int a) - { - this.a = a; - } + this.a = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithReadOnlyFieldOutsideOfConstructor() - { - // Not legal, but is at least something they might want. - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithReadOnlyFieldOutsideOfConstructor() + { + // Not legal, but is at least something they might want. + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + readonly int a; + void M(int a) { - readonly int a; - void M(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + readonly int a; + void M(int a) { - readonly int a; - void M(int a) - { - {|CS0191:this.a|} = a; - } + {|CS0191:this.a|} = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamWithAccessibleFieldInBaseType() - { - await VerifyCS.VerifyCodeFixAsync(""" - class Base - { - protected int a; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamWithAccessibleFieldInBaseType() + { + await VerifyCS.VerifyCodeFixAsync(""" + class Base + { + protected int a; + } - class C : Base + class C : Base + { + public C(int a) { - public C(int a) - { - {|CS1717:a = a|}; - } - } - """, """ - class Base - { - protected int a; + {|CS1717:a = a|}; } + } + """, """ + class Base + { + protected int a; + } - class C : Base + class C : Base + { + public C(int a) { - public C(int a) - { - this.a = a; - } + this.a = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamNotWithInaccessibleFieldInBaseType() - { - var code = """ - class Base - { - private int a; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamNotWithInaccessibleFieldInBaseType() + { + var code = """ + class Base + { + private int a; + } - class C : Base + class C : Base + { + public C(int a) { - public C(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamNotWithStaticField() - { - var code = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamNotWithStaticField() + { + var code = """ + class C + { + static int a; + public C(int a) { - static int a; - public C(int a) - { - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestParamToParamCompareWithSameNamedField() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestParamToParamCompareWithSameNamedField() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int a; + void M(int a) { - int a; - void M(int a) + if ({|CS1718:a == a|}) { - if ({|CS1718:a == a|}) - { - } } } - """, """ - class C + } + """, """ + class C + { + int a; + void M(int a) { - int a; - void M(int a) + if (this.a == a) { - if (this.a == a) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int a; + void M(int a) { - int a; - void M(int a) - { - {|CS1717:a = a|}; - {|CS1717:a = a|}; - } + {|CS1717:a = a|}; + {|CS1717:a = a|}; } - """, """ - class C + } + """, """ + class C + { + int a; + void M(int a) { - int a; - void M(int a) - { - this.a = a; - this.a = a; - } + this.a = a; + this.a = a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestFieldToFieldWithPropAvailableOffOfThis() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestFieldToFieldWithPropAvailableOffOfThis() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int a; + int A { get; set; } + void M() { - int a; - int A { get; set; } - void M() - { - {|CS1717:this.a = this.a|}; - } + {|CS1717:this.a = this.a|}; } - """, """ - class C + } + """, """ + class C + { + int a; + int A { get; set; } + void M() { - int a; - int A { get; set; } - void M() - { - this.A = this.a; - } + this.A = this.a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] - public async Task TestFieldToFieldWithPropAvailableOffOfOtherInstance() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28290")] + public async Task TestFieldToFieldWithPropAvailableOffOfOtherInstance() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int a; + int A { get; set; } + void M(C c) { - int a; - int A { get; set; } - void M(C c) - { - {|CS1717:c.a = c.a|}; - } + {|CS1717:c.a = c.a|}; } - """, """ - class C + } + """, """ + class C + { + int a; + int A { get; set; } + void M(C c) { - int a; - int A { get; set; } - void M(C c) - { - c.A = c.a; - } + c.A = c.a; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/DocumentationComments/AddDocCommentNodesCodeFixProviderTests.cs b/src/Analyzers/CSharp/Tests/DocumentationComments/AddDocCommentNodesCodeFixProviderTests.cs index 3ec80a9afe51d..6e3d87d569712 100644 --- a/src/Analyzers/CSharp/Tests/DocumentationComments/AddDocCommentNodesCodeFixProviderTests.cs +++ b/src/Analyzers/CSharp/Tests/DocumentationComments/AddDocCommentNodesCodeFixProviderTests.cs @@ -13,884 +13,883 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DocumentationComments +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DocumentationComments; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] +public class AddDocCommentNodesCodesFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public class AddDocCommentNodesCodesFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + private static readonly CSharpParseOptions Regular = new(kind: SourceCodeKind.Regular); + + public AddDocCommentNodesCodesFixProviderTests(ITestOutputHelper logger) + : base(logger) { - private static readonly CSharpParseOptions Regular = new(kind: SourceCodeKind.Regular); - - public AddDocCommentNodesCodesFixProviderTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAddDocCommentNodesCodeFixProvider()); - - private async Task TestAsync(string initial, string expected) - { - var parseOptions = Regular.WithDocumentationMode(DocumentationMode.Diagnose); - await TestAsync(initial, expected, parseOptions: parseOptions); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_NoNodesBefore() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int [|i|], int j, int k) {} - } - """; + } - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_NoNodesAfter() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int i, int j, int [|k|]) {} - } - """; + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAddDocCommentNodesCodeFixProvider()); - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_NodesBeforeAndAfter() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - /// - public void Fizz(int i, int [|j|], int k) {} - } - """; + private async Task TestAsync(string initial, string expected) + { + var parseOptions = Regular.WithDocumentationMode(DocumentationMode.Diagnose); + await TestAsync(initial, expected, parseOptions: parseOptions); + } - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_NodesBeforeAndAfter_RawTextInComment() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - /// text - /// - public void Fizz(int i, int [|j|], int k) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_NoNodesBefore() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int [|i|], int j, int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - /// text - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_NodesBeforeAndAfter_WithContent() - { - var initial = - """ - class Program - { - /// - /// - /// - /// Parameter does something - /// Parameter does something else - public void Fizz(int i, int [|j|], int k) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_NoNodesAfter() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int i, int j, int [|k|]) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - /// Parameter does something - /// - /// Parameter does something else - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_NestedInSummaryTag() - { - var initial = - """ - class Program - { - /// - /// - /// - public void Fizz(int i, int j, int [|k|]) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_NodesBeforeAndAfter() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + /// + public void Fizz(int i, int [|j|], int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_BeforeNode_EverythingOnOneLine() - { - var initial = - """ - class Program - { - /// - public void Fizz(int [|i|], int j, int k) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_NodesBeforeAndAfter_RawTextInComment() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + /// text + /// + public void Fizz(int i, int [|j|], int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// text + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_AfterNode_EverythingOnOneLine() - { - var initial = - """ - class Program - { - /// - public void Fizz(int i, int j, int [|k|]) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_NodesBeforeAndAfter_WithContent() + { + var initial = + """ + class Program + { + /// + /// + /// + /// Parameter does something + /// Parameter does something else + public void Fizz(int i, int [|j|], int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// Parameter does something + /// + /// Parameter does something else + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_BeforeNode_JustParamNode() - { - var initial = - """ - class Program - { - /// - public void Fizz(int [|i|], int j, int k) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_NestedInSummaryTag() + { + var initial = + """ + class Program + { + /// + /// + /// + public void Fizz(int i, int j, int [|k|]) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_AfterNode_JustParamNode() - { - var initial = - """ - class Program - { - /// - public void Fizz(int i, int j, int [|k|]) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_BeforeNode_EverythingOnOneLine() + { + var initial = + """ + class Program + { + /// + public void Fizz(int [|i|], int j, int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_MultipleDocComments() - { - var initial = - """ - class Program - { - /// - // ... - /// - /// - /// - /// - public void Fizz(int [|i|], int j, int k) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_AfterNode_EverythingOnOneLine() + { + var initial = + """ + class Program + { + /// + public void Fizz(int i, int j, int [|k|]) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - // ... - /// - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_Ctor() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public Program(int [|i|], int j, int k) {} - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_BeforeNode_JustParamNode() + { + var initial = + """ + class Program + { + /// + public void Fizz(int [|i|], int j, int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - /// - public Program(int i, int j, int k) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_Delegate() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public delegate int Goo(int [|i|], int j, int k); - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_AfterNode_JustParamNode() + { + var initial = + """ + class Program + { + /// + public void Fizz(int i, int j, int [|k|]) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } - var expected = - """ - class Program - { - /// - /// - /// - /// - /// - /// - public delegate int Goo(int [|i|], int j, int k); - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_Operator() - { - var initial = - """ - public struct MyStruct + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_MultipleDocComments() + { + var initial = + """ + class Program + { + /// + // ... + /// + /// + /// + /// + public void Fizz(int [|i|], int j, int k) {} + } + """; + + var expected = + """ + class Program + { + /// + // ... + /// + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_Ctor() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public Program(int [|i|], int j, int k) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// + public Program(int i, int j, int k) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_Delegate() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public delegate int Goo(int [|i|], int j, int k); + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// + public delegate int Goo(int [|i|], int j, int k); + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_Operator() + { + var initial = + """ + public struct MyStruct + { + public int Val { get; } + + public MyStruct(int val) { - public int Val { get; } - - public MyStruct(int val) - { - Val = val; - } - - /// - /// - /// - /// - /// - public static MyStruct operator +(MyStruct s1, MyStruct [|s2|]) - { - return new MyStruct(s1.Val + s2.Val); - } + Val = val; } - """; - var expected = - """ - public struct MyStruct + /// + /// + /// + /// + /// + public static MyStruct operator +(MyStruct s1, MyStruct [|s2|]) { - public int Val { get; } - - public MyStruct(int val) - { - Val = val; - } - - /// - /// - /// - /// - /// - /// - public static MyStruct operator +(MyStruct s1, MyStruct s2) - { - return new MyStruct(s1.Val + s2.Val); - } + return new MyStruct(s1.Val + s2.Val); } - """; - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument_MultipleParamNodesInVariousPlaces() - { - var initial = - """ - class Program + } + """; + + var expected = + """ + public struct MyStruct + { + public int Val { get; } + + public MyStruct(int val) { - /// - /// - /// - /// - public void Fizz(int i, int {|FixAllInDocument:j|}, int k, int l) {} + Val = val; } - """; - var expected = - """ - class Program + /// + /// + /// + /// + /// + /// + public static MyStruct operator +(MyStruct s1, MyStruct s2) { - /// - /// - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k, int l) {} + return new MyStruct(s1.Val + s2.Val); } - """; - - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument() - { - var initial = """ - - - - - /// - /// - /// - /// - public void Fizz(int i, int j, {|FixAllInDocument:int k|}) {} - - /// - /// - /// - /// - /// - /// - public int Buzz(int i, int j, int k) { returns 0; } - }]]> - - - - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - - /// - /// - /// - /// - /// - /// - /// - public int Buzz(int i, int j, int k) { returns 0; } - }]]> - - - - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - """; - - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject() - { - var initial = """ - - - - - /// - /// - /// - /// - public void Fizz(int i, int j, {|FixAllInProject:int k|}) {} - }]]> - - - - /// - /// - /// - /// - /// - public int Buzz(int i, int j, int k) { returns 0; } - }]]> - - - - - - /// - /// - /// - /// - /// - public int Buzz(int i, int j, int k) { returns 0; } - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - /// - /// - /// - /// - /// - /// - public int Buzz(int i, int j, int k) { returns 0; } - }]]> - - - - - - /// - /// - /// - /// - /// - public int Buzz(int i, int j, int k) { returns 0; } - }]]> - - - - """; - - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution() - { - var initial = """ - - - - - /// - /// - /// - /// - public void Fizz(int i, int j, {|FixAllInSolution:int k|}) {} - }]]> - - - - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - - - /// - /// - /// - /// - /// - public void Fizz(int i, int j, int k) {} - }]]> - - - - """; + } + """; + await TestAsync(initial, expected); + } - await TestAsync(initial, expected); - } + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument_MultipleParamNodesInVariousPlaces() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int i, int {|FixAllInDocument:j|}, int k, int l) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k, int l) {} + } + """; + + await TestAsync(initial, expected); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - [WorkItem("https://github.com/dotnet/roslyn/issues/52738")] - public async Task AddsParamTag_Record() - { - var initial = """ + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() + { + var initial = """ + + + + /// /// - /// - record R(int [|First|], int Second, int Third); - """; + /// + /// + public void Fizz(int i, int j, {|FixAllInDocument:int k|}) {} - var expected = """ /// /// /// - /// - /// - /// - record R(int First, int Second, int Third); - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_Class() - { - var initial = """ + /// + /// + /// + public int Buzz(int i, int j, int k) { returns 0; } + }]]> + + + + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + """; + + var expected = """ + + + + /// /// - /// - class R(int [|First|], int Second, int Third); - """; + /// + /// + /// + public void Fizz(int i, int j, int k) {} - var expected = """ /// /// /// - /// - /// - /// - class R(int First, int Second, int Third); - """; - await TestAsync(initial, expected); - } + /// + /// + /// + /// + public int Buzz(int i, int j, int k) { returns 0; } + }]]> + + + + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + """; + + await TestAsync(initial, expected); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] - public async Task AddsParamTag_Struct() - { - var initial = """ + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var initial = """ + + + + + /// + /// + /// + /// + public void Fizz(int i, int j, {|FixAllInProject:int k|}) {} + }]]> + + + + /// + /// + /// + /// + /// + public int Buzz(int i, int j, int k) { returns 0; } + }]]> + + + + + /// /// - /// - struct R(int [|First|], int Second, int Third); - """; + /// + /// + /// + public int Buzz(int i, int j, int k) { returns 0; } + }]]> + + + + """; + + var expected = """ + + + + + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + /// + /// + /// + /// + /// + /// + public int Buzz(int i, int j, int k) { returns 0; } + }]]> + + + + + + /// + /// + /// + /// + /// + public int Buzz(int i, int j, int k) { returns 0; } + }]]> + + + + """; + + await TestAsync(initial, expected); + } - var expected = """ + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() + { + var initial = """ + + + + + /// + /// + /// + /// + public void Fizz(int i, int j, {|FixAllInSolution:int k|}) {} + }]]> + + + + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + """; + + var expected = """ + + + + + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + /// /// - /// - /// - /// - struct R(int First, int Second, int Third); - """; - await TestAsync(initial, expected); - } + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + + + /// + /// + /// + /// + /// + public void Fizz(int i, int j, int k) {} + }]]> + + + + """; + + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + [WorkItem("https://github.com/dotnet/roslyn/issues/52738")] + public async Task AddsParamTag_Record() + { + var initial = """ + /// + /// + /// + /// + record R(int [|First|], int Second, int Third); + """; + + var expected = """ + /// + /// + /// + /// + /// + /// + record R(int First, int Second, int Third); + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_Class() + { + var initial = """ + /// + /// + /// + /// + class R(int [|First|], int Second, int Third); + """; + + var expected = """ + /// + /// + /// + /// + /// + /// + class R(int First, int Second, int Third); + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddDocCommentNodes)] + public async Task AddsParamTag_Struct() + { + var initial = """ + /// + /// + /// + /// + struct R(int [|First|], int Second, int Third); + """; + + var expected = """ + /// + /// + /// + /// + /// + /// + struct R(int First, int Second, int Third); + """; + await TestAsync(initial, expected); } } diff --git a/src/Analyzers/CSharp/Tests/DocumentationComments/RemoveDocCommentNodeCodeFixProviderTests.cs b/src/Analyzers/CSharp/Tests/DocumentationComments/RemoveDocCommentNodeCodeFixProviderTests.cs index a6e03154f08bc..a48d5aebecf2f 100644 --- a/src/Analyzers/CSharp/Tests/DocumentationComments/RemoveDocCommentNodeCodeFixProviderTests.cs +++ b/src/Analyzers/CSharp/Tests/DocumentationComments/RemoveDocCommentNodeCodeFixProviderTests.cs @@ -13,822 +13,821 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DocumentationComments +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.DocumentationComments; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] +public class RemoveDocCommentNodeCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public class RemoveDocCommentNodeCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + private static readonly CSharpParseOptions Regular = new(kind: SourceCodeKind.Regular); + + public RemoveDocCommentNodeCodeFixProviderTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpRemoveDocCommentNodeCodeFixProvider()); + + private async Task TestAsync(string initial, string expected) + { + var parseOptions = Regular.WithDocumentationMode(DocumentationMode.Diagnose); + await TestAsync(initial, expected, parseOptions: parseOptions); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag_OnlyParamTags() + { + var initial = + """ + class Program + { + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag_TagBelowOffendingParamTag() + { + var initial = + """ + class Program + { + /// + /// + /// + public int Fizz(int value) { return 0; } + } + """; + + var expected = + """ + class Program + { + /// + /// + public int Fizz(int value) { return 0; } + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag_BothParamTagsOnSameLine_DocCommentTagBetweenThem() + { + var initial = + """ + class Program + { + /// + /// + /// + /// /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag_BothParamTagsOnSameLine_WhitespaceBetweenThem() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag_BothParamTagsOnSameLine_NothingBetweenThem1() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13436")] + public async Task RemovesTag_BothParamTagsOnSameLine_NothingBetweenThem2() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13436")] + public async Task RemovesTag_TrailingTextAfterTag() + { + var initial = + """ + class Program + { + /// + /// + /// + /// a + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// a + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateParamTag_RawTextBeforeAndAfterNode() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + /// some commentout of the XML nodes + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + /// some commentout of the XML nodes + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesDuplicateTypeparamTag() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + /// + public void Fizz() { } + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + /// + public void Fizz() { } + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesParamTagWithNoMatchingParameter() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesParamTag_NestedInSummaryTag() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] + public async Task RemovesParamTag_NestedInSummaryTag_WithChildren() + { + var initial = + """ + class Program + { + /// + /// + /// + /// + /// + /// + public void Fizz(int value) {} + } + """; + + var expected = + """ + class Program + { + /// + /// + /// + public void Fizz(int value) {} + } + """; + await TestAsync(initial, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllTypeparamInDocument_DoesNotFixDuplicateParamTags() + { + var initial = """ + + + + + /// + /// + /// + /// + /// + /// + /// + public void Fizz(int value) {} + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public int Buzz(int value) { returns 0; } + }]]> + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + var expected = """ + + + + + /// + /// + /// + /// + /// + /// + public void Fizz(int value) {} + + /// + /// + /// + /// + /// + /// + /// + /// + public int Buzz(int value) { returns 0; } + }]]> + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + await TestAsync(initial, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() + { + var initial = """ + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + + /// + /// + /// + /// + /// + /// + public int Buzz(int value) { returns 0; } + }]]> + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + var expected = """ + + + + + /// + /// + /// + public void Fizz(int value) {} + + /// + /// + /// + /// + /// + public int Buzz(int value) { returns 0; } + }]]> + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + await TestAsync(initial, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var initial = """ + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + var expected = """ + + + + + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + await TestAsync(initial, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() { - private static readonly CSharpParseOptions Regular = new(kind: SourceCodeKind.Regular); - - public RemoveDocCommentNodeCodeFixProviderTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpRemoveDocCommentNodeCodeFixProvider()); - - private async Task TestAsync(string initial, string expected) - { - var parseOptions = Regular.WithDocumentationMode(DocumentationMode.Diagnose); - await TestAsync(initial, expected, parseOptions: parseOptions); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag_OnlyParamTags() - { - var initial = - """ - class Program - { - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag_TagBelowOffendingParamTag() - { - var initial = - """ - class Program - { - /// - /// - /// - public int Fizz(int value) { return 0; } - } - """; - - var expected = - """ - class Program - { - /// - /// - public int Fizz(int value) { return 0; } - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag_BothParamTagsOnSameLine_DocCommentTagBetweenThem() - { - var initial = - """ - class Program - { - /// - /// - /// - /// /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag_BothParamTagsOnSameLine_WhitespaceBetweenThem() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag_BothParamTagsOnSameLine_NothingBetweenThem1() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13436")] - public async Task RemovesTag_BothParamTagsOnSameLine_NothingBetweenThem2() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13436")] - public async Task RemovesTag_TrailingTextAfterTag() - { - var initial = - """ - class Program - { - /// - /// - /// - /// a - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// a - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateParamTag_RawTextBeforeAndAfterNode() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - /// some commentout of the XML nodes - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - /// some commentout of the XML nodes - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesDuplicateTypeparamTag() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - /// - public void Fizz() { } - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - /// - public void Fizz() { } - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesParamTagWithNoMatchingParameter() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesParamTag_NestedInSummaryTag() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveDocCommentNode)] - public async Task RemovesParamTag_NestedInSummaryTag_WithChildren() - { - var initial = - """ - class Program - { - /// - /// - /// - /// - /// - /// - public void Fizz(int value) {} - } - """; - - var expected = - """ - class Program - { - /// - /// - /// - public void Fizz(int value) {} - } - """; - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllTypeparamInDocument_DoesNotFixDuplicateParamTags() - { - var initial = """ - - - - - /// - /// - /// - /// - /// - /// - /// - public void Fizz(int value) {} - - /// - /// - /// - /// - /// - /// - /// - /// - /// - public int Buzz(int value) { returns 0; } - }]]> - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - /// - /// - /// - public void Fizz(int value) {} - - /// - /// - /// - /// - /// - /// - /// - /// - public int Buzz(int value) { returns 0; } - }]]> - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument() - { - var initial = """ - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - - /// - /// - /// - /// - /// - /// - public int Buzz(int value) { returns 0; } - }]]> - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - public void Fizz(int value) {} - - /// - /// - /// - /// - /// - public int Buzz(int value) { returns 0; } - }]]> - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject() - { - var initial = """ - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - await TestAsync(initial, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution() - { - var initial = """ - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - var expected = """ - - - - - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - - - /// - /// - /// - public void Fizz(int value) {} - }]]> - - - - """; - - await TestAsync(initial, expected); - } + var initial = """ + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + var expected = """ + + + + + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + + + /// + /// + /// + public void Fizz(int value) {} + }]]> + + + + """; + + await TestAsync(initial, expected); } } diff --git a/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs b/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs index 7e15d5997a092..70a4e835c508c 100644 --- a/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs +++ b/src/Analyzers/CSharp/Tests/FileHeaders/FileHeaderTests.cs @@ -11,425 +11,425 @@ Microsoft.CodeAnalysis.CSharp.FileHeaders.CSharpFileHeaderDiagnosticAnalyzer, Microsoft.CodeAnalysis.CSharp.FileHeaders.CSharpFileHeaderCodeFixProvider>; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.FileHeaders +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.FileHeaders; + +public class FileHeaderTests { - public class FileHeaderTests + private const string TestSettings = """ + [*.cs] + file_header_template = Copyright (c) SomeCorp. All rights reserved.\nLicensed under the ??? license. See LICENSE file in the project root for full license information. + """; + + private const string TestSettingsWithEmptyLines = """ + [*.cs] + file_header_template = \nCopyright (c) SomeCorp. All rights reserved.\n\nLicensed under the ??? license. See LICENSE file in the project root for full license information.\n + """; + + /// + /// Verifies that the analyzer will not report a diagnostic when the file header is not configured. + /// + /// A representing the asynchronous unit test. + [Theory] + [InlineData("")] + [InlineData("file_header_template =")] + [InlineData("file_header_template = unset")] + public async Task TestFileHeaderNotConfiguredAsync(string fileHeaderTemplate) { - private const string TestSettings = """ - [*.cs] - file_header_template = Copyright (c) SomeCorp. All rights reserved.\nLicensed under the ??? license. See LICENSE file in the project root for full license information. - """; - - private const string TestSettingsWithEmptyLines = """ - [*.cs] - file_header_template = \nCopyright (c) SomeCorp. All rights reserved.\n\nLicensed under the ??? license. See LICENSE file in the project root for full license information.\n + var testCode = """ + namespace N + { + } """; - /// - /// Verifies that the analyzer will not report a diagnostic when the file header is not configured. - /// - /// A representing the asynchronous unit test. - [Theory] - [InlineData("")] - [InlineData("file_header_template =")] - [InlineData("file_header_template = unset")] - public async Task TestFileHeaderNotConfiguredAsync(string fileHeaderTemplate) + await new VerifyCS.Test { - var testCode = """ - namespace N - { - } - """; - - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = testCode, - EditorConfig = $@" + TestCode = testCode, + FixedCode = testCode, + EditorConfig = $@" [*] {fileHeaderTemplate} ", - }.RunAsync(); - } - - /// - /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. - /// - /// A representing the asynchronous unit test. - [Theory] - [InlineData("\n")] - [InlineData("\r\n")] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1414432")] - public async Task TestNoFileHeaderAsync(string lineEnding) - { - var testCode = """ - [||]namespace N - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - namespace N - { - } - """; - - await new VerifyCS.Test + }.RunAsync(); + } + + /// + /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. + /// + /// A representing the asynchronous unit test. + [Theory] + [InlineData("\n")] + [InlineData("\r\n")] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1414432")] + public async Task TestNoFileHeaderAsync(string lineEnding) + { + var testCode = """ + [||]namespace N { - TestCode = testCode.ReplaceLineEndings(lineEnding), - FixedCode = fixedCode.ReplaceLineEndings(lineEnding), - EditorConfig = TestSettings, - Options = - { - { FormattingOptions2.NewLine, lineEnding }, - }, - }.RunAsync(); - } - - /// - /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestNoFileHeaderWithUsingDirectiveAsync() + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + namespace N + { + } + """; + + await new VerifyCS.Test { - var testCode = """ - [||]using System; + TestCode = testCode.ReplaceLineEndings(lineEnding), + FixedCode = fixedCode.ReplaceLineEndings(lineEnding), + EditorConfig = TestSettings, + Options = + { + { FormattingOptions2.NewLine, lineEnding }, + }, + }.RunAsync(); + } - namespace N - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + /// + /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestNoFileHeaderWithUsingDirectiveAsync() + { + var testCode = """ + [||]using System; - using System; + namespace N + { + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - namespace N - { - } - """; + using System; - await new VerifyCS.Test + namespace N { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestNoFileHeaderWithBlankLineAndUsingDirectiveAsync() + } + """; + + await new VerifyCS.Test { - var testCode = """ - [||] - using System; - - namespace N - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - using System; - - namespace N - { - } - """; - - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestNoFileHeaderWithBlankLineAndUsingDirectiveAsync() + { + var testCode = """ + [||] + using System; + + namespace N + { + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + using System; + + namespace N { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestNoFileHeaderWithWhitespaceLineAsync() + } + """; + + await new VerifyCS.Test { - var testCode = "[||] " + """ + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } - using System; + /// + /// Verifies that the analyzer will report a diagnostic when the file is completely missing a header. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestNoFileHeaderWithWhitespaceLineAsync() + { + var testCode = "[||] " + """ - namespace N - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + using System; - using System; + namespace N + { + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - namespace N - { - } - """; + using System; - await new VerifyCS.Test + namespace N { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that the built-in variable fileName works as expected. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestFileNameBuiltInVariableAsync() + } + """; + + await new VerifyCS.Test { - var editorConfig = """ - [*.cs] - file_header_template = {fileName} Copyright (c) SomeCorp. All rights reserved.\nLicensed under the ??? license. See LICENSE file in the project root for full license information. - """; - - var testCode = """ - [||]namespace N - { - } - """; - var fixedCode = """ - // Test0.cs Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - namespace N - { - } - """; - - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that the built-in variable fileName works as expected. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestFileNameBuiltInVariableAsync() + { + var editorConfig = """ + [*.cs] + file_header_template = {fileName} Copyright (c) SomeCorp. All rights reserved.\nLicensed under the ??? license. See LICENSE file in the project root for full license information. + """; + + var testCode = """ + [||]namespace N + { + } + """; + var fixedCode = """ + // Test0.cs Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + namespace N { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = editorConfig, - }.RunAsync(); - } - - /// - /// Verifies that a valid file header built using single line comments will not produce a diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestValidFileHeaderWithSingleLineCommentsAsync() + } + """; + + await new VerifyCS.Test { - var testCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = editorConfig, + }.RunAsync(); + } - namespace Bar - { - } - """; + /// + /// Verifies that a valid file header built using single line comments will not produce a diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestValidFileHeaderWithSingleLineCommentsAsync() + { + var testCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - await new VerifyCS.Test + namespace Bar { - TestCode = testCode, - FixedCode = testCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that a valid file header built using multi-line comments will not produce a diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestValidFileHeaderWithMultiLineComments1Async() + } + """; + + await new VerifyCS.Test { - var testCode = """ - /* Copyright (c) SomeCorp. All rights reserved. - * Licensed under the ??? license. See LICENSE file in the project root for full license information. - */ + TestCode = testCode, + FixedCode = testCode, + EditorConfig = TestSettings, + }.RunAsync(); + } - namespace Bar - { - } - """; + /// + /// Verifies that a valid file header built using multi-line comments will not produce a diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestValidFileHeaderWithMultiLineComments1Async() + { + var testCode = """ + /* Copyright (c) SomeCorp. All rights reserved. + * Licensed under the ??? license. See LICENSE file in the project root for full license information. + */ - await new VerifyCS.Test + namespace Bar { - TestCode = testCode, - FixedCode = testCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that a valid file header built using multi-line comments will not produce a diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestValidFileHeaderWithMultiLineComments2Async() + } + """; + + await new VerifyCS.Test { - var testCode = """ - /* Copyright (c) SomeCorp. All rights reserved. - Licensed under the ??? license. See LICENSE file in the project root for full license information. */ + TestCode = testCode, + FixedCode = testCode, + EditorConfig = TestSettings, + }.RunAsync(); + } - namespace Bar - { - } - """; + /// + /// Verifies that a valid file header built using multi-line comments will not produce a diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestValidFileHeaderWithMultiLineComments2Async() + { + var testCode = """ + /* Copyright (c) SomeCorp. All rights reserved. + Licensed under the ??? license. See LICENSE file in the project root for full license information. */ - await new VerifyCS.Test + namespace Bar { - TestCode = testCode, - FixedCode = testCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that a valid file header built using unterminated multi-line comments will not produce a diagnostic - /// message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestValidFileHeaderWithMultiLineComments3Async() + } + """; + + await new VerifyCS.Test { - var testCode = """ - /* Copyright (c) SomeCorp. All rights reserved. - Licensed under the ??? license. See LICENSE file in the project root for full license information. - """; + TestCode = testCode, + FixedCode = testCode, + EditorConfig = TestSettings, + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = testCode, - ExpectedDiagnostics = - { - // /0/Test0.cs(1,1): error CS1035: End-of-file found, '*/' expected - DiagnosticResult.CompilerError("CS1035").WithSpan(1, 1, 1, 1), - }, - FixedCode = testCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that a file header without text / only whitespace will produce the expected diagnostic message. - /// - /// The comment text. - /// A representing the asynchronous unit test. - [Theory] - [InlineData("[|//|]")] - [InlineData("[|//|] ")] - public async Task TestInvalidFileHeaderWithoutTextAsync(string comment) + /// + /// Verifies that a valid file header built using unterminated multi-line comments will not produce a diagnostic + /// message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestValidFileHeaderWithMultiLineComments3Async() + { + var testCode = """ + /* Copyright (c) SomeCorp. All rights reserved. + Licensed under the ??? license. See LICENSE file in the project root for full license information. + """; + + await new VerifyCS.Test { - var testCode = $@"{comment} + TestCode = testCode, + ExpectedDiagnostics = + { + // /0/Test0.cs(1,1): error CS1035: End-of-file found, '*/' expected + DiagnosticResult.CompilerError("CS1035").WithSpan(1, 1, 1, 1), + }, + FixedCode = testCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that a file header without text / only whitespace will produce the expected diagnostic message. + /// + /// The comment text. + /// A representing the asynchronous unit test. + [Theory] + [InlineData("[|//|]")] + [InlineData("[|//|] ")] + public async Task TestInvalidFileHeaderWithoutTextAsync(string comment) + { + var testCode = $@"{comment} namespace Bar {{ }}"; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - namespace Bar - { - } - """; - - await new VerifyCS.Test + namespace Bar { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestInvalidFileHeaderWithWrongTextAsync() + } + """; + + await new VerifyCS.Test { - var testCode = """ - [|//|] Copyright (c) OtherCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - namespace Bar - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - namespace Bar - { - } - """; - - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestInvalidFileHeaderWithWrongTextAsync() + { + var testCode = """ + [|//|] Copyright (c) OtherCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + namespace Bar + { + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + namespace Bar { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestInvalidFileHeaderWithWrongText2Async() + } + """; + + await new VerifyCS.Test { - var testCode = """ - [|/*|] Copyright (c) OtherCorp. All rights reserved. - * Licensed under the ??? license. See LICENSE file in the project root for full license information. - */ - - namespace Bar - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - /* Copyright (c) OtherCorp. All rights reserved. - * Licensed under the ??? license. See LICENSE file in the project root for full license information. - */ - - namespace Bar - { - } - """; - - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestInvalidFileHeaderWithWrongText2Async() + { + var testCode = """ + [|/*|] Copyright (c) OtherCorp. All rights reserved. + * Licensed under the ??? license. See LICENSE file in the project root for full license information. + */ + + namespace Bar { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - [Theory] - [InlineData("", "")] - [InlineData(" Header", "")] - [InlineData(" Header", " Header")] - public async Task TestValidFileHeaderInRegionAsync(string startLabel, string endLabel) + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + /* Copyright (c) OtherCorp. All rights reserved. + * Licensed under the ??? license. See LICENSE file in the project root for full license information. + */ + + namespace Bar + { + } + """; + + await new VerifyCS.Test { - var testCode = $@"#region{startLabel} + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + [Theory] + [InlineData("", "")] + [InlineData(" Header", "")] + [InlineData(" Header", " Header")] + public async Task TestValidFileHeaderInRegionAsync(string startLabel, string endLabel) + { + var testCode = $@"#region{startLabel} // Copyright (c) SomeCorp. All rights reserved. // Licensed under the ??? license. See LICENSE file in the project root for full license information. #endregion{endLabel} @@ -439,21 +439,21 @@ namespace Bar }} "; - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = testCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - [Theory] - [InlineData("", "")] - [InlineData(" Header", "")] - [InlineData(" Header", " Header")] - public async Task TestInvalidFileHeaderWithWrongTextInRegionAsync(string startLabel, string endLabel) + await new VerifyCS.Test { - var testCode = $@"#region{startLabel} + TestCode = testCode, + FixedCode = testCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + [Theory] + [InlineData("", "")] + [InlineData(" Header", "")] + [InlineData(" Header", " Header")] + public async Task TestInvalidFileHeaderWithWrongTextInRegionAsync(string startLabel, string endLabel) + { + var testCode = $@"#region{startLabel} [|//|] Copyright (c) OtherCorp. All rights reserved. // Licensed under the ??? license. See LICENSE file in the project root for full license information. #endregion{endLabel} @@ -462,7 +462,7 @@ namespace Bar {{ }} "; - var fixedCode = $@"// Copyright (c) SomeCorp. All rights reserved. + var fixedCode = $@"// Copyright (c) SomeCorp. All rights reserved. // Licensed under the ??? license. See LICENSE file in the project root for full license information. #region{startLabel} @@ -475,164 +475,163 @@ namespace Bar }} "; - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestInvalidFileHeaderWithWrongTextInUnterminatedMultiLineComment1Async() + await new VerifyCS.Test { - var testCode = """ - {|CS1035:|}[|/*|] Copyright (c) OtherCorp. All rights reserved. - * Licensed under the ??? license. See LICENSE file in the project root for full license information. - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - {|CS1035:|}/* Copyright (c) OtherCorp. All rights reserved. - * Licensed under the ??? license. See LICENSE file in the project root for full license information. - """; - - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestInvalidFileHeaderWithWrongTextInUnterminatedMultiLineComment2Async() + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestInvalidFileHeaderWithWrongTextInUnterminatedMultiLineComment1Async() + { + var testCode = """ + {|CS1035:|}[|/*|] Copyright (c) OtherCorp. All rights reserved. + * Licensed under the ??? license. See LICENSE file in the project root for full license information. + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + {|CS1035:|}/* Copyright (c) OtherCorp. All rights reserved. + * Licensed under the ??? license. See LICENSE file in the project root for full license information. + """; + + await new VerifyCS.Test { - var testCode = """ - {|CS1035:|}[|/*|]/ - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } - {|CS1035:|}/*/ - """; + /// + /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestInvalidFileHeaderWithWrongTextInUnterminatedMultiLineComment2Async() + { + var testCode = """ + {|CS1035:|}[|/*|]/ + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. - /// - /// A representing the asynchronous unit test. - [Theory] - [InlineData("")] - [InlineData(" ")] - public async Task TestInvalidFileHeaderWithWrongTextAfterBlankLineAsync(string firstLine) + {|CS1035:|}/*/ + """; + + await new VerifyCS.Test { - var testCode = $@"{firstLine} + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + /// + /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. + /// + /// A representing the asynchronous unit test. + [Theory] + [InlineData("")] + [InlineData(" ")] + public async Task TestInvalidFileHeaderWithWrongTextAfterBlankLineAsync(string firstLine) + { + var testCode = $@"{firstLine} [|//|] Copyright (c) OtherCorp. All rights reserved. // Licensed under the ??? license. See LICENSE file in the project root for full license information. namespace Bar {{ }}"; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - namespace Bar - { - } - """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - await new VerifyCS.Test + namespace Bar { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - /// - /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. - /// - /// A representing the asynchronous unit test. - [Fact] - public async Task TestInvalidFileHeaderWithWrongTextFollowedByCommentAsync() + } + """; + + await new VerifyCS.Test { - var testCode = """ - [|//|] Copyright (c) OtherCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } - //using System; + /// + /// Verifies that an invalid file header built using single line comments will produce the expected diagnostic message. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestInvalidFileHeaderWithWrongTextFollowedByCommentAsync() + { + var testCode = """ + [|//|] Copyright (c) OtherCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - namespace Bar - { - } - """; - var fixedCode = """ - // Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. + //using System; - //using System; + namespace Bar + { + } + """; + var fixedCode = """ + // Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. - namespace Bar - { - } - """; + //using System; - await new VerifyCS.Test + namespace Bar { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettings, - }.RunAsync(); - } - - [Fact] - public async Task TestHeaderMissingRequiredNewLinesAsync() + } + """; + + await new VerifyCS.Test { - var testCode = """ - [|//|] Copyright (c) SomeCorp. All rights reserved. - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - - namespace Bar - { - } - """; - var fixedCode = """ - // - // Copyright (c) SomeCorp. All rights reserved. - // - // Licensed under the ??? license. See LICENSE file in the project root for full license information. - // - - namespace Bar - { - } - """; - - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettings, + }.RunAsync(); + } + + [Fact] + public async Task TestHeaderMissingRequiredNewLinesAsync() + { + var testCode = """ + [|//|] Copyright (c) SomeCorp. All rights reserved. + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + + namespace Bar + { + } + """; + var fixedCode = """ + // + // Copyright (c) SomeCorp. All rights reserved. + // + // Licensed under the ??? license. See LICENSE file in the project root for full license information. + // + + namespace Bar { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = TestSettingsWithEmptyLines, - }.RunAsync(); - } + } + """; + + await new VerifyCS.Test + { + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = TestSettingsWithEmptyLines, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/FixIncorrectConstraint/FixIncorrectConstraintTests.cs b/src/Analyzers/CSharp/Tests/FixIncorrectConstraint/FixIncorrectConstraintTests.cs index c99241e00f24b..185acac7619e6 100644 --- a/src/Analyzers/CSharp/Tests/FixIncorrectConstraint/FixIncorrectConstraintTests.cs +++ b/src/Analyzers/CSharp/Tests/FixIncorrectConstraint/FixIncorrectConstraintTests.cs @@ -8,92 +8,91 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.FixIncorrectConstraint -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpFixIncorrectConstraintCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.FixIncorrectConstraint; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpFixIncorrectConstraintCodeFixProvider>; - public class FixIncorrectConstraintTests +public class FixIncorrectConstraintTests +{ + [Fact] + public async Task TestEnumConstraint() { - [Fact] - public async Task TestEnumConstraint() + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C where T : {|CS9010:enum|} { - TestCode = """ - class C where T : {|CS9010:enum|} - { - } - """, - FixedCode = """ - class C where T : struct, System.Enum - { - } - """, - }.RunAsync(); - } + } + """, + FixedCode = """ + class C where T : struct, System.Enum + { + } + """, + }.RunAsync(); + } - [Fact] - public async Task TestEnumConstraintWithUsing() + [Fact] + public async Task TestEnumConstraintWithUsing() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class C where T : {|CS9010:enum|} - { - } - """, - FixedCode = """ - using System; + class C where T : {|CS9010:enum|} + { + } + """, + FixedCode = """ + using System; - class C where T : struct, Enum - { - } - """, - }.RunAsync(); - } + class C where T : struct, Enum + { + } + """, + }.RunAsync(); + } - [Fact] - public async Task TestDelegateConstraint() + [Fact] + public async Task TestDelegateConstraint() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C where T : {|CS9011:delegate|} { - TestCode = """ - class C where T : {|CS9011:delegate|} - { - } - """, - FixedCode = """ - class C where T : System.Delegate - { - } - """, - }.RunAsync(); - } + } + """, + FixedCode = """ + class C where T : System.Delegate + { + } + """, + }.RunAsync(); + } - [Fact] - public async Task TestDelegateConstraintWithUsing() + [Fact] + public async Task TestDelegateConstraintWithUsing() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class C where T : {|CS9011:delegate|} - { - } - """, - FixedCode = """ - using System; + class C where T : {|CS9011:delegate|} + { + } + """, + FixedCode = """ + using System; - class C where T : Delegate - { - } - """, - }.RunAsync(); - } + class C where T : Delegate + { + } + """, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/FixReturnType/FixReturnTypeTests.cs b/src/Analyzers/CSharp/Tests/FixReturnType/FixReturnTypeTests.cs index 6f3733aa37bc4..cddfb81f7d86c 100644 --- a/src/Analyzers/CSharp/Tests/FixReturnType/FixReturnTypeTests.cs +++ b/src/Analyzers/CSharp/Tests/FixReturnType/FixReturnTypeTests.cs @@ -11,498 +11,497 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.FixReturnType +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.FixReturnType; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpFixReturnTypeCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsFixReturnType)] +public class FixReturnTypeTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpFixReturnTypeCodeFixProvider>; + [Fact] + public async Task Simple() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() + { + {|CS0127:return|} 1; + } + } + """, """ + class C + { + int M() + { + return 1; + } + } + """); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsFixReturnType)] - public class FixReturnTypeTests + [Fact] + public async Task Simple_WithTrivia() { - [Fact] - public async Task Simple() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + /*A*/ void /*B*/ M() { - void M() - { - {|CS0127:return|} 1; - } + {|CS0127:return|} 1; } - """, """ - class C + } + """, """ + class C + { + /*A*/ + int /*B*/ M() { - int M() - { - return 1; - } + return 1; } - """); - } + } + """); + // Note: the formatting change is introduced by Formatter.FormatAsync + } - [Fact] - public async Task Simple_WithTrivia() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ReturnString() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - /*A*/ void /*B*/ M() - { - {|CS0127:return|} 1; - } + {|CS0127:return|} ""; } - """, """ - class C + } + """, """ + class C + { + string M() { - /*A*/ - int /*B*/ M() - { - return 1; - } + return ""; } - """); - // Note: the formatting change is introduced by Formatter.FormatAsync - } + } + """); + } - [Fact] - public async Task ReturnString() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ReturnNull() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - {|CS0127:return|} ""; - } + {|CS0127:return|} null; } - """, """ - class C + } + """, """ + class C + { + object M() { - string M() - { - return ""; - } + return null; } - """); - } + } + """); + } - [Fact] - public async Task ReturnNull() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] + public async Task ReturnTypelessTuple() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - {|CS0127:return|} null; - } + {|CS0127:return|} (null, string.Empty); } - """, """ - class C + } + """, """ + class C + { + (object, string) M() { - object M() - { - return null; - } + return (null, string.Empty); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] - public async Task ReturnTypelessTuple() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] + public async Task ReturnTypelessTuple_Nested() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - {|CS0127:return|} (null, string.Empty); - } + {|CS0127:return|} ((5, null), string.Empty); } - """, """ - class C + } + """, """ + class C + { + ((int, object), string) M() { - (object, string) M() - { - return (null, string.Empty); - } + return ((5, null), string.Empty); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] - public async Task ReturnTypelessTuple_Nested() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] + public async Task ReturnTypelessTuple_Async() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + async void M() { - void M() - { - {|CS0127:return|} ((5, null), string.Empty); - } + {|CS0127:return|} (null, string.Empty); } - """, """ - class C + } + """, """ + class C + { + async System.Threading.Tasks.Task<(object, string)> M() { - ((int, object), string) M() - { - return ((5, null), string.Empty); - } + return (null, string.Empty); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] - public async Task ReturnTypelessTuple_Async() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] + public async Task ReturnTypelessTuple_Nested_Async() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + async void M() { - async void M() - { - {|CS0127:return|} (null, string.Empty); - } + {|CS0127:return|} ((5, null), string.Empty); } - """, """ - class C + } + """, """ + class C + { + async System.Threading.Tasks.Task<((int, object), string)> M() { - async System.Threading.Tasks.Task<(object, string)> M() - { - return (null, string.Empty); - } + return ((5, null), string.Empty); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65302")] - public async Task ReturnTypelessTuple_Nested_Async() + [Fact] + public async Task ReturnLambda() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ class C { - async void M() + void M() { - {|CS0127:return|} ((5, null), string.Empty); + {|CS0127:return|} () => {}; } } - """, """ + """, + FixedCode = """ class C { - async System.Threading.Tasks.Task<((int, object), string)> M() + object M() { - return ((5, null), string.Empty); + return () => {}; } } - """); - } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task ReturnLambda() - { - await new VerifyCS.Test + [Fact] + public async Task ReturnC() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C { - TestCode = """ - class C - { - void M() - { - {|CS0127:return|} () => {}; - } - } - """, - FixedCode = """ - class C - { - object M() - { - return () => {}; - } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } - - [Fact] - public async Task ReturnC() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + void M() { - void M() - { - {|CS0127:return|} new C(); - } + {|CS0127:return|} new C(); } - """, """ - class C + } + """, """ + class C + { + C M() { - C M() - { - return new C(); - } + return new C(); } - """); - } + } + """); + } - [Fact] - public async Task ReturnString_AsyncVoid() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ReturnString_AsyncVoid() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + async void M() { - async void M() - { - {|CS0127:return|} ""; - } + {|CS0127:return|} ""; } - """, """ - class C + } + """, """ + class C + { + async System.Threading.Tasks.Task M() { - async System.Threading.Tasks.Task M() - { - return ""; - } + return ""; } - """); - } + } + """); + } - [Fact] - public async Task ReturnString_AsyncVoid_WithUsing() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Threading.Tasks; + [Fact] + public async Task ReturnString_AsyncVoid_WithUsing() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Threading.Tasks; - class C + class C + { + async void M() { - async void M() - { - {|CS0127:return|} ""; - } + {|CS0127:return|} ""; } - """, """ - using System.Threading.Tasks; + } + """, """ + using System.Threading.Tasks; - class C + class C + { + async Task M() { - async Task M() - { - return ""; - } + return ""; } - """); - } + } + """); + } - [Fact] - public async Task ReturnString_AsyncTask() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ReturnString_AsyncTask() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + async System.Threading.Tasks.Task M() { - async System.Threading.Tasks.Task M() - { - {|CS1997:return|} ""; - } + {|CS1997:return|} ""; } - """, """ - class C + } + """, """ + class C + { + async System.Threading.Tasks.Task M() { - async System.Threading.Tasks.Task M() - { - return ""; - } + return ""; } - """); - } + } + """); + } - [Fact] - public async Task ReturnString_LocalFunction() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ReturnString_LocalFunction() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() + void local() { - void local() - { - {|CS0127:return|} ""; - } + {|CS0127:return|} ""; } } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() + string local() { - string local() - { - return ""; - } + return ""; } } - """); - } + } + """); + } - [Fact] - public async Task ReturnString_AsyncVoid_LocalFunction() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ReturnString_AsyncVoid_LocalFunction() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() + async void local() { - async void local() - { - {|CS0127:return|} ""; - } + {|CS0127:return|} ""; } } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() + async System.Threading.Tasks.Task local() { - async System.Threading.Tasks.Task local() - { - return ""; - } + return ""; } } - """); - } + } + """); + } - [Fact] - public async Task ExpressionBodied() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task ExpressionBodied() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() => {|CS0201:1|}; + } + """, """ + class C + { + int M() => 1; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47089")] + public async Task ExpressionAndReturnTypeAreVoid() + { + var markup = """ + using System; + + class C + { + void M() { - void M() => {|CS0201:1|}; + {|CS0127:return|} Console.WriteLine(); } - """, """ - class C + } + """; + await VerifyCS.VerifyCodeFixAsync(markup, markup); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53574")] + public async Task TestAnonymousTypeTopLevel() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + public void Method() { - int M() => 1; + {|CS0127:return|} new { A = 0, B = 1 }; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47089")] - public async Task ExpressionAndReturnTypeAreVoid() - { - var markup = """ - using System; - - class C + } + """, """ + class C + { + public object Method() { - void M() - { - {|CS0127:return|} Console.WriteLine(); - } + return new { A = 0, B = 1 }; } - """; - await VerifyCS.VerifyCodeFixAsync(markup, markup); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53574")] - public async Task TestAnonymousTypeTopLevel() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53574")] + public async Task TestAnonymousTypeTopNested() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + public void Method() { - public void Method() - { - {|CS0127:return|} new { A = 0, B = 1 }; - } + {|CS0127:return|} new[] { new { A = 0, B = 1 } }; } - """, """ - class C + } + """, """ + class C + { + public object Method() { - public object Method() - { - return new { A = 0, B = 1 }; - } + return new[] { new { A = 0, B = 1 } }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53574")] - public async Task TestAnonymousTypeTopNested() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64901")] + public async Task ReturnString_ValueTask() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ + using System.Threading.Tasks; + class C { - public void Method() + async ValueTask M() { - {|CS0127:return|} new[] { new { A = 0, B = 1 } }; + {|CS1997:return|} ""; } } - """, """ + """, + FixedCode = """ + using System.Threading.Tasks; + class C { - public object Method() + async ValueTask M() { - return new[] { new { A = 0, B = 1 } }; + return ""; } } - """); - } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64901")] - public async Task ReturnString_ValueTask() - { - await new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64901")] + public async Task ReturnString_CustomTaskType() + { + var markup = """ + using System.Runtime.CompilerServices; + + [AsyncMethodBuilder(typeof(C))] + class C { - TestCode = """ - using System.Threading.Tasks; - - class C - { - async ValueTask M() - { - {|CS1997:return|} ""; - } - } - """, - FixedCode = """ - using System.Threading.Tasks; - - class C - { - async ValueTask M() - { - return ""; - } - } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64901")] - public async Task ReturnString_CustomTaskType() - { - var markup = """ - using System.Runtime.CompilerServices; - - [AsyncMethodBuilder(typeof(C))] - class C + async C M() { - async C M() - { - {|CS1997:return|} ""; - } + {|CS1997:return|} ""; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = markup, - FixedCode = markup, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = markup, + FixedCode = markup, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/ForEachCast/ForEachCastTests.cs b/src/Analyzers/CSharp/Tests/ForEachCast/ForEachCastTests.cs index e12d40ba42f01..233931d0541d1 100644 --- a/src/Analyzers/CSharp/Tests/ForEachCast/ForEachCastTests.cs +++ b/src/Analyzers/CSharp/Tests/ForEachCast/ForEachCastTests.cs @@ -10,1309 +10,1308 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ForEachCast -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpForEachCastDiagnosticAnalyzer, - CSharpForEachCastCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ForEachCast; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpForEachCastDiagnosticAnalyzer, + CSharpForEachCastCodeFixProvider>; - public class ForEachCastTests +public class ForEachCastTests +{ + private static async Task TestWorkerAsync( + string testCode, string fixedCode, string optionValue, ReferenceAssemblies? referenceAssemblies) { - private static async Task TestWorkerAsync( - string testCode, string fixedCode, string optionValue, ReferenceAssemblies? referenceAssemblies) + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + EditorConfig = """ + [*] + dotnet_style_prefer_foreach_explicit_cast_in_source= + """ + optionValue, + ReferenceAssemblies = referenceAssemblies ?? ReferenceAssemblies.Default, + }.RunAsync(); + } + + private static Task TestAlwaysAsync(string markup, string alwaysMarkup, ReferenceAssemblies? referenceAssemblies = null) + => TestWorkerAsync(markup, alwaysMarkup, "always", referenceAssemblies); + + private static Task TestWhenStronglyTypedAsync(string markup, string nonLegacyMarkup, ReferenceAssemblies? referenceAssemblies = null) + => TestWorkerAsync(markup, nonLegacyMarkup, "when_strongly_typed", referenceAssemblies); + + [Fact] + public async Task NonGenericIComparableCollection() + { + var test = """ + namespace ConsoleApplication1 { - TestCode = testCode, - FixedCode = fixedCode, - EditorConfig = """ - [*] - dotnet_style_prefer_foreach_explicit_cast_in_source= - """ + optionValue, - ReferenceAssemblies = referenceAssemblies ?? ReferenceAssemblies.Default, - }.RunAsync(); - } - - private static Task TestAlwaysAsync(string markup, string alwaysMarkup, ReferenceAssemblies? referenceAssemblies = null) - => TestWorkerAsync(markup, alwaysMarkup, "always", referenceAssemblies); - - private static Task TestWhenStronglyTypedAsync(string markup, string nonLegacyMarkup, ReferenceAssemblies? referenceAssemblies = null) - => TestWorkerAsync(markup, nonLegacyMarkup, "when_strongly_typed", referenceAssemblies); - - [Fact] - public async Task NonGenericIComparableCollection() - { - var test = """ - namespace ConsoleApplication1 - { - class Program - { - void Main() + class Program + { + void Main() + { + [|foreach|] (string item in new A()) { - [|foreach|] (string item in new A()) - { - } } } - struct A + } + struct A + { + public Enumerator GetEnumerator() => new Enumerator(); + public struct Enumerator { - public Enumerator GetEnumerator() => new Enumerator(); - public struct Enumerator - { - public System.IComparable Current => 42; - public bool MoveNext() => true; - } + public System.IComparable Current => 42; + public bool MoveNext() => true; } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task GenericObjectCollection() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task GenericObjectCollection() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + [|foreach|] (string item in x) { - var x = new List(); - [|foreach|] (string item in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (string item in x.Cast()) { - var x = new List(); - foreach (string item in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task ObjectArray() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main(object[] x) + [Fact] + public async Task ObjectArray() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main(object[] x) + { + [|foreach|] (string item in x) { - [|foreach|] (string item in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main(object[] x) + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main(object[] x) + { + foreach (string item in x.Cast()) { - foreach (string item in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task IComparableArrayCollection() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main(IComparable[] x) + [Fact] + public async Task IComparableArrayCollection() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main(IComparable[] x) + { + [|foreach|] (string item in x) { - [|foreach|] (string item in x) - { - } } } } - """; - var fixedCode = """ - using System; - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main(IComparable[] x) + } + """; + var fixedCode = """ + using System; + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main(IComparable[] x) + { + foreach (string item in x.Cast()) { - foreach (string item in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task IEnumerableOfObjectCollection() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main(IEnumerable x) + [Fact] + public async Task IEnumerableOfObjectCollection() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main(IEnumerable x) + { + [|foreach|] (string item in x) { - [|foreach|] (string item in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main(IEnumerable x) + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main(IEnumerable x) + { + foreach (string item in x.Cast()) { - foreach (string item in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task IListOfObjectCollection() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main(IList x) + [Fact] + public async Task IListOfObjectCollection() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main(IList x) + { + [|foreach|] (string item in x) { - [|foreach|] (string item in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main(IList x) + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main(IList x) + { + foreach (string item in x.Cast()) { - foreach (string item in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task NonGenericObjectCollection_Always() - { - var test = """ - using System.Collections; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task NonGenericObjectCollection_Always() + { + var test = """ + using System.Collections; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new ArrayList(); + [|foreach|] (string item in x) { - var x = new ArrayList(); - [|foreach|] (string item in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + } + """; + var fixedCode = """ + using System.Collections; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new ArrayList(); + foreach (string item in x.Cast()) { - var x = new ArrayList(); - foreach (string item in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + } - [Fact] - public async Task NonGenericObjectCollection_NonLegacy() - { - var test = """ - using System.Collections; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task NonGenericObjectCollection_NonLegacy() + { + var test = """ + using System.Collections; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new ArrayList(); + foreach (string item in x) { - var x = new ArrayList(); - foreach (string item in x) - { - } } } } - """; + } + """; - await TestWhenStronglyTypedAsync(test, test); - } + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task SameType() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task SameType() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (string item in x) { - var x = new List(); - foreach (string item in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task CastBaseToChild() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task CastBaseToChild() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + [|foreach|] (B item in x) { - var x = new List(); - [|foreach|] (B item in x) - { - } } } - class A { } - class B : A { } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + class A { } + class B : A { } + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (B item in x.Cast()) { - var x = new List(); - foreach (B item in x.Cast()) - { - } } } - class A { } - class B : A { } } - """; + class A { } + class B : A { } + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task ImplicitConversion() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task ImplicitConversion() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (long item in x) { - var x = new List(); - foreach (long item in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task UserDefinedImplicitConversion() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task UserDefinedImplicitConversion() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (B item in x) { - var x = new List(); - foreach (B item in x) - { - } } } - class A { } - class B - { - public static implicit operator B(A a) => new B(); - } } - """; + class A { } + class B + { + public static implicit operator B(A a) => new B(); + } + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task ExplicitConversion() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task ExplicitConversion() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + [|foreach|] (int item in x) { - var x = new List(); - [|foreach|] (int item in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (int item in x.Select(v => (int)v)) { - var x = new List(); - foreach (int item in x.Select(v => (int)v)) - { - } } } } - """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + } + """; + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task UserDefinedExplicitConversion() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task UserDefinedExplicitConversion() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + [|foreach|] (B item in x) { - var x = new List(); - [|foreach|] (B item in x) - { - } } } - class A { } - class B - { - public static explicit operator B(A a) => new B(); - } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + class A { } + class B + { + public static explicit operator B(A a) => new B(); + } + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (B item in x.Select(v => (B)v)) { - var x = new List(); - foreach (B item in x.Select(v => (B)v)) - { - } } } - class A { } - class B - { - public static explicit operator B(A a) => new B(); - } } - """; + class A { } + class B + { + public static explicit operator B(A a) => new B(); + } + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task CastChildToBase() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task CastChildToBase() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (A item in x) { - var x = new List(); - foreach (A item in x) - { - } } } - class A { } - class B : A { } } - """; + class A { } + class B : A { } + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task InterfaceToClass() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task InterfaceToClass() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + [|foreach|] (string s in x) { - var x = new List(); - [|foreach|] (string s in x) - { - } } } } - """; - - var fixedCode = """ - using System; - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + } + """; + + var fixedCode = """ + using System; + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (string s in x.Cast()) { - var x = new List(); - foreach (string s in x.Cast()) - { - } } } } - """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + } + """; + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task ClassToImplementedInterfase() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task ClassToImplementedInterfase() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (IComparable s in x) { - var x = new List(); - foreach (IComparable s in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task GenericTypes_Unrelated() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task GenericTypes_Unrelated() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + {|CS0030:foreach|} (B s in x) { - var x = new List(); - {|CS0030:foreach|} (B s in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task GenericTypes_Valid_Relationship() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() where A : B + [Fact] + public async Task GenericTypes_Valid_Relationship() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() where A : B + { + var x = new List(); + foreach (B s in x) { - var x = new List(); - foreach (B s in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task GenericTypes_Invalid_Relationship() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() where B : A + [Fact] + public async Task GenericTypes_Invalid_Relationship() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() where B : A + { + var x = new List(); + [|foreach|] (B s in x) { - var x = new List(); - [|foreach|] (B s in x) - { - } } } } - """; + } + """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() where B : A + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() where B : A + { + var x = new List(); + foreach (B s in x.Select(v => (B)v)) { - var x = new List(); - foreach (B s in x.Select(v => (B)v)) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task GenericTypes_Invalid_Relationship_ClassConstraint() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() - where A : class - where B : class, A + [Fact] + public async Task GenericTypes_Invalid_Relationship_ClassConstraint() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + where A : class + where B : class, A + { + var x = new List(); + [|foreach|] (B s in x) { - var x = new List(); - [|foreach|] (B s in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() - where A : class - where B : class, A + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + where A : class + where B : class, A + { + var x = new List(); + foreach (B s in x.Cast()) { - var x = new List(); - foreach (B s in x.Cast()) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task CollectionFromMethodResult_Invalid() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task CollectionFromMethodResult_Invalid() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + [|foreach|] (string item in GenerateSequence()) + { + } + IEnumerable GenerateSequence() { - [|foreach|] (string item in GenerateSequence()) - { - } - IEnumerable GenerateSequence() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } } - """; - var fixedCode = """ - using System; - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + } + """; + var fixedCode = """ + using System; + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + foreach (string item in GenerateSequence().Cast()) + { + } + IEnumerable GenerateSequence() { - foreach (string item in GenerateSequence().Cast()) - { - } - IEnumerable GenerateSequence() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task CollectionFromMethodResult_Valid() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task CollectionFromMethodResult_Valid() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + foreach (IComparable item in GenerateSequence()) + { + } + IEnumerable GenerateSequence() { - foreach (IComparable item in GenerateSequence()) - { - } - IEnumerable GenerateSequence() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task DynamicSameType() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task DynamicSameType() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (dynamic s in x) { - var x = new List(); - foreach (dynamic s in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task DynamicToObject() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task DynamicToObject() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (object s in x) { - var x = new List(); - foreach (object s in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task DynamicToString() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task DynamicToString() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + [|foreach|] (string s in x) { - var x = new List(); - [|foreach|] (string s in x) - { - } } } } - """; - var fixedCode = """ - using System.Collections.Generic; - using System.Linq; - namespace ConsoleApplication1 - { - class Program - { - void Main() + } + """; + var fixedCode = """ + using System.Collections.Generic; + using System.Linq; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (string s in x.Select(v => (string)v)) { - var x = new List(); - foreach (string s in x.Select(v => (string)v)) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); + } - [Fact] - public async Task DynamicToVar() - { - var test = """ - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task DynamicToVar() + { + var test = """ + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List(); + foreach (var s in x) { - var x = new List(); - foreach (var s in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task TupleToVarTuple() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task TupleToVarTuple() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List<(int, IComparable)>(); + foreach (var (i, j) in x) { - var x = new List<(int, IComparable)>(); - foreach (var (i, j) in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task TupleToSameTuple() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task TupleToSameTuple() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List<(int, IComparable)>(); + foreach ((int i, IComparable j) in x) { - var x = new List<(int, IComparable)>(); - foreach ((int i, IComparable j) in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task TupleToChildTuple() - { - var test = """ - using System; - using System.Collections.Generic; - namespace ConsoleApplication1 - { - class Program - { - void Main() + [Fact] + public async Task TupleToChildTuple() + { + var test = """ + using System; + using System.Collections.Generic; + namespace ConsoleApplication1 + { + class Program + { + void Main() + { + var x = new List<(int, IComparable)>(); + foreach ((int i, {|CS0266:int j|}) in x) { - var x = new List<(int, IComparable)>(); - foreach ((int i, {|CS0266:int j|}) in x) - { - } } } } - """; + } + """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact] - public async Task TupleToChildTuple2() - { - var test = """ - using System; - using System.Linq; + [Fact] + public async Task TupleToChildTuple2() + { + var test = """ + using System; + using System.Linq; - public static class Program - { - public static void M((object, object)[] x) + public static class Program + { + public static void M((object, object)[] x) + { + [|foreach|] ((string, string) item in x) { - [|foreach|] ((string, string) item in x) - { - Console.WriteLine(item.Item1); - Console.WriteLine(item.Item2); - } + Console.WriteLine(item.Item1); + Console.WriteLine(item.Item2); } } - """; + } + """; - var code = """ - using System; - using System.Linq; + var code = """ + using System; + using System.Linq; - public static class Program - { - public static void M((object, object)[] x) + public static class Program + { + public static void M((object, object)[] x) + { + foreach ((string, string) item in x.Select(v => ((string, string))v)) { - foreach ((string, string) item in x.Select(v => ((string, string))v)) - { - Console.WriteLine(item.Item1); - Console.WriteLine(item.Item2); - } + Console.WriteLine(item.Item1); + Console.WriteLine(item.Item2); } } - """; + } + """; - await TestAlwaysAsync(test, code); - await TestWhenStronglyTypedAsync(test, code); - } + await TestAlwaysAsync(test, code); + await TestWhenStronglyTypedAsync(test, code); + } - [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] - public async Task TestRegex_GoodCast() - { - var test = """ - using System.Text.RegularExpressions; + [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] + public async Task TestRegex_GoodCast() + { + var test = """ + using System.Text.RegularExpressions; - public static class Program - { - public static void M(Regex regex, string text) + public static class Program + { + public static void M(Regex regex, string text) + { + foreach (Match m in regex.Matches(text)) { - foreach (Match m in regex.Matches(text)) - { - } } } - """; - await TestAlwaysAsync(test, test, ReferenceAssemblies.Net.Net80); - await TestWhenStronglyTypedAsync(test, test, ReferenceAssemblies.Net.Net80); - } + } + """; + await TestAlwaysAsync(test, test, ReferenceAssemblies.Net.Net80); + await TestWhenStronglyTypedAsync(test, test, ReferenceAssemblies.Net.Net80); + } - [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] - public async Task TestRegex_BadCast() - { - var test = """ - using System.Text.RegularExpressions; + [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] + public async Task TestRegex_BadCast() + { + var test = """ + using System.Text.RegularExpressions; - public static class Program - { - public static void M(Regex regex, string text) + public static class Program + { + public static void M(Regex regex, string text) + { + [|foreach|] (string m in regex.Matches(text)) { - [|foreach|] (string m in regex.Matches(text)) - { - } } } - """; - var code = """ - using System.Linq; - using System.Text.RegularExpressions; - - public static class Program - { - public static void M(Regex regex, string text) + } + """; + var code = """ + using System.Linq; + using System.Text.RegularExpressions; + + public static class Program + { + public static void M(Regex regex, string text) + { + foreach (string m in regex.Matches(text).Cast()) { - foreach (string m in regex.Matches(text).Cast()) - { - } } } - """; - await TestAlwaysAsync(test, code, ReferenceAssemblies.Net.Net80); - await TestWhenStronglyTypedAsync(test, code, ReferenceAssemblies.Net.Net80); - } + } + """; + await TestAlwaysAsync(test, code, ReferenceAssemblies.Net.Net80); + await TestWhenStronglyTypedAsync(test, code, ReferenceAssemblies.Net.Net80); + } - [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] - public async Task WeaklyTypedGetEnumeratorWithIEnumerableOfT() - { - var test = """ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Text.RegularExpressions; + [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] + public async Task WeaklyTypedGetEnumeratorWithIEnumerableOfT() + { + var test = """ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Text.RegularExpressions; - public class C : IEnumerable - { - public IEnumerator GetEnumerator() => new Enumerator(); // compiler picks this for the foreach loop. + public class C : IEnumerable + { + public IEnumerator GetEnumerator() => new Enumerator(); // compiler picks this for the foreach loop. - IEnumerator IEnumerable.GetEnumerator() => null; // compiler doesn't use this. + IEnumerator IEnumerable.GetEnumerator() => null; // compiler doesn't use this. - public static void M(C c) + public static void M(C c) + { + // The compiler adds a cast here from 'object' to 'Match', + // and it will fail at runtime because GetEnumerator().Current will return a string. + // This is due to badly implemented type 'C', and is rare enough. So, we don't report here + // to reduce false positives. + foreach (Match x in c) { - // The compiler adds a cast here from 'object' to 'Match', - // and it will fail at runtime because GetEnumerator().Current will return a string. - // This is due to badly implemented type 'C', and is rare enough. So, we don't report here - // to reduce false positives. - foreach (Match x in c) - { - } } + } - private class Enumerator : IEnumerator - { - public object Current => "String"; + private class Enumerator : IEnumerator + { + public object Current => "String"; - public bool MoveNext() - { - return true; - } + public bool MoveNext() + { + return true; + } - public void Reset() - { - } + public void Reset() + { } } - """; - await TestAlwaysAsync(test, test); - await TestWhenStronglyTypedAsync(test, test); - } + } + """; + await TestAlwaysAsync(test, test); + await TestWhenStronglyTypedAsync(test, test); + } - [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] - public async Task WeaklyTypedGetEnumeratorWithIEnumerableOfT_DifferentTypeUsedInForEach() - { - var code = """ - using System; - using System.Collections; - using System.Collections.Generic; + [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] + public async Task WeaklyTypedGetEnumeratorWithIEnumerableOfT_DifferentTypeUsedInForEach() + { + var code = """ + using System; + using System.Collections; + using System.Collections.Generic; - public class C : IEnumerable - { - public IEnumerator GetEnumerator() => new Enumerator(); // compiler picks this for the foreach loop. + public class C : IEnumerable + { + public IEnumerator GetEnumerator() => new Enumerator(); // compiler picks this for the foreach loop. - IEnumerator IEnumerable.GetEnumerator() => null; // compiler doesn't use this. + IEnumerator IEnumerable.GetEnumerator() => null; // compiler doesn't use this. - public static void M(C c) + public static void M(C c) + { + [|foreach|] (C x in c) { - [|foreach|] (C x in c) - { - } } + } - private class Enumerator : IEnumerator - { - public object Current => "String"; + private class Enumerator : IEnumerator + { + public object Current => "String"; - public bool MoveNext() - { - return true; - } + public bool MoveNext() + { + return true; + } - public void Reset() - { - } + public void Reset() + { } } - """; + } + """; - var fixedCode = """ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Linq; + var fixedCode = """ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; - public class C : IEnumerable - { - public IEnumerator GetEnumerator() => new Enumerator(); // compiler picks this for the foreach loop. + public class C : IEnumerable + { + public IEnumerator GetEnumerator() => new Enumerator(); // compiler picks this for the foreach loop. - IEnumerator IEnumerable.GetEnumerator() => null; // compiler doesn't use this. + IEnumerator IEnumerable.GetEnumerator() => null; // compiler doesn't use this. - public static void M(C c) + public static void M(C c) + { + foreach (C x in c.Cast()) { - foreach (C x in c.Cast()) - { - } } + } - private class Enumerator : IEnumerator - { - public object Current => "String"; + private class Enumerator : IEnumerator + { + public object Current => "String"; - public bool MoveNext() - { - return true; - } + public bool MoveNext() + { + return true; + } - public void Reset() - { - } + public void Reset() + { } } - """; - await TestAlwaysAsync(code, fixedCode); - await TestWhenStronglyTypedAsync(code, fixedCode); - } + } + """; + await TestAlwaysAsync(code, fixedCode); + await TestWhenStronglyTypedAsync(code, fixedCode); + } - [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] - public async Task WeaklyTypedGetEnumeratorWithMultipleIEnumerableOfT() - { - // NOTE: The analyzer only considers the first IEnumerable implementation. - // That is why the following tests produces a diagnostic for the implicit string cast, but not for the implicit int cast. - var test = """ - using System; - using System.Collections; - using System.Collections.Generic; - - public class C : IEnumerable, IEnumerable - { - public IEnumerator GetEnumerator() => null; + [Fact, WorkItem(63470, "https://github.com/dotnet/roslyn/issues/63470")] + public async Task WeaklyTypedGetEnumeratorWithMultipleIEnumerableOfT() + { + // NOTE: The analyzer only considers the first IEnumerable implementation. + // That is why the following tests produces a diagnostic for the implicit string cast, but not for the implicit int cast. + var test = """ + using System; + using System.Collections; + using System.Collections.Generic; + + public class C : IEnumerable, IEnumerable + { + public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; - public static void M(C c) + public static void M(C c) + { + foreach (int x in c) { - foreach (int x in c) - { - } + } - [|foreach|] (string x in c) - { - } + [|foreach|] (string x in c) + { } } - """; + } + """; - var fixedCode = """ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Linq; + var fixedCode = """ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; - public class C : IEnumerable, IEnumerable - { - public IEnumerator GetEnumerator() => null; + public class C : IEnumerable, IEnumerable + { + public IEnumerator GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; - IEnumerator IEnumerable.GetEnumerator() => null; + IEnumerator IEnumerable.GetEnumerator() => null; - public static void M(C c) + public static void M(C c) + { + foreach (int x in c) { - foreach (int x in c) - { - } + } - foreach (string x in c.Cast()) - { - } + foreach (string x in c.Cast()) + { } } - """; - await TestAlwaysAsync(test, fixedCode); - await TestWhenStronglyTypedAsync(test, fixedCode); - } + } + """; + await TestAlwaysAsync(test, fixedCode); + await TestWhenStronglyTypedAsync(test, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/Formatting/FormattingAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/Formatting/FormattingAnalyzerTests.cs index 07962bbcd8453..cbe2148fab052 100644 --- a/src/Analyzers/CSharp/Tests/Formatting/FormattingAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/Formatting/FormattingAnalyzerTests.cs @@ -9,31 +9,31 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting; + +using Verify = CSharpCodeFixVerifier; + +[Trait(Traits.Feature, Traits.Features.Formatting)] +public class FormattingAnalyzerTests { - using Verify = CSharpCodeFixVerifier; + [Fact] + public async Task TrailingWhitespace() + { + var testCode = + "class X[| |]" + Environment.NewLine + + "{" + Environment.NewLine + + "}" + Environment.NewLine; + var expected = + "class X" + Environment.NewLine + + "{" + Environment.NewLine + + "}" + Environment.NewLine; + await Verify.VerifyCodeFixAsync(testCode, expected); + } - [Trait(Traits.Feature, Traits.Features.Formatting)] - public class FormattingAnalyzerTests + [Fact] + public async Task TestMissingSpace() { - [Fact] - public async Task TrailingWhitespace() - { - var testCode = - "class X[| |]" + Environment.NewLine + - "{" + Environment.NewLine + - "}" + Environment.NewLine; - var expected = - "class X" + Environment.NewLine + - "{" + Environment.NewLine + - "}" + Environment.NewLine; - await Verify.VerifyCodeFixAsync(testCode, expected); - } - - [Fact] - public async Task TestMissingSpace() - { - var testCode = @" + var testCode = @" class TypeName { void Method() @@ -42,7 +42,7 @@ void Method() } } "; - var expected = @" + var expected = @" class TypeName { void Method() @@ -51,13 +51,13 @@ void Method() } } "; - await Verify.VerifyCodeFixAsync(testCode, expected); - } + await Verify.VerifyCodeFixAsync(testCode, expected); + } - [Fact] - public async Task TestAlreadyFormatted() - { - var testCode = @" + [Fact] + public async Task TestAlreadyFormatted() + { + var testCode = @" class MyClass { void MyMethod() @@ -66,13 +66,13 @@ void MyMethod() } "; - await Verify.VerifyAnalyzerAsync(testCode); - } + await Verify.VerifyAnalyzerAsync(testCode); + } - [Fact] - public async Task TestNeedsIndentation() - { - var testCode = @" + [Fact] + public async Task TestNeedsIndentation() + { + var testCode = @" class MyClass { $$void MyMethod() @@ -80,7 +80,7 @@ class MyClass $$} } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod() @@ -89,13 +89,13 @@ void MyMethod() } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestNeedsIndentationButSuppressed() - { - var testCode = @" + [Fact] + public async Task TestNeedsIndentationButSuppressed() + { + var testCode = @" class MyClass { $$void MyMethod1() @@ -113,7 +113,7 @@ void MyMethod3() $$} } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod1() @@ -132,13 +132,13 @@ void MyMethod3() } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestWhitespaceBetweenMethods1() - { - var testCode = @" + [Fact] + public async Task TestWhitespaceBetweenMethods1() + { + var testCode = @" class MyClass { void MyMethod1() @@ -150,7 +150,7 @@ void MyMethod2() } } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod1() @@ -163,13 +163,13 @@ void MyMethod2() } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestWhitespaceBetweenMethods2() - { - var testCode = @" + [Fact] + public async Task TestWhitespaceBetweenMethods2() + { + var testCode = @" class MyClass { void MyMethod1() @@ -181,7 +181,7 @@ void MyMethod2() } } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod1() @@ -194,14 +194,14 @@ void MyMethod2() } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestWhitespaceBetweenMethods3() - { - // This example has trailing whitespace on both lines preceding MyMethod2 - var testCode = @" + [Fact] + public async Task TestWhitespaceBetweenMethods3() + { + // This example has trailing whitespace on both lines preceding MyMethod2 + var testCode = @" class MyClass { void MyMethod1() @@ -213,7 +213,7 @@ void MyMethod1() } } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod1() @@ -226,13 +226,13 @@ void MyMethod2() } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestOverIndentation() - { - var testCode = @" + [Fact] + public async Task TestOverIndentation() + { + var testCode = @" class MyClass { [| |]void MyMethod() @@ -240,7 +240,7 @@ class MyClass [| |]} } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod() @@ -249,20 +249,20 @@ void MyMethod() } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestIncrementalFixesFullLine() - { - var testCode = @" + [Fact] + public async Task TestIncrementalFixesFullLine() + { + var testCode = @" class MyClass { int Property1$${$$get;$$set;$$} int Property2$${$$get;$$} } "; - var fixedCode = @" + var fixedCode = @" class MyClass { int Property1 { get; set; } @@ -270,57 +270,57 @@ class MyClass } "; - await new Verify.Test - { - TestCode = testCode, - FixedCode = fixedCode, + await new Verify.Test + { + TestCode = testCode, + FixedCode = fixedCode, - // Each application of a single code fix covers all diagnostics on the same line. In total, two lines - // require changes so the number of incremental iterations is exactly 2. - NumberOfIncrementalIterations = 2, - }.RunAsync(); - } + // Each application of a single code fix covers all diagnostics on the same line. In total, two lines + // require changes so the number of incremental iterations is exactly 2. + NumberOfIncrementalIterations = 2, + }.RunAsync(); + } - [Fact] - public async Task TestEditorConfigUsed() - { - var testCode = @" + [Fact] + public async Task TestEditorConfigUsed() + { + var testCode = @" class MyClass { void MyMethod()[| |]{ } } "; - var fixedCode = @" + var fixedCode = @" class MyClass { void MyMethod() { } } "; - var editorConfig = @" + var editorConfig = @" root = true [*.cs] csharp_new_line_before_open_brace = methods "; - await new Verify.Test + await new Verify.Test + { + TestState = { - TestState = + Sources = { testCode }, + AnalyzerConfigFiles = { - Sources = { testCode }, - AnalyzerConfigFiles = - { - ("/.editorconfig", editorConfig), - }, + ("/.editorconfig", editorConfig), }, - FixedState = { Sources = { fixedCode } }, - }.RunAsync(); - } + }, + FixedState = { Sources = { fixedCode } }, + }.RunAsync(); + } - [Fact] - public async Task TestRegion() - { - var testCode = @" + [Fact] + public async Task TestRegion() + { + var testCode = @" class MyClass { #if true @@ -340,13 +340,13 @@ public void M() #endif } "; - await Verify.VerifyCodeFixAsync(testCode, testCode); - } + await Verify.VerifyCodeFixAsync(testCode, testCode); + } - [Fact] - public async Task TestRegion2() - { - var testCode = @" + [Fact] + public async Task TestRegion2() + { + var testCode = @" class MyClass { #if true @@ -371,7 +371,7 @@ public void M() } "; - var fixedCode = @" + var fixedCode = @" class MyClass { #if true @@ -395,13 +395,13 @@ public void M() #endif } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestRegion3() - { - var testCode = @" + [Fact] + public async Task TestRegion3() + { + var testCode = @" class MyClass { #if true @@ -421,7 +421,7 @@ public void M() #endif } "; - var fixedCode = @" + var fixedCode = @" class MyClass { #if true @@ -441,13 +441,13 @@ public void M() #endif } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task TestRegion4() - { - var testCode = @" + [Fact] + public async Task TestRegion4() + { + var testCode = @" class MyClass { #if true @@ -464,7 +464,7 @@ public void M() { } #endif } "; - var fixedCode = @" + var fixedCode = @" class MyClass { #if true @@ -481,7 +481,6 @@ public void M() { } #endif } "; - await Verify.VerifyCodeFixAsync(testCode, fixedCode); - } + await Verify.VerifyCodeFixAsync(testCode, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/HideBase/HideBaseTests.cs b/src/Analyzers/CSharp/Tests/HideBase/HideBaseTests.cs index 9e5f5de7dd6bf..63ad4114aab34 100644 --- a/src/Analyzers/CSharp/Tests/HideBase/HideBaseTests.cs +++ b/src/Analyzers/CSharp/Tests/HideBase/HideBaseTests.cs @@ -11,203 +11,202 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.HideBase +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.HideBase; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddNew)] +public class HideBaseTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddNew)] - public class HideBaseTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public HideBaseTests(ITestOutputHelper logger) + : base(logger) { - public HideBaseTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new HideBaseCodeFixProvider()); - - [Fact] - public async Task TestAddNewToProperty() - { - await TestInRegularAndScriptAsync( - """ - class Application - { - public static Application Current { get; } - } - - class App : Application - { - [|public static App Current|] { get; set; } - } - """, - """ - class Application - { - public static Application Current { get; } - } - - class App : Application - { - public static new App Current { get; set; } - } - """); - } - - [Fact] - public async Task TestAddNewToMethod() - { - await TestInRegularAndScriptAsync( - """ - class Application - { - public static void Method() - { - } - } - - class App : Application - { - [|public static void Method() - { - }|] - } - """, - """ - class Application - { - public static void Method() - { - } - } - - class App : Application - { - public static new void Method() - { - } - } - """); - } - - [Fact] - public async Task TestAddNewToField() - { - await TestInRegularAndScriptAsync( - """ - class Application - { - public string Test; - } - - class App : Application - { - [|public int Test;|] - } - """, - """ - class Application - { - public string Test; - } + } - class App : Application - { - public new int Test; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18391")] - public async Task TestAddNewToConstant() - { - await TestInRegularAndScriptAsync( - """ - class Application - { - public const int Test = 1; - } + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new HideBaseCodeFixProvider()); - class App : Application - { - [|public const int Test = Application.Test + 1;|] - } - """, - """ - class Application - { - public const int Test = 1; - } + [Fact] + public async Task TestAddNewToProperty() + { + await TestInRegularAndScriptAsync( + """ + class Application + { + public static Application Current { get; } + } + + class App : Application + { + [|public static App Current|] { get; set; } + } + """, + """ + class Application + { + public static Application Current { get; } + } + + class App : Application + { + public static new App Current { get; set; } + } + """); + } - class App : Application - { - public new const int Test = Application.Test + 1; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14455")] - public async Task TestAddNewToConstantInternalFields() - { - await TestInRegularAndScriptAsync( - """ - class A { internal const int i = 0; } - class B : A { [|internal const int i = 1;|] } - """, - """ - class A { internal const int i = 0; } - class B : A { internal new const int i = 1; } - """); - } - - [Fact] - public async Task TestAddNewToDisorderedModifiers() - => await TestInRegularAndScript1Async( - """ - class Application + [Fact] + public async Task TestAddNewToMethod() + { + await TestInRegularAndScriptAsync( + """ + class Application + { + public static void Method() { - public static string Test; } + } - class App : Application + class App : Application + { + [|public static void Method() { - [|static public int Test;|] - } - """, - """ - class Application + }|] + } + """, + """ + class Application + { + public static void Method() { - public static string Test; } + } - class App : Application + class App : Application + { + public static new void Method() { - static public new int Test; } - """); + } + """); + } - [Fact] - public async Task TestAddNewToOrderedModifiersWithTrivia() - => await TestInRegularAndScript1Async( - """ - class Application - { - public string Test; - } + [Fact] + public async Task TestAddNewToField() + { + await TestInRegularAndScriptAsync( + """ + class Application + { + public string Test; + } + + class App : Application + { + [|public int Test;|] + } + """, + """ + class Application + { + public string Test; + } + + class App : Application + { + public new int Test; + } + """); + } - class App : Application - { - [|/* start */ public /* middle */ readonly /* end */ int Test;|] - } - """, - """ - class Application - { - public string Test; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18391")] + public async Task TestAddNewToConstant() + { + await TestInRegularAndScriptAsync( + """ + class Application + { + public const int Test = 1; + } + + class App : Application + { + [|public const int Test = Application.Test + 1;|] + } + """, + """ + class Application + { + public const int Test = 1; + } + + class App : Application + { + public new const int Test = Application.Test + 1; + } + """); + } - class App : Application - { - /* start */ public /* middle */ new readonly /* end */ int Test; - } - """); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14455")] + public async Task TestAddNewToConstantInternalFields() + { + await TestInRegularAndScriptAsync( + """ + class A { internal const int i = 0; } + class B : A { [|internal const int i = 1;|] } + """, + """ + class A { internal const int i = 0; } + class B : A { internal new const int i = 1; } + """); } + + [Fact] + public async Task TestAddNewToDisorderedModifiers() + => await TestInRegularAndScript1Async( + """ + class Application + { + public static string Test; + } + + class App : Application + { + [|static public int Test;|] + } + """, + """ + class Application + { + public static string Test; + } + + class App : Application + { + static public new int Test; + } + """); + + [Fact] + public async Task TestAddNewToOrderedModifiersWithTrivia() + => await TestInRegularAndScript1Async( + """ + class Application + { + public string Test; + } + + class App : Application + { + [|/* start */ public /* middle */ readonly /* end */ int Test;|] + } + """, + """ + class Application + { + public string Test; + } + + class App : Application + { + /* start */ public /* middle */ new readonly /* end */ int Test; + } + """); } diff --git a/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests.cs b/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests.cs index cc87cca3f27d4..97f431170bbe6 100644 --- a/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests.cs +++ b/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests.cs @@ -15,2502 +15,2501 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InlineDeclaration +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InlineDeclaration; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] +public partial class CSharpInlineDeclarationTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] - public partial class CSharpInlineDeclarationTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public CSharpInlineDeclarationTests(ITestOutputHelper logger) + : base(logger) { - public CSharpInlineDeclarationTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpInlineDeclarationDiagnosticAnalyzer(), new CSharpInlineDeclarationCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpInlineDeclarationDiagnosticAnalyzer(), new CSharpInlineDeclarationCodeFixProvider()); - [Fact] - public async Task InlineVariable1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineVariable1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (int.TryParse(v, out i)) { - [|int|] i; - if (int.TryParse(v, out i)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineInNestedCall() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineInNestedCall() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (Goo(int.TryParse(v, out i))) { - [|int|] i; - if (Goo(int.TryParse(v, out i))) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (Goo(int.TryParse(v, out int i))) { - if (Goo(int.TryParse(v, out int i))) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineVariableWithConstructor1() - { - await TestInRegularAndScript1Async( - """ - class C1 - { - public C1(int v, out int i) {} + [Fact] + public async Task InlineVariableWithConstructor1() + { + await TestInRegularAndScript1Async( + """ + class C1 + { + public C1(int v, out int i) {} - void M(int v) + void M(int v) + { + [|int|] i; + if (new C1(v, out i)) { - [|int|] i; - if (new C1(v, out i)) - { - } } } - """, - """ - class C1 - { - public C1(int v, out int i) {} + } + """, + """ + class C1 + { + public C1(int v, out int i) {} - void M(int v) + void M(int v) + { + if (new C1(v, out int i)) { - if (new C1(v, out int i)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineVariableMissingWithIndexer1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task InlineVariableMissingWithIndexer1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|int|] i; + if (this[out i]) { - [|int|] i; - if (this[out i]) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineVariableIntoFirstOut1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineVariableIntoFirstOut1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (int.TryParse(v, out i, out i)) { - [|int|] i; - if (int.TryParse(v, out i, out i)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (int.TryParse(v, out int i, out i)) { - if (int.TryParse(v, out int i, out i)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineVariableIntoFirstOut2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineVariableIntoFirstOut2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (int.TryParse(v, out i)) { - [|int|] i; - if (int.TryParse(v, out i)) - { - } + } - if (int.TryParse(v, out i)) - { - } + if (int.TryParse(v, out i)) + { } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } + } - if (int.TryParse(v, out i)) - { - } + if (int.TryParse(v, out i)) + { } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInCSharp6() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMissingInCSharp6() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + [|int|] i; + if (int.TryParse(v, out i)) { - [|int|] i; - if (int.TryParse(v, out i)) - { - } } } - """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task InlineVariablePreferVar1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineVariablePreferVar1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string v) { - void M(string v) + [|int|] i; + if (int.TryParse(v, out i)) { - [|int|] i; - if (int.TryParse(v, out i)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M(string v) { - void M(string v) + if (int.TryParse(v, out var i)) { - if (int.TryParse(v, out var i)) - { - } } } - """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); + } - [Fact] - public async Task InlineVariablePreferVarExceptForPredefinedTypes1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineVariablePreferVarExceptForPredefinedTypes1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string v) { - void M(string v) + [|int|] i; + if (int.TryParse(v, out i)) { - [|int|] i; - if (int.TryParse(v, out i)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M(string v) { - void M(string v) + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } } - """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeButKeepIntrinsics())); - } + } + """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeButKeepIntrinsics())); + } - [Fact] - public async Task TestAvailableWhenWrittenAfter1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestAvailableWhenWrittenAfter1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (int.TryParse(v, out i)) { - [|int|] i; - if (int.TryParse(v, out i)) - { - } + } + + i = 0; + } + } + """, + """ + class C + { + void M() + { + if (int.TryParse(v, out int i)) + { + } + + i = 0; + } + } + """); + } - i = 0; + [Fact] + public async Task TestMissingWhenWrittenBetween1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + [|int|] i; + i = 0; + if (int.TryParse(v, out i)) + { } } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestMissingWhenReadBetween1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|int|] i = 0; + M1(i); + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out int i)) - { - } + } + } + + void M1(int i) + { + } + } + """); + } - i = 0; + [Fact] + public async Task TestMissingWithComplexInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + [|int|] i = M1(); + if (int.TryParse(v, out i)) + { } } - """); - } - [Fact] - public async Task TestMissingWhenWrittenBetween1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + int M1() + { + } + } + """); + } + + [Fact] + public async Task TestAvailableInOuterScopeIfNotWrittenOutside() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|int|] i = 0; { - [|int|] i; - i = 0; if (int.TryParse(v, out i)) { } + + i = 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingWhenReadBetween1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingIfWrittenAfterInOuterScope() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|int|] i = 0; { - [|int|] i = 0; - M1(i); if (int.TryParse(v, out i)) { } } - void M1(int i) - { - } + i = 1; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingWithComplexInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingIfWrittenBetweenInOuterScope() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|int|] i = 0; { - [|int|] i = M1(); + i = 1; if (int.TryParse(v, out i)) { } } + } + } + """); + } - int M1() + [Fact] + public async Task TestMissingInNonOut() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + [|int|] i; + if (int.TryParse(v, i)) { } } - """); - } + } + """); + } - [Fact] - public async Task TestAvailableInOuterScopeIfNotWrittenOutside() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingInField() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + [|int|] i; + + void M() { - void M() + if (int.TryParse(v, out this.i)) { - [|int|] i = 0; - { - if (int.TryParse(v, out i)) - { - } - - i = 1; - } } } - """); - } + } + """); + } + + [Fact] + public async Task TestMissingInField2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + [|int|] i; - [Fact] - public async Task TestMissingIfWrittenAfterInOuterScope() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M() { - void M() + if (int.TryParse(v, out i)) { - [|int|] i = 0; - { - if (int.TryParse(v, out i)) - { - } - } - - i = 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingIfWrittenBetweenInOuterScope() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingInNonLocalStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + foreach ([|int|] i in e) { - [|int|] i = 0; + if (int.TryParse(v, out i)) { - i = 1; - if (int.TryParse(v, out i)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInNonOut() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingInEmbeddedStatementWithWriteAfterwards() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - [|int|] i; - if (int.TryParse(v, i)) + [|int|] i; + while (true) + if (int.TryParse(v, out i)) { } - } + + i = 1; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInField() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestInEmbeddedStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { [|int|] i; - - void M() - { - if (int.TryParse(v, out this.i)) + while (true) + if (int.TryParse(v, out i)) { + i = 1; + } + } + } + """, + """ + class C + { + void M() + { + while (true) + if (int.TryParse(v, out int i)) + { + i = 1; } - } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInField2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestAvailableInNestedBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { [|int|] i; - - void M() + while (true) { if (int.TryParse(v, out i)) { } } } - """); - } - - [Fact] - public async Task TestMissingInNonLocalStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + void M() { - void M() + while (true) { - foreach ([|int|] i in e) + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out i)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInEmbeddedStatementWithWriteAfterwards() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestOverloadResolutionDoNotUseVar1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (M2(out i)) { - [|int|] i; - while (true) - if (int.TryParse(v, out i)) - { - } - - i = 1; } } - """); - } - [Fact] - public async Task TestInEmbeddedStatement() - { - await TestInRegularAndScript1Async( - """ - class C + void M2(out int i) + { + } + + void M2(out string s) { - void M() - { - [|int|] i; - while (true) - if (int.TryParse(v, out i)) - { - i = 1; - } - } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (M2(out int i)) { - while (true) - if (int.TryParse(v, out int i)) - { - i = 1; - } } } - """); - } - [Fact] - public async Task TestAvailableInNestedBlock() - { - await TestInRegularAndScript1Async( - """ - class C + void M2(out int i) { - void M() - { - [|int|] i; - while (true) - { - if (int.TryParse(v, out i)) - { - } - } - } } - """, - """ - class C + + void M2(out string s) { - void M() - { - while (true) - { - if (int.TryParse(v, out int i)) - { - } - } - } } - """); - } + } + """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); + } - [Fact] - public async Task TestOverloadResolutionDoNotUseVar1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOverloadResolutionDoNotUseVar2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] i = 0; + if (M2(out i)) { - [|int|] i; - if (M2(out i)) - { - } } + } - void M2(out int i) - { - } + void M2(out int i) + { + } - void M2(out string s) - { - } + void M2(out string s) + { } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (M2(out int i)) { - if (M2(out int i)) - { - } } + } - void M2(out int i) - { - } + void M2(out int i) + { + } - void M2(out string s) - { - } + void M2(out string s) + { } - """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); + } - [Fact] - public async Task TestOverloadResolutionDoNotUseVar2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestGenericInferenceDoNotUseVar3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; + if (M2(out i)) { - [|var|] i = 0; - if (M2(out i)) - { - } } + } - void M2(out int i) + void M2(out T i) + { + } + } + """, + """ + class C + { + void M() + { + if (M2(out int i)) { } + } - void M2(out string s) - { - } + void M2(out T i) + { } - """, - """ - class C + } + """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); + } + + [Fact] + public async Task TestComments1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + // prefix comment + [|int|] i; { - if (M2(out int i)) + if (int.TryParse(v, out i)) { } } - - void M2(out int i) - { - } - - void M2(out string s) - { - } } - """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); - } - - [Fact] - public async Task TestGenericInferenceDoNotUseVar3() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix comment { - [|int|] i; - if (M2(out i)) + if (int.TryParse(v, out int i)) { } } - - void M2(out T i) - { - } - } - """, - """ - class C - { - void M() - { - if (M2(out int i)) - { - } - } - - void M2(out T i) - { - } - } - """, new TestParameters(options: new UseImplicitTypeTests().ImplicitTypeEverywhere())); - } - - [Fact] - public async Task TestComments1() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M() - { - // prefix comment - [|int|] i; - { - if (int.TryParse(v, out i)) - { - } - } - } - } - """, - """ - class C - { - void M() - { - // prefix comment - { - if (int.TryParse(v, out int i)) - { - } - } - } } - """); - } + } + """); + } - [Fact] - public async Task TestComments2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|int|] i; // suffix comment { - [|int|] i; // suffix comment + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // suffix comment { - // suffix comment + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + // prefix comment + [|int|] i; // suffix comment { - // prefix comment - [|int|] i; // suffix comment + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix comment + // suffix comment { - // prefix comment - // suffix comment + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments4() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments4() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int [|i|] /*suffix*/, j; { - int [|i|] /*suffix*/, j; + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int j; { - int j; + if (int.TryParse(v, out int i /*suffix*/)) { - if (int.TryParse(v, out int i /*suffix*/)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments5() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments5() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int /*prefix*/ [|i|], j; { - int /*prefix*/ [|i|], j; + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int j; { - int j; + if (int.TryParse(v, out int /*prefix*/ i)) { - if (int.TryParse(v, out int /*prefix*/ i)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments6() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments6() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int /*prefix*/ [|i|] /*suffix*/, j; { - int /*prefix*/ [|i|] /*suffix*/, j; + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int j; { - int j; + if (int.TryParse(v, out int /*prefix*/ i /*suffix*/)) { - if (int.TryParse(v, out int /*prefix*/ i /*suffix*/)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments7() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments7() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int j, /*prefix*/ [|i|] /*suffix*/; { - int j, /*prefix*/ [|i|] /*suffix*/; + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int j; { - int j; + if (int.TryParse(v, out int /*prefix*/ i /*suffix*/)) { - if (int.TryParse(v, out int /*prefix*/ i /*suffix*/)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments8() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments8() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + // prefix + int j, [|i|]; // suffix { - // prefix - int j, [|i|]; // suffix + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix + int j; // suffix { - // prefix - int j; // suffix + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments9() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments9() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int /*int comment*/ + /*prefix*/ [|i|] /*suffix*/, + j; { - int /*int comment*/ - /*prefix*/ [|i|] /*suffix*/, - j; + if (int.TryParse(v, out i)) { - if (int.TryParse(v, out i)) - { - } } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int /*int comment*/ + j; { - int /*int comment*/ - j; + if (int.TryParse(v, out int /*prefix*/ i /*suffix*/)) { - if (int.TryParse(v, out int /*prefix*/ i /*suffix*/)) - { - } } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15994")] - public async Task TestCommentsTrivia1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15994")] + public async Task TestCommentsTrivia1() + { + await TestInRegularAndScript1Async( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine("Goo"); + Console.WriteLine("Goo"); - int [|result|]; - if (int.TryParse("12", out result)) - { + int [|result|]; + if (int.TryParse("12", out result)) + { - } } } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine("Goo"); + Console.WriteLine("Goo"); - if (int.TryParse("12", out int result)) - { + if (int.TryParse("12", out int result)) + { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15994")] - public async Task TestCommentsTrivia2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15994")] + public async Task TestCommentsTrivia2() + { + await TestInRegularAndScript1Async( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine("Goo"); + Console.WriteLine("Goo"); - // Goo + // Goo - int [|result|]; - if (int.TryParse("12", out result)) - { + int [|result|]; + if (int.TryParse("12", out result)) + { - } } } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine("Goo"); + Console.WriteLine("Goo"); - // Goo + // Goo - if (int.TryParse("12", out int result)) - { + if (int.TryParse("12", out int result)) + { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15336")] - public async Task TestNotMissingIfCapturedInLambdaAndNotUsedAfterwards() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15336")] + public async Task TestNotMissingIfCapturedInLambdaAndNotUsedAfterwards() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - string [|s|]; - Bar(() => Baz(out s)); - } + string [|s|]; + Bar(() => Baz(out s)); + } - void Baz(out string s) { } + void Baz(out string s) { } - void Bar(Action a) { } - } - """, - """ - using System; + void Bar(Action a) { } + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - Bar(() => Baz(out string s)); - } + Bar(() => Baz(out string s)); + } - void Baz(out string s) { } + void Baz(out string s) { } - void Bar(Action a) { } - } - """); - } + void Bar(Action a) { } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15336")] - public async Task TestMissingIfCapturedInLambdaAndUsedAfterwards() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15336")] + public async Task TestMissingIfCapturedInLambdaAndUsedAfterwards() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - string [|s|]; - Bar(() => Baz(out s)); - Console.WriteLine(s); - } + string [|s|]; + Bar(() => Baz(out s)); + Console.WriteLine(s); + } - void Baz(out string s) { } + void Baz(out string s) { } - void Bar(Action a) { } - } - """); - } + void Bar(Action a) { } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15408")] - public async Task TestDataFlow1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15408")] + public async Task TestDataFlow1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo(string x) { - void Goo(string x) + object [|s|] = null; + if (x != null || TryBaz(out s)) { - object [|s|] = null; - if (x != null || TryBaz(out s)) - { - Console.WriteLine(s); - } + Console.WriteLine(s); } + } - private bool TryBaz(out object s) - { - throw new NotImplementedException(); - } + private bool TryBaz(out object s) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15408")] - public async Task TestDataFlow2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15408")] + public async Task TestDataFlow2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Goo(string x) { - void Goo(string x) + object [|s|] = null; + if (x != null && TryBaz(out s)) { - object [|s|] = null; - if (x != null && TryBaz(out s)) - { - Console.WriteLine(s); - } + Console.WriteLine(s); } + } - private bool TryBaz(out object s) - { - throw new NotImplementedException(); - } + private bool TryBaz(out object s) + { + throw new NotImplementedException(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo(string x) { - void Goo(string x) + if (x != null && TryBaz(out object s)) { - if (x != null && TryBaz(out object s)) - { - Console.WriteLine(s); - } + Console.WriteLine(s); } + } - private bool TryBaz(out object s) - { - throw new NotImplementedException(); - } + private bool TryBaz(out object s) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16028")] - public async Task TestExpressionTree1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16028")] + public async Task TestExpressionTree1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - int [|result|]; - Method(() => GetValue(out result)); - } + int [|result|]; + Method(() => GetValue(out result)); + } - public static void GetValue(out int result) - { - result = 0; - } + public static void GetValue(out int result) + { + result = 0; + } - public static void Method(Expression expression) - { + public static void Method(Expression expression) + { - } } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16198")] + public async Task TestIndentation1() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + private int Bar() + { + IProjectRuleSnapshot [|unresolvedReferenceSnapshot|] = null; + var itemType = GetUnresolvedReferenceItemType(originalItemSpec, + updatedUnresolvedSnapshots, + catalogs, + out unresolvedReferenceSnapshot); + } + } + """, + """ + using System; + + class C + { + private int Bar() + { + var itemType = GetUnresolvedReferenceItemType(originalItemSpec, + updatedUnresolvedSnapshots, + catalogs, + out IProjectRuleSnapshot unresolvedReferenceSnapshot); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16198")] - public async Task TestIndentation1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestNotInLoops1() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static void Main(string[] args) { - private int Bar() + string [|token|]; + do { - IProjectRuleSnapshot [|unresolvedReferenceSnapshot|] = null; - var itemType = GetUnresolvedReferenceItemType(originalItemSpec, - updatedUnresolvedSnapshots, - catalogs, - out unresolvedReferenceSnapshot); } + while (!TryExtractTokenFromEmail(out token)); + + Console.WriteLine(token == "Test"); } - """, - """ - using System; - class C + private static bool TryExtractTokenFromEmail(out string token) { - private int Bar() - { - var itemType = GetUnresolvedReferenceItemType(originalItemSpec, - updatedUnresolvedSnapshots, - catalogs, - out IProjectRuleSnapshot unresolvedReferenceSnapshot); - } + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestNotInLoops1() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestNotInLoops2() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + while (!TryExtractTokenFromEmail(out token)) { - string [|token|]; - do - { - } - while (!TryExtractTokenFromEmail(out token)); - - Console.WriteLine(token == "Test"); } - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + Console.WriteLine(token == "Test"); } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestNotInLoops2() - { - await TestMissingAsync( - """ - using System; - class C + private static bool TryExtractTokenFromEmail(out string token) { - static void Main(string[] args) - { - string [|token|]; - while (!TryExtractTokenFromEmail(out token)) - { - } - - Console.WriteLine(token == "Test"); - } - - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestNotInLoops3() - { - await TestMissingAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestNotInLoops3() + { + await TestMissingAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + foreach (var v in TryExtractTokenFromEmail(out token)) { - string [|token|]; - foreach (var v in TryExtractTokenFromEmail(out token)) - { - } - - Console.WriteLine(token == "Test"); } - private static IEnumerable TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + Console.WriteLine(token == "Test"); } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestNotInLoops4() - { - await TestMissingAsync( - """ - using System; - using System.Collections.Generic; - class C + private static IEnumerable TryExtractTokenFromEmail(out string token) { - static void Main(string[] args) - { - string [|token|]; - for ( ; TryExtractTokenFromEmail(out token); ) - { - } + throw new NotImplementedException(); + } + } + """); + } - Console.WriteLine(token == "Test"); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestNotInLoops4() + { + await TestMissingAsync( + """ + using System; + using System.Collections.Generic; - private static bool TryExtractTokenFromEmail(out string token) + class C + { + static void Main(string[] args) + { + string [|token|]; + for ( ; TryExtractTokenFromEmail(out token); ) { - throw new NotImplementedException(); } - } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestNotInUsing() - { - await TestMissingAsync( - """ - using System; + Console.WriteLine(token == "Test"); + } - class C + private static bool TryExtractTokenFromEmail(out string token) { - static void Main(string[] args) - { - string [|token|]; - using (GetDisposableAndValue(out token)) - { - } + throw new NotImplementedException(); + } + } + """); + } - Console.WriteLine(token); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestNotInUsing() + { + await TestMissingAsync( + """ + using System; - private static IDisposable GetDisposableAndValue(out string token) + class C + { + static void Main(string[] args) + { + string [|token|]; + using (GetDisposableAndValue(out token)) { - throw new NotImplementedException(); } + + Console.WriteLine(token); + } + + private static IDisposable GetDisposableAndValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestNotInExceptionFilter() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestNotInExceptionFilter() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + try { - string [|token|]; - try - { - } - catch when (GetValue(out token)) - { - } - - Console.WriteLine(token); } - - private static bool GetValue(out string token) + catch when (GetValue(out token)) { - throw new NotImplementedException(); } + + Console.WriteLine(token); + } + + private static bool GetValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestNotInShortCircuitExpression1() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestNotInShortCircuitExpression1() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - string [|token|] = null; - bool condition = false && GetValue(out token); - Console.WriteLine(token); - } + string [|token|] = null; + bool condition = false && GetValue(out token); + Console.WriteLine(token); + } - private static bool GetValue(out string token) - { - throw new NotImplementedException(); - } + private static bool GetValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestNotInShortCircuitExpression2() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestNotInShortCircuitExpression2() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - string [|token|]; - bool condition = false && GetValue(out token); - Console.WriteLine(token); - } + string [|token|]; + bool condition = false && GetValue(out token); + Console.WriteLine(token); + } - private static bool GetValue(out string token) - { - throw new NotImplementedException(); - } + private static bool GetValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestNotInFixed() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestNotInFixed() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static unsafe void Main(string[] args) { - static unsafe void Main(string[] args) + string [|token|]; + fixed (int* p = GetValue(out token)) { - string [|token|]; - fixed (int* p = GetValue(out token)) - { - } - - Console.WriteLine(token); } - private static int[] GetValue(out string token) - { - throw new NotImplementedException(); - } + Console.WriteLine(token); + } + + private static int[] GetValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestInLoops1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestInLoops1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + do { - string [|token|]; - do - { - } - while (!TryExtractTokenFromEmail(out token)); } + while (!TryExtractTokenFromEmail(out token)); + } - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + private static bool TryExtractTokenFromEmail(out string token) + { + throw new NotImplementedException(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + do { - do - { - } - while (!TryExtractTokenFromEmail(out string token)); } + while (!TryExtractTokenFromEmail(out string token)); + } - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + private static bool TryExtractTokenFromEmail(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestInLoops2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestInLoops2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + while (!TryExtractTokenFromEmail(out token)) { - string [|token|]; - while (!TryExtractTokenFromEmail(out token)) - { - } } + } - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + private static bool TryExtractTokenFromEmail(out string token) + { + throw new NotImplementedException(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + while (!TryExtractTokenFromEmail(out string token)) { - while (!TryExtractTokenFromEmail(out string token)) - { - } } + } - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + private static bool TryExtractTokenFromEmail(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestInLoops3() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestInLoops3() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + foreach (var v in TryExtractTokenFromEmail(out token)) { - string [|token|]; - foreach (var v in TryExtractTokenFromEmail(out token)) - { - } - } - - private static IEnumerable TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); } } - """, - """ - using System; - using System.Collections.Generic; - class C + private static IEnumerable TryExtractTokenFromEmail(out string token) { - static void Main(string[] args) - { - foreach (var v in TryExtractTokenFromEmail(out string token)) - { - } - } - - private static IEnumerable TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] - public async Task TestInLoops4() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - string [|token|]; - for ( ; TryExtractTokenFromEmail(out token); ) - { - } - } - - private static bool TryExtractTokenFromEmail(out string token) + foreach (var v in TryExtractTokenFromEmail(out string token)) { - throw new NotImplementedException(); } } - """, - """ - using System; - using System.Collections.Generic; - class C + private static IEnumerable TryExtractTokenFromEmail(out string token) { - static void Main(string[] args) - { - for (; TryExtractTokenFromEmail(out string token);) - { - } - } - - private static bool TryExtractTokenFromEmail(out string token) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestInUsing() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17624")] + public async Task TestInLoops4() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + for ( ; TryExtractTokenFromEmail(out token); ) { - string [|token|]; - using (GetDisposableAndValue(out token)) - { - } } + } - private static IDisposable GetDisposableAndValue(out string token) - { - throw new NotImplementedException(); - } + private static bool TryExtractTokenFromEmail(out string token) + { + throw new NotImplementedException(); } - """, - """ - using System; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + for (; TryExtractTokenFromEmail(out string token);) { - using (GetDisposableAndValue(out string token)) - { - } } + } - private static IDisposable GetDisposableAndValue(out string token) - { - throw new NotImplementedException(); - } + private static bool TryExtractTokenFromEmail(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestInExceptionFilter() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestInUsing() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + using (GetDisposableAndValue(out token)) { - string [|token|]; - try - { - } - catch when (GetValue(out token)) - { - } } + } - private static bool GetValue(out string token) - { - throw new NotImplementedException(); - } + private static IDisposable GetDisposableAndValue(out string token) + { + throw new NotImplementedException(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + using (GetDisposableAndValue(out string token)) { - try - { - } - catch when (GetValue(out string token)) - { - } } + } - private static bool GetValue(out string token) - { - throw new NotImplementedException(); - } + private static IDisposable GetDisposableAndValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestInShortCircuitExpression1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestInExceptionFilter() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + string [|token|]; + try { - string [|token|] = null; - bool condition = false && GetValue(out token); } - - private static bool GetValue(out string token) + catch when (GetValue(out token)) { - throw new NotImplementedException(); } } - """, - """ - using System; - class C + private static bool GetValue(out string token) { - static void Main(string[] args) - { - bool condition = false && GetValue(out string token); - } - - private static bool GetValue(out string token) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """); - } + } + """, + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestInShortCircuitExpression2() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + try { - string [|token|]; - bool condition = false && GetValue(out token); } - - private static bool GetValue(out string token) + catch when (GetValue(out string token)) { - throw new NotImplementedException(); } } - """, - """ - using System; - class C + private static bool GetValue(out string token) { - static void Main(string[] args) - { - bool condition = false && GetValue(out string token); - } - - private static bool GetValue(out string token) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] - public async Task TestInFixed() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestInShortCircuitExpression1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - string [|token|]; - fixed (int* p = GetValue(out token)) - { - } - } + string [|token|] = null; + bool condition = false && GetValue(out token); + } - private static int[] GetValue(out string token) - { - throw new NotImplementedException(); - } + private static bool GetValue(out string token) + { + throw new NotImplementedException(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - fixed (int* p = GetValue(out string token)) - { - } - } + bool condition = false && GetValue(out string token); + } - private static int[] GetValue(out string token) - { - throw new NotImplementedException(); - } + private static bool GetValue(out string token) + { + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17743")] - public async Task TestInLocalFunction1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestInShortCircuitExpression2() + { + await TestInRegularAndScript1Async( + """ + using System; - class Demo + class C + { + static void Main(string[] args) { - static void Main() - { - F(); - void F() - { - Action f = () => - { - Dictionary dict = null; - int [|x|] = 0; - dict?.TryGetValue(0, out x); - Console.WriteLine(x); - }; - } - } + string [|token|]; + bool condition = false && GetValue(out token); } - """); - } - [Fact] - public async Task TestInLocalFunction2() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Collections.Generic; + private static bool GetValue(out string token) + { + throw new NotImplementedException(); + } + } + """, + """ + using System; - class Demo + class C + { + static void Main(string[] args) { - static void Main() - { - F(); - void F() - { - Action f = () => - { - Dictionary dict = null; - int [|x|] = 0; - dict.TryGetValue(0, out x); - Console.WriteLine(x); - }; - } - } + bool condition = false && GetValue(out string token); } - """, - """ - using System; - using System.Collections.Generic; - class Demo + private static bool GetValue(out string token) { - static void Main() - { - F(); - void F() - { - Action f = () => - { - Dictionary dict = null; - dict.TryGetValue(0, out int x); - Console.WriteLine(x); - }; - } - } + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16676")] - public async Task TestMultipleDeclarationStatementsOnSameLine1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18076")] + public async Task TestInFixed() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + static void Main(string[] args) { - void Goo() + string [|token|]; + fixed (int* p = GetValue(out token)) { - string a; string [|b|]; - Method(out a, out b); } } - """, - """ - class C + + private static int[] GetValue(out string token) { - void Goo() - { - string a; - Method(out a, out string b); - } + throw new NotImplementedException(); } - """); - } + } + """, + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16676")] - public async Task TestMultipleDeclarationStatementsOnSameLine2() - { - await TestInRegularAndScript1Async( - """ - class C + class C + { + static void Main(string[] args) { - void Goo() + fixed (int* p = GetValue(out string token)) { - string a; /*leading*/ string [|b|]; // trailing - Method(out a, out b); } } - """, - """ - class C + + private static int[] GetValue(out string token) { - void Goo() - { - string a; /*leading*/ // trailing - Method(out a, out string b); - } + throw new NotImplementedException(); } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17743")] + public async Task TestInLocalFunction1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16676")] - public async Task TestMultipleDeclarationStatementsOnSameLine3() - { - await TestInRegularAndScript1Async( - """ - class C + class Demo + { + static void Main() { - void Goo() + F(); + void F() { - string a; - /*leading*/ string [|b|]; // trailing - Method(out a, out b); + Action f = () => + { + Dictionary dict = null; + int [|x|] = 0; + dict?.TryGetValue(0, out x); + Console.WriteLine(x); + }; } } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestInLocalFunction2() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Collections.Generic; + + class Demo + { + static void Main() { - void Goo() + F(); + void F() { - string a; - /*leading*/ // trailing - Method(out a, out string b); + Action f = () => + { + Dictionary dict = null; + int [|x|] = 0; + dict.TryGetValue(0, out x); + Console.WriteLine(x); + }; } } - """); - } + } + """, + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestMissingOnUnderscore() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C + class Demo + { + static void Main() { - void M() + F(); + void F() { - [|int|] _; - if (N(out _) + Action f = () => { - Console.WriteLine(_); - } + Dictionary dict = null; + dict.TryGetValue(0, out int x); + Console.WriteLine(x); + }; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18668")] - public async Task TestDefiniteAssignmentIssueWithVar() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16676")] + public async Task TestMultipleDeclarationStatementsOnSameLine1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void Goo() + { + string a; string [|b|]; + Method(out a, out b); + } + } + """, + """ + class C + { + void Goo() + { + string a; + Method(out a, out string b); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16676")] + public async Task TestMultipleDeclarationStatementsOnSameLine2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void Goo() + { + string a; /*leading*/ string [|b|]; // trailing + Method(out a, out b); + } + } + """, + """ + class C + { + void Goo() + { + string a; /*leading*/ // trailing + Method(out a, out string b); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16676")] + public async Task TestMultipleDeclarationStatementsOnSameLine3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void Goo() + { + string a; + /*leading*/ string [|b|]; // trailing + Method(out a, out b); + } + } + """, + """ + class C + { + void Goo() + { + string a; + /*leading*/ // trailing + Method(out a, out string b); + } + } + """); + } + + [Fact] + public async Task TestMissingOnUnderscore() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - static void M(bool condition) + [|int|] _; + if (N(out _) { - [|var|] x = 1; - var result = condition && int.TryParse("2", out x); - Console.WriteLine(x); + Console.WriteLine(_); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18668")] - public async Task TestDefiniteAssignmentIssueWithNonVar() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18668")] + public async Task TestDefiniteAssignmentIssueWithVar() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M(bool condition) { - static void M(bool condition) - { - [|int|] x = 1; - var result = condition && int.TryParse("2", out x); - Console.WriteLine(x); - } + [|var|] x = 1; + var result = condition && int.TryParse("2", out x); + Console.WriteLine(x); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] - public async Task TestMissingOnCrossFunction1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18668")] + public async Task TestDefiniteAssignmentIssueWithNonVar() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class C + { + static void M(bool condition) { - static void Main(string[] args) - { - Method(); - } + [|int|] x = 1; + var result = condition && int.TryParse("2", out x); + Console.WriteLine(x); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] + public async Task TestMissingOnCrossFunction1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class Program + { + static void Main(string[] args) + { + Method(); + } + + public static void Method() + { + [|T t|]; + void Local() + { + Out(out t); + Console.WriteLine(t); + } + Local(); + } + + public static void Out(out T t) => t = default; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] + public async Task TestMissingOnCrossFunction2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - public static void Method() - { + class Program + { + static void Main(string[] args) + { + Method(); + } + + public static void Method() + { + void Local() + { [|T t|]; - void Local() + void InnerLocal() { Out(out t); Console.WriteLine(t); } - Local(); - } - - public static void Out(out T t) => t = default; } - """); - } + Local(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] - public async Task TestMissingOnCrossFunction2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + public static void Out(out T t) => t = default; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] + public async Task TestMissingOnCrossFunction3() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { Method(); - } + } - public static void Method() - { + public static void Method() + { + [|T t|]; void Local() { - [|T t|]; - void InnerLocal() - { - Out(out t); - Console.WriteLine(t); + { // <-- note this set of added braces + Out(out t); + Console.WriteLine(t); } } Local(); - } - - public static void Out(out T t) => t = default; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] - public async Task TestMissingOnCrossFunction3() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + public static void Out(out T t) => t = default; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] + public async Task TestMissingOnCrossFunction4() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Method(); - } + Method(); + } - public static void Method() - { + public static void Method() + { + { // <-- note this set of added braces [|T t|]; void Local() { - { // <-- note this set of added braces + { // <-- and my axe Out(out t); Console.WriteLine(t); } } Local(); } - - public static void Out(out T t) => t = default; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21907")] - public async Task TestMissingOnCrossFunction4() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class Program - { - static void Main(string[] args) - { - Method(); - } - public static void Method() - { - { // <-- note this set of added braces - [|T t|]; - void Local() - { - { // <-- and my axe - Out(out t); - Console.WriteLine(t); - } - } - Local(); - } - } + public static void Out(out T t) => t = default; + } + """); + } - public static void Out(out T t) => t = default; - } - """); - } + [Fact] + public async Task TestDefiniteAssignment1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - [Fact] - public async Task TestDefiniteAssignment1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + class C + { + static bool M(out bool i) => throw null; - class C + static void M(bool condition) { - static bool M(out bool i) => throw null; - - static void M(bool condition) + [|bool|] x = false; + if (condition || M(out x)) { - [|bool|] x = false; - if (condition || M(out x)) - { - Console.WriteLine(x); - } + Console.WriteLine(x); } } - """); - } - - [Fact] - public async Task TestDefiniteAssignment2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C - { - static bool M(out bool i) => throw null; - static bool Use(bool i) => throw null; + } + """); + } - static void M(bool condition) - { - [|bool|] x = false; - if (condition || M(out x)) - { - x = Use(x); - } - } - } - """); - } + [Fact] + public async Task TestDefiniteAssignment2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - [Theory] - [InlineData("c && M(out x)", "c && M(out bool x)")] - [InlineData("false || M(out x)", "false || M(out bool x)")] - [InlineData("M(out x) || M(out x)", "M(out bool x) || M(out x)")] - public async Task TestDefiniteAssignment3(string input, string output) - { - await TestInRegularAndScript1Async( - $$""" - using System; + class C + { + static bool M(out bool i) => throw null; + static bool Use(bool i) => throw null; - class C + static void M(bool condition) { - static bool M(out bool i) => throw null; - static bool Use(bool i) => throw null; - - static void M(bool c) + [|bool|] x = false; + if (condition || M(out x)) { - [|bool|] x = false; - if ({{input}}) - { - Console.WriteLine(x); - } + x = Use(x); } } - """, - $$""" - using System; + } + """); + } - class C - { - static bool M(out bool i) => throw null; - static bool Use(bool i) => throw null; + [Theory] + [InlineData("c && M(out x)", "c && M(out bool x)")] + [InlineData("false || M(out x)", "false || M(out bool x)")] + [InlineData("M(out x) || M(out x)", "M(out bool x) || M(out x)")] + public async Task TestDefiniteAssignment3(string input, string output) + { + await TestInRegularAndScript1Async( + $$""" + using System; - static void M(bool c) - { - if ({{output}}) - { - Console.WriteLine(x); - } - } - } - """); - } + class C + { + static bool M(out bool i) => throw null; + static bool Use(bool i) => throw null; - [Fact] - public async Task InlineVariable_NullableEnable() - { - await TestInRegularAndScript1Async(""" - #nullable enable - class C + static void M(bool c) { - void M(out C c2) + [|bool|] x = false; + if ({{input}}) { - [|C|] c; - M(out c); - c2 = c; + Console.WriteLine(x); } } - """, """ - #nullable enable - class C + } + """, + $$""" + using System; + + class C + { + static bool M(out bool i) => throw null; + static bool Use(bool i) => throw null; + + static void M(bool c) { - void M(out C c2) + if ({{output}}) { - M(out C c); - c2 = c; + Console.WriteLine(x); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44429")] - public async Task TopLevelStatement() - { - await TestMissingAsync(""" - [|int|] i; - if (int.TryParse(v, out i)) - { - } - """, new TestParameters(TestOptions.Regular)); - } + [Fact] + public async Task InlineVariable_NullableEnable() + { + await TestInRegularAndScript1Async(""" + #nullable enable + class C + { + void M(out C c2) + { + [|C|] c; + M(out c); + c2 = c; + } + } + """, """ + #nullable enable + class C + { + void M(out C c2) + { + M(out C c); + c2 = c; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47041")] - public async Task CollectionInitializer() - { - await TestInRegularAndScript1Async( - """ - class C - { - private List> _funcs2 = new List>() - { - s => { int [|i|] = 0; return int.TryParse(s, out i); } - }; - } - """, - """ - class C - { - private List> _funcs2 = new List>() - { - s => { return int.TryParse(s, out int i); } - }; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44429")] + public async Task TopLevelStatement() + { + await TestMissingAsync(""" + [|int|] i; + if (int.TryParse(v, out i)) + { + } + """, new TestParameters(TestOptions.Regular)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22881")] - public async Task PriorRegionClose() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47041")] + public async Task CollectionInitializer() + { + await TestInRegularAndScript1Async( + """ + class C + { + private List> _funcs2 = new List>() + { + s => { int [|i|] = 0; return int.TryParse(s, out i); } + }; + } + """, + """ + class C + { + private List> _funcs2 = new List>() + { + s => { return int.TryParse(s, out int i); } + }; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22881")] + public async Task PriorRegionClose() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - #region test + #region test - int i = 0; + int i = 0; - #endregion + #endregion - int [|hello|]; - TestMethod(out hello); - } + int [|hello|]; + TestMethod(out hello); + } - private void TestMethod(out int hello) - { - } + private void TestMethod(out int hello) + { } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - #region test + #region test - int i = 0; + int i = 0; - #endregion + #endregion - TestMethod(out int hello); - } + TestMethod(out int hello); + } - private void TestMethod(out int hello) - { - } + private void TestMethod(out int hello) + { } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests_FixAllTests.cs index 5e1796a134906..6b87c764f4649 100644 --- a/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/InlineDeclaration/CSharpInlineDeclarationTests_FixAllTests.cs @@ -9,481 +9,480 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InlineDeclaration +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InlineDeclaration; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] +public partial class CSharpInlineDeclarationTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] - public partial class CSharpInlineDeclarationTests + [Fact] + public async Task FixAllInDocument1() { - [Fact] - public async Task FixAllInDocument1() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i|}, j; + if (int.TryParse(v, out i, out j)) { - int {|FixAllInDocument:i|}, j; - if (int.TryParse(v, out i, out j)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (int.TryParse(v, out int i, out int j)) { - if (int.TryParse(v, out int i, out int j)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument2() - { + [Fact] + public async Task FixAllInDocument2() + { - await TestInRegularAndScriptAsync( - """ - class C + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + {|FixAllInDocument:int|} i; + if (int.TryParse(v, out i)) { - {|FixAllInDocument:int|} i; - if (int.TryParse(v, out i)) - { - } } + } - void M1() + void M1() + { + int i; + if (int.TryParse(v, out i)) { - int i; - if (int.TryParse(v, out i)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } + } - void M1() + void M1() + { + if (int.TryParse(v, out int i)) { - if (int.TryParse(v, out int i)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument3() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - // Now get final exe and args. CTtrl-F5 wraps exe in cmd prompt - string {|FixAllInDocument:finalExecutable|}, finalArguments; - GetExeAndArguments(useCmdShell, executable, arguments, out finalExecutable, out finalArguments); - } + [Fact] + public async Task FixAllInDocument3() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + // Now get final exe and args. CTtrl-F5 wraps exe in cmd prompt + string {|FixAllInDocument:finalExecutable|}, finalArguments; + GetExeAndArguments(useCmdShell, executable, arguments, out finalExecutable, out finalArguments); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - // Now get final exe and args. CTtrl-F5 wraps exe in cmd prompt - GetExeAndArguments(useCmdShell, executable, arguments, out string finalExecutable, out string finalArguments); - } + // Now get final exe and args. CTtrl-F5 wraps exe in cmd prompt + GetExeAndArguments(useCmdShell, executable, arguments, out string finalExecutable, out string finalArguments); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29935")] - public async Task FixAllInDocumentSymbolResolution() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - string {|FixAllInDocument:s|}; - bool b; - A(out s, out b); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29935")] + public async Task FixAllInDocumentSymbolResolution() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + string {|FixAllInDocument:s|}; + bool b; + A(out s, out b); + } - void A(out string s, out bool b) - { - s = string.Empty; - b = false; - } + void A(out string s, out bool b) + { + s = string.Empty; + b = false; + } - void A(out string s, out string s2) - { - s = s2 = string.Empty; - } + void A(out string s, out string s2) + { + s = s2 = string.Empty; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - A(out string s, out bool b); - } + A(out string s, out bool b); + } - void A(out string s, out bool b) - { - s = string.Empty; - b = false; - } + void A(out string s, out bool b) + { + s = string.Empty; + b = false; + } - void A(out string s, out string s2) - { - s = s2 = string.Empty; - } + void A(out string s, out string s2) + { + s = s2 = string.Empty; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocument4() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}; int i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocument4() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}; int i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - } + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocument5() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int dummy; int {|FixAllInDocument:i1|}; int i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocument5() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int dummy; int {|FixAllInDocument:i1|}; int i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int dummy; - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + int dummy; + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocument6() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}; int dummy; int i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocument6() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}; int dummy; int i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int dummy; - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + int dummy; + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocument7() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}; int i2; int dummy; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocument7() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}; int i2; int dummy; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int dummy; - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + int dummy; + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument8() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int dummy, {|FixAllInDocument:i1|}, i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact] + public async Task FixAllInDocument8() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int dummy, {|FixAllInDocument:i1|}, i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int dummy; - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + int dummy; + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument9() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}, dummy, i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact] + public async Task FixAllInDocument9() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}, dummy, i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int dummy; - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + int dummy; + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument10() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}, i2, dummy; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact] + public async Task FixAllInDocument10() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}, i2, dummy; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int dummy; - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + int dummy; + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument11() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}, i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - } + [Fact] + public async Task FixAllInDocument11() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}, i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - } + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocumentComments1() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - /* leading */ int {|FixAllInDocument:i1|}; int i2; // trailing - int.TryParse(v, out i1); - int.TryParse(v, out i2); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocumentComments1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + /* leading */ int {|FixAllInDocument:i1|}; int i2; // trailing + int.TryParse(v, out i1); + int.TryParse(v, out i2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - /* leading */ // trailing - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - } + /* leading */ // trailing + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocumentComments2() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - /* leading */ int dummy; /* in-between */ int {|FixAllInDocument:i1|}; int i2; // trailing - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocumentComments2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + /* leading */ int dummy; /* in-between */ int {|FixAllInDocument:i1|}; int i2; // trailing + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - /* leading */ int dummy; /* in-between */ // trailing - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + /* leading */ int dummy; /* in-between */ // trailing + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] - public async Task FixAllInDocumentComments3() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int {|FixAllInDocument:i1|}; /* 0 */int /* 1 */ dummy /* 2 */; /* 3*/ int i2; - int.TryParse(v, out i1); - int.TryParse(v, out i2); - dummy = 42; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28323")] + public async Task FixAllInDocumentComments3() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int {|FixAllInDocument:i1|}; /* 0 */int /* 1 */ dummy /* 2 */; /* 3*/ int i2; + int.TryParse(v, out i1); + int.TryParse(v, out i2); + dummy = 42; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - /* 0 */ - int /* 1 */ dummy /* 2 */; /* 3*/ - int.TryParse(v, out int i1); - int.TryParse(v, out int i2); - dummy = 42; - } + /* 0 */ + int /* 1 */ dummy /* 2 */; /* 3*/ + int.TryParse(v, out int i1); + int.TryParse(v, out int i2); + dummy = 42; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs index 573c58a3c9a36..7bf1df28ebabd 100644 --- a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs +++ b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests.cs @@ -12,1122 +12,1121 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.InvokeDelegateWithConditionalAccess +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.InvokeDelegateWithConditionalAccess; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInvokeDelegateWithConditionalAccess)] +public partial class InvokeDelegateWithConditionalAccessTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsInvokeDelegateWithConditionalAccess)] - public partial class InvokeDelegateWithConditionalAccessTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public InvokeDelegateWithConditionalAccessTests(ITestOutputHelper logger) + : base(logger) { - public InvokeDelegateWithConditionalAccessTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new InvokeDelegateWithConditionalAccessAnalyzer(), new InvokeDelegateWithConditionalAccessCodeFixProvider()); - - [Fact] - public async Task Test1() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + } - void Goo() - { - [||]var v = a; - if (v != null) - { - v(); - } - } - } - """, - """ - class C - { - System.Action a; + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new InvokeDelegateWithConditionalAccessAnalyzer(), new InvokeDelegateWithConditionalAccessCodeFixProvider()); - void Goo() - { - a?.Invoke(); - } - } - """); - } - - [Fact] - public async Task TestOnIf() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + [Fact] + public async Task Test1() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() - { - var v = a; - [||]if (v != null) - { - v(); - } - } - } - """, - """ - class C + void Goo() { - System.Action a; - - void Goo() + [||]var v = a; + if (v != null) { - a?.Invoke(); + v(); } } - """); - } - - [Fact] - public async Task TestOnInvoke() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestOnIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + [||]if (v != null) { - var v = a; - if (v != null) - { - [||]v(); - } + v(); } } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestOnInvoke() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + if (v != null) { - a?.Invoke(); + [||]v(); } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] - public async Task TestMissingBeforeCSharp6() - { - await TestMissingAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + } + } + """); + } - void Goo() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] + public async Task TestMissingBeforeCSharp6() + { + await TestMissingAsync( + """ + class C + { + System.Action a; + + void Goo() + { + [||]var v = a; + if (v != null) { - [||]var v = a; - if (v != null) - { - v(); - } + v(); } } - """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp5))); - } - - [Fact] - public async Task TestInvertedIf() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + } + """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp5))); + } + + [Fact] + public async Task TestInvertedIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + [||]var v = a; + if (null != v) { - [||]var v = a; - if (null != v) - { - v(); - } + v(); } } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + } + } + """); + } - void Goo() - { - a?.Invoke(); - } + [Fact] + public async Task TestIfWithNoBraces() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + + void Goo() + { + [||]var v = a; + if (null != v) + v(); } - """); - } - - [Fact] - public async Task TestIfWithNoBraces() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestWithComplexExpression() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + bool b = true; + [||]var v = b ? a : null; + if (v != null) { - [||]var v = a; - if (null != v) - v(); + v(); } } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + bool b = true; + (b ? a : null)?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestMissingWithElseClause() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + [||]var v = a; + if (v != null) { - a?.Invoke(); + v(); } - } - """); - } - - [Fact] - public async Task TestWithComplexExpression() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; - - void Goo() + else { - bool b = true; - [||]var v = b ? a : null; - if (v != null) - { - v(); - } } } - """, - """ - class C - { - System.Action a; + } + """); + } + + [Fact] + public async Task TestMissingOnDeclarationWithMultipleVariables() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + [||]var v = a, x = a; + if (v != null) { - bool b = true; - (b ? a : null)?.Invoke(); + v(); } } - """); - } - - [Fact] - public async Task TestMissingWithElseClause() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - System.Action a; + } + """); + } - void Goo() + /// + /// With multiple variables in the same declaration, the fix _is not_ offered on the declaration + /// itself, but _is_ offered on the invocation pattern. + /// + [Fact] + public async Task TestLocationWhereOfferedWithMultipleVariables() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a, x = a; + [||]if (v != null) { - [||]var v = a; - if (v != null) - { - v(); - } - else - { - } + v(); } } - """); - } - - [Fact] - public async Task TestMissingOnDeclarationWithMultipleVariables() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + var v = a, x = a; + v?.Invoke(); + } + } + """); + } - void Goo() + /// + /// If we have a variable declaration and if it is read/written outside the delegate + /// invocation pattern, the fix is not offered on the declaration. + /// + [Fact] + public async Task TestMissingOnDeclarationIfUsedOutside() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() + { + [||]var v = a; + if (v != null) { - [||]var v = a, x = a; - if (v != null) - { - v(); - } + v(); } + + v = null; } - """); - } - - /// - /// With multiple variables in the same declaration, the fix _is not_ offered on the declaration - /// itself, but _is_ offered on the invocation pattern. - /// - [Fact] - public async Task TestLocationWhereOfferedWithMultipleVariables() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + } + """); + } + + /// + /// If we have a variable declaration and if it is read/written outside the delegate + /// invocation pattern, the fix is not offered on the declaration but is offered on + /// the invocation pattern itself. + /// + [Fact] + public async Task TestLocationWhereOfferedIfUsedOutside() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + [||]if (v != null) { - var v = a, x = a; - [||]if (v != null) - { - v(); - } + v(); } + + v = null; } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + var v = a; + v?.Invoke(); - void Goo() - { - var v = a, x = a; - v?.Invoke(); - } + v = null; } - """); - } - - /// - /// If we have a variable declaration and if it is read/written outside the delegate - /// invocation pattern, the fix is not offered on the declaration. - /// - [Fact] - public async Task TestMissingOnDeclarationIfUsedOutside() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - System.Action a; + } + """); + } - void Goo() - { - [||]var v = a; - if (v != null) - { - v(); - } + [Fact] + public async Task TestSimpleForm1() + { + await TestInRegularAndScript1Async( + """ + using System; - v = null; - } - } - """); - } - - /// - /// If we have a variable declaration and if it is read/written outside the delegate - /// invocation pattern, the fix is not offered on the declaration but is offered on - /// the invocation pattern itself. - /// - [Fact] - public async Task TestLocationWhereOfferedIfUsedOutside() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + class C + { + public event EventHandler E; - void Goo() + void M() + { + [||]if (this.E != null) { - var v = a; - [||]if (v != null) - { - v(); - } - - v = null; + this.E(this, EventArgs.Empty); } } - """, - """ - class C - { - System.Action a; + } + """, + """ + using System; - void Goo() - { - var v = a; - v?.Invoke(); + class C + { + public event EventHandler E; - v = null; - } + void M() + { + this.E?.Invoke(this, EventArgs.Empty); } - """); - } + } + """); + } - [Fact] - public async Task TestSimpleForm1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSimpleForm2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C - { - public event EventHandler E; + class C + { + public event EventHandler E; - void M() + void M() + { + if (this.E != null) { - [||]if (this.E != null) - { - this.E(this, EventArgs.Empty); - } + [||]this.E(this, EventArgs.Empty); } } - """, - """ - using System; + } + """, + """ + using System; - class C - { - public event EventHandler E; + class C + { + public event EventHandler E; - void M() - { - this.E?.Invoke(this, EventArgs.Empty); - } + void M() + { + this.E?.Invoke(this, EventArgs.Empty); } - """); - } + } + """); + } + + [Fact] + public async Task TestInElseClause1() + { + await TestInRegularAndScript1Async( + """ + using System; - [Fact] - public async Task TestSimpleForm2() - { - await TestInRegularAndScript1Async( - """ - using System; + class C + { + public event EventHandler E; - class C + void M() { - public event EventHandler E; - - void M() + if (true != true) { - if (this.E != null) - { - [||]this.E(this, EventArgs.Empty); - } } - } - """, - """ - using System; - - class C - { - public event EventHandler E; - - void M() + else [||]if (this.E != null) { - this.E?.Invoke(this, EventArgs.Empty); + this.E(this, EventArgs.Empty); } } - """); - } + } + """, + """ + using System; - [Fact] - public async Task TestInElseClause1() - { - await TestInRegularAndScript1Async( - """ - using System; + class C + { + public event EventHandler E; - class C + void M() { - public event EventHandler E; - - void M() + if (true != true) { - if (true != true) - { - } - else [||]if (this.E != null) - { - this.E(this, EventArgs.Empty); - } } - } - """, - """ - using System; - - class C - { - public event EventHandler E; - - void M() + else { - if (true != true) - { - } - else - { - this.E?.Invoke(this, EventArgs.Empty); - } + this.E?.Invoke(this, EventArgs.Empty); } } - """); - } + } + """); + } - [Fact] - public async Task TestInElseClause2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestInElseClause2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C - { - public event EventHandler E; + class C + { + public event EventHandler E; - void M() + void M() + { + if (true != true) { - if (true != true) - { - } - else [||]if (this.E != null) - this.E(this, EventArgs.Empty); } + else [||]if (this.E != null) + this.E(this, EventArgs.Empty); } - """, - """ - using System; + } + """, + """ + using System; - class C - { - public event EventHandler E; + class C + { + public event EventHandler E; - void M() - { - if (true != true) - { - } - else this.E?.Invoke(this, EventArgs.Empty); - } - } - """); - } - - [Fact] - public async Task TestTrivia1() - { - await TestInRegularAndScript1Async( - """ - class C + void M() { - System.Action a; - void Goo() + if (true != true) { - // Comment - [||]var v = a; - if (v != null) - { - v(); // Comment2 - } } + else this.E?.Invoke(this, EventArgs.Empty); } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestTrivia1() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() + // Comment + [||]var v = a; + if (v != null) { - // Comment - a?.Invoke(); // Comment2 + v(); // Comment2 } } - """); - } - - [Fact] - public async Task TestTrivia2() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() - { - // Comment - [||]if (a != null) - { - a(); // Comment2 - } - } + // Comment + a?.Invoke(); // Comment2 } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestTrivia2() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() + // Comment + [||]if (a != null) { - // Comment - a?.Invoke(); // Comment2 + a(); // Comment2 } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51563")] - public async Task TestTrivia3() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() - { - // Comment - [||]var v = a; - if (v != null) { v(); /* 123 */ } // trails - System.Console.WriteLine(); - } + // Comment + a?.Invoke(); // Comment2 } - """, - """ - class C + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51563")] + public async Task TestTrivia3() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() - { - // Comment - a?.Invoke(); /* 123 */ // trails - System.Console.WriteLine(); - } + // Comment + [||]var v = a; + if (v != null) { v(); /* 123 */ } // trails + System.Console.WriteLine(); } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51563")] - public async Task TestTrivia4() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() - { - [||]if (a != null) { a(); /* 123 */ } // trails - System.Console.WriteLine(); - } + // Comment + a?.Invoke(); /* 123 */ // trails + System.Console.WriteLine(); } - """, - """ - class C + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51563")] + public async Task TestTrivia4() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - void Goo() - { - a?.Invoke(); /* 123 */ // trails - System.Console.WriteLine(); - } + [||]if (a != null) { a(); /* 123 */ } // trails + System.Console.WriteLine(); } - """); - } - - /// - /// tests locations where the fix is offered. - /// - [Fact] - public async Task TestFixOfferedOnIf() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + System.Action a; + void Goo() { - System.Action a; - - void Goo() - { - var v = a; - [||]if (v != null) - { - v(); - } - } + a?.Invoke(); /* 123 */ // trails + System.Console.WriteLine(); } - """, - """ - class C - { - System.Action a; + } + """); + } - void Goo() - { - a?.Invoke(); - } - } - """); - } - - /// - /// tests locations where the fix is offered. - /// - [Fact] - public async Task TestFixOfferedInsideIf() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + /// + /// tests locations where the fix is offered. + /// + [Fact] + public async Task TestFixOfferedOnIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() - { - var v = a; - if (v != null) - { - [||]v(); - } - } - } - """, - """ - class C + void Goo() { - System.Action a; - - void Goo() + var v = a; + [||]if (v != null) { - a?.Invoke(); + v(); } } - """); - } - - [Fact] - public async Task TestMissingOnConditionalInvocation() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; - - void Goo() - { - [||]var v = a; - v?.Invoke(); - } + a?.Invoke(); } - """); - } - - [Fact] - public async Task TestMissingOnConditionalInvocation2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - System.Action a; + } + """); + } + + /// + /// tests locations where the fix is offered. + /// + [Fact] + public async Task TestFixOfferedInsideIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + if (v != null) { - var v = a; - [||]v?.Invoke(); + [||]v(); } } - """); - } - - [Fact] - public async Task TestMissingOnConditionalInvocation3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; - - void Goo() - { - [||]a?.Invoke(); - } + a?.Invoke(); } - """); - } - - [Fact] - public async Task TestMissingOnNonNullCheckExpressions() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """); + } + + [Fact] + public async Task TestMissingOnConditionalInvocation() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + [||]var v = a; + v?.Invoke(); + } + } + """); + } - void Goo() - { - var v = a; - if (v == a) - { - [||]v(); - } - } + [Fact] + public async Task TestMissingOnConditionalInvocation2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a; + [||]v?.Invoke(); } - """); - } - - [Fact] - public async Task TestMissingOnNonNullCheckExpressions2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """); + } + + [Fact] + public async Task TestMissingOnConditionalInvocation3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + [||]a?.Invoke(); + } + } + """); + } + + [Fact] + public async Task TestMissingOnNonNullCheckExpressions() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + if (v == a) { - var v = a; - if (v == null) - { - [||]v(); - } + [||]v(); } } - """); - } - - /// - /// if local declaration is not immediately preceding the invocation pattern, - /// the fix is not offered on the declaration. - /// - [Fact] - public async Task TestLocalNotImmediatelyPrecedingNullCheckAndInvokePattern() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - System.Action a; + } + """); + } - void Goo() + [Fact] + public async Task TestMissingOnNonNullCheckExpressions2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a; + if (v == null) { - [||]var v = a; - int x; - if (v != null) - { - v(); - } + [||]v(); } } - """); - } - - /// - /// if local declaration is not immediately preceding the invocation pattern, - /// the fix is not offered on the declaration but is offered on the invocation pattern itself. - /// - [Fact] - public async Task TestLocalDNotImmediatelyPrecedingNullCheckAndInvokePattern2() - { - await TestInRegularAndScript1Async( - """ - class C - { - System.Action a; + } + """); + } + + /// + /// if local declaration is not immediately preceding the invocation pattern, + /// the fix is not offered on the declaration. + /// + [Fact] + public async Task TestLocalNotImmediatelyPrecedingNullCheckAndInvokePattern() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + [||]var v = a; + int x; + if (v != null) { - var v = a; - int x; - [||]if (v != null) - { - v(); - } + v(); } } - """, - """ - class C - { - System.Action a; + } + """); + } + + /// + /// if local declaration is not immediately preceding the invocation pattern, + /// the fix is not offered on the declaration but is offered on the invocation pattern itself. + /// + [Fact] + public async Task TestLocalDNotImmediatelyPrecedingNullCheckAndInvokePattern2() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + int x; + [||]if (v != null) { - var v = a; - int x; - v?.Invoke(); + v(); } } - """); - } - - [Fact] - public async Task TestMissingOnFunc() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Func a; - - int Goo() - { - var v = a; - [||]if (v != null) - { - return v(); - } - } + var v = a; + int x; + v?.Invoke(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] - public async Task TestWithLambdaInitializer() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestMissingOnFunc() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + System.Func a; - class C + int Goo() { - void Goo() + var v = a; + [||]if (v != null) { - Action v = () => {}; - [||]if (v != null) - { - v(); - } + return v(); } } - """, - """ - using System; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] + public async Task TestWithLambdaInitializer() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action v = () => {}; + [||]if (v != null) { - Action v = () => {}; - v?.Invoke(); + v(); } } - """); - } + } + """, + """ + using System; + + class C + { + void Goo() + { + Action v = () => {}; + v?.Invoke(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] - public async Task TestWithLambdaInitializer2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] + public async Task TestWithLambdaInitializer2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action v = (() => {}); + [||]if (v != null) { - Action v = (() => {}); - [||]if (v != null) - { - v(); - } + v(); } } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void Goo() { - void Goo() - { - Action v = (() => {}); - v?.Invoke(); - } + Action v = (() => {}); + v?.Invoke(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] - public async Task TestForWithAnonymousMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] + public async Task TestForWithAnonymousMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action v = delegate {}; + [||]if (v != null) { - Action v = delegate {}; - [||]if (v != null) - { - v(); - } + v(); } } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void Goo() { - void Goo() - { - Action v = delegate {}; - v?.Invoke(); - } + Action v = delegate {}; + v?.Invoke(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] - public async Task TestWithMethodReference() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13226")] + public async Task TestWithMethodReference() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action v = Console.WriteLine; + [||]if (v != null) { - Action v = Console.WriteLine; - [||]if (v != null) - { - v(); - } + v(); } } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void Goo() { - void Goo() - { - Action v = Console.WriteLine; - v?.Invoke(); - } + Action v = Console.WriteLine; + v?.Invoke(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31827")] - public async Task TestWithExplicitInvokeCall1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31827")] + public async Task TestWithExplicitInvokeCall1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - [||]if (Event != null) - Event.Invoke(this, EventArgs.Empty); - } - - event EventHandler Event; + [||]if (Event != null) + Event.Invoke(this, EventArgs.Empty); } - """, - """ - using System; - class C - { - void M() - { - Event?.Invoke(this, EventArgs.Empty); - } + event EventHandler Event; + } + """, + """ + using System; - event EventHandler Event; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31827")] - public async Task TestWithExplicitInvokeCall2() - { - await TestInRegularAndScript1Async( - """ - class C + class C + { + void M() { - System.Action a; + Event?.Invoke(this, EventArgs.Empty); + } + + event EventHandler Event; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31827")] + public async Task TestWithExplicitInvokeCall2() + { + await TestInRegularAndScript1Async( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + [||]var v = a; + if (v != null) { - [||]var v = a; - if (v != null) - { - v.Invoke(); - } + v.Invoke(); } } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; - - void Goo() - { - a?.Invoke(); - } + a?.Invoke(); } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50976")] - public async Task TestMissingOnFunctionPointer() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50976")] + public async Task TestMissingOnFunctionPointer() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + unsafe void M(delegate* managed func) { - unsafe void M(delegate* managed func) + if (func != null) { - if (func != null) - { - [||]func(); - } + [||]func(); } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs index 5ccf06df80da4..07c379e3b669b 100644 --- a/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/InvokeDelegateWithConditionalAccess/InvokeDelegateWithConditionalAccessTests_FixAllTests.cs @@ -8,249 +8,242 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.InvokeDelegateWithConditionalAccess +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.InvokeDelegateWithConditionalAccess; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInvokeDelegateWithConditionalAccess)] +public partial class InvokeDelegateWithConditionalAccessTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsInvokeDelegateWithConditionalAccess)] - public partial class InvokeDelegateWithConditionalAccessTests + [Fact] + public async Task TestFixAllInDocument1() { - [Fact] - public async Task TestFixAllInDocument1() - { - await TestInRegularAndScriptAsync( - """ - class C - { - System.Action a; + await TestInRegularAndScriptAsync( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + {|FixAllInDocument:var|} v = a; + if (v != null) { - {|FixAllInDocument:var|} v = a; - if (v != null) - { - v(); - } - - var x = a; - if (x != null) - { - x(); - } + v(); } - } - """, - """ - class C - { - System.Action a; - void Goo() + var x = a; + if (x != null) { - a?.Invoke(); - - a?.Invoke(); + x(); } } - """); - } - - [Fact] - public async Task TestFixAllInDocument2() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + a?.Invoke(); + } + } + """); + } - void Goo() - { - var v = a; - {|FixAllInDocument:if|} (v != null) - { - v(); - } + [Fact] + public async Task TestFixAllInDocument2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + System.Action a; - var x = a; - if (x != null) - { - x(); - } - } - } - """, - """ - class C + void Goo() { - System.Action a; - - void Goo() + var v = a; + {|FixAllInDocument:if|} (v != null) { - a?.Invoke(); - - a?.Invoke(); + v(); } - } - """); - } - - [Fact] - public async Task TestFixAllInDocument3() - { - await TestInRegularAndScriptAsync( - """ - class C - { - System.Action a; - void Goo() + var x = a; + if (x != null) { - var v = a; - if (v != null) - { - {|FixAllInDocument:v|}(); - } - - var x = a; - if (x != null) - { - x(); - } + x(); } } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; - - void Goo() - { - a?.Invoke(); - - a?.Invoke(); - } + a?.Invoke(); + a?.Invoke(); } - """); - } + } + """); + } - [Fact] - public async Task TestFixAllInDocument4() - { - await TestInRegularAndScriptAsync( - """ - class C - { - System.Action a; + [Fact] + public async Task TestFixAllInDocument3() + { + await TestInRegularAndScriptAsync( + """ + class C + { + System.Action a; - void Goo() + void Goo() + { + var v = a; + if (v != null) { - var v = a; - if (v != null) - { - v(); - } - - {|FixAllInDocument:var|} x = a; - if (x != null) - { - x(); - } + {|FixAllInDocument:v|}(); } - } - """, - """ - class C - { - System.Action a; - void Goo() + var x = a; + if (x != null) { - a?.Invoke(); - - a?.Invoke(); + x(); } } - """); - } - - [Fact] - public async Task TestFixAllInDocument5() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + a?.Invoke(); + } + } + """); + } - void Goo() - { - var v = a; - if (v != null) - { - v(); - } + [Fact] + public async Task TestFixAllInDocument4() + { + await TestInRegularAndScriptAsync( + """ + class C + { + System.Action a; - var x = a; - {|FixAllInDocument:if|} (x != null) - { - x(); - } - } - } - """, - """ - class C + void Goo() { - System.Action a; - - void Goo() + var v = a; + if (v != null) { - a?.Invoke(); + v(); + } - a?.Invoke(); + {|FixAllInDocument:var|} x = a; + if (x != null) + { + x(); } } - """); - } - - [Fact] - public async Task TestFixAllInDocument6() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + a?.Invoke(); + } + } + """); + } - void Goo() + [Fact] + public async Task TestFixAllInDocument5() + { + await TestInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a; + if (v != null) { - var v = a; - if (v != null) - { - v(); - } + v(); + } - var x = a; - if (x != null) - { - {|FixAllInDocument:x|}(); - } + var x = a; + {|FixAllInDocument:if|} (x != null) + { + x(); } } - """, - """ - class C + } + """, + """ + class C + { + System.Action a; + + void Goo() { - System.Action a; + a?.Invoke(); + a?.Invoke(); + } + } + """); + } - void Goo() + [Fact] + public async Task TestFixAllInDocument6() + { + await TestInRegularAndScriptAsync( + """ + class C + { + System.Action a; + + void Goo() + { + var v = a; + if (v != null) { - a?.Invoke(); + v(); + } - a?.Invoke(); + var x = a; + if (x != null) + { + {|FixAllInDocument:x|}(); } } - """); - } + } + """, + """ + class C + { + System.Action a; + + void Goo() + { + a?.Invoke(); + a?.Invoke(); + } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/Iterator/AddYieldTests.cs b/src/Analyzers/CSharp/Tests/Iterator/AddYieldTests.cs index e1758a8960543..2ada179cf9b67 100644 --- a/src/Analyzers/CSharp/Tests/Iterator/AddYieldTests.cs +++ b/src/Analyzers/CSharp/Tests/Iterator/AddYieldTests.cs @@ -9,436 +9,435 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.Iterator +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.Iterator; + +using VerifyCS = CSharpCodeFixVerifier; + +[Trait(Traits.Feature, Traits.Features.CodeActionsChangeToYield)] +public class AddYieldTests { - using VerifyCS = CSharpCodeFixVerifier; + private static async Task TestMissingInRegularAndScriptAsync(string code) + { + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsChangeToYield)] - public class AddYieldTests + private static async Task TestInRegularAndScriptAsync(string code, string fixedCode) { - private static async Task TestMissingInRegularAndScriptAsync(string code) - { - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - private static async Task TestInRegularAndScriptAsync(string code, string fixedCode) - { - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } - - [Fact] - public async Task TestAddYieldIEnumerableReturnNull() - { - var initial = - """ - using System; - using System.Collections; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - class Program + [Fact] + public async Task TestAddYieldIEnumerableReturnNull() + { + var initial = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - return null; - } + return null; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestAddYieldIEnumerableReturnObject() - { - var initial = - """ - using System; - using System.Collections; + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } - class Program + [Fact] + public async Task TestAddYieldIEnumerableReturnObject() + { + var initial = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - return {|CS0266:new object()|}; - } + return {|CS0266:new object()|}; } - """; - var expected = - """ - using System; - using System.Collections; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - yield return new object(); - } + yield return new object(); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldIEnumeratorReturnObject() - { - var initial = - """ - using System; - using System.Collections; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldIEnumeratorReturnObject() + { + var initial = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - return {|CS0266:new object()|}; - } + return {|CS0266:new object()|}; } - """; - var expected = - """ - using System; - using System.Collections; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - yield return new object(); - } + yield return new object(); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldIEnumeratorReturnGenericList() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldIEnumeratorReturnGenericList() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - return {|CS0266:new List()|}; - } + return {|CS0266:new List()|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - yield return new List(); - } + yield return new List(); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldGenericIEnumeratorReturnObject() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumeratorReturnObject() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - return {|CS0266:new object()|}; - } + return {|CS0266:new object()|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - yield return new object(); - } + yield return new object(); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldGenericIEnumerableReturnObject() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumerableReturnObject() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - return {|CS0266:new object()|}; - } + return {|CS0266:new object()|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - yield return new object(); - } + yield return new object(); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldIEnumerableReturnGenericList() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldIEnumerableReturnGenericList() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - return new List(); - } + return new List(); } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestAddYieldGenericIEnumeratorReturnDefault() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumeratorReturnDefault() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - return {|CS0266:default(T)|}; - } + return {|CS0266:default(T)|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - yield return default(T); - } + yield return default(T); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldGenericIEnumerableReturnConvertibleToObject() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumerableReturnConvertibleToObject() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - return {|CS0029:0|}; - } + return {|CS0029:0|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - yield return 0; - } + yield return 0; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldGenericIEnumerableReturnConvertibleToFloat() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumerableReturnConvertibleToFloat() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - return {|CS0029:0|}; - } + return {|CS0029:0|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator M() { - static IEnumerator M() - { - yield return 0; - } + yield return 0; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldGenericIEnumeratorNonConvertableType() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumeratorNonConvertableType() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator> M() { - static IEnumerator> M() - { - return {|CS0266:new List()|}; - } + return {|CS0266:new List()|}; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestAddYieldGenericIEnumeratorConvertableTypeDateTime() - { - var initial = - """ - using System; - using System.Collections; - using System.Collections.Generic; + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } - class Program + [Fact] + public async Task TestAddYieldGenericIEnumeratorConvertableTypeDateTime() + { + var initial = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator> M() { - static IEnumerator> M() - { - return {|CS0266:new List()|}; - } + return {|CS0266:new List()|}; } - """; - var expected = - """ - using System; - using System.Collections; - using System.Collections.Generic; - - class Program + } + """; + var expected = + """ + using System; + using System.Collections; + using System.Collections.Generic; + + class Program + { + static IEnumerator> M() { - static IEnumerator> M() - { - yield return new List(); - } + yield return new List(); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestAddYieldNoTypeArguments() - { - var initial = - """ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Text; - using System.Threading.Tasks; - - namespace ConsoleApplication13 + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } + + [Fact] + public async Task TestAddYieldNoTypeArguments() + { + var initial = + """ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + namespace ConsoleApplication13 + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - var d = new A.B.C.D(); - } + var d = new A.B.C.D(); } } + } + + #pragma warning disable CS0108 + public class A where Z : new() + { + public virtual Z P1 { get { return new Z(); } } - #pragma warning disable CS0108 - public class A where Z : new() + public class B : A> where Y : new() { - public virtual Z P1 { get { return new Z(); } } + public override A.B P1 { get; {|CS0546:set|}; } + public virtual Y P2 { get { return {|CS0029:new Z()|}; } } - public class B : A> where Y : new() + public class C : B> where X : new() { - public override A.B P1 { get; {|CS0546:set|}; } - public virtual Y P2 { get { return {|CS0029:new Z()|}; } } + public override A.B>.B.B.C> P1 { get; set; } + public override A.B.C P2 { get; {|CS0546:set|}; } + public virtual X P3 { get; set; } - public class C : B> where X : new() + public class D : C> where W : new() { - public override A.B>.B.B.C> P1 { get; set; } - public override A.B.C P2 { get; {|CS0546:set|}; } - public virtual X P3 { get; set; } - - public class D : C> where W : new() - { - public override A.B>.B.B.C>>.B.B>.B.B.C>.C.B.C.D>> P1 { get; set; } - public override A.B>.B.B.C>.C.B.C.D> P2 { get; set; } - public override A.B.C.D P3 { get; set; } - public virtual W P4 { get; set; } - } + public override A.B>.B.B.C>>.B.B>.B.B.C>.C.B.C.D>> P1 { get; set; } + public override A.B>.B.B.C>.C.B.C.D> P2 { get; set; } + public override A.B.C.D P3 { get; set; } + public virtual W P4 { get; set; } } } } - """; - await TestMissingInRegularAndScriptAsync(initial); - } + } + """; + await TestMissingInRegularAndScriptAsync(initial); } } diff --git a/src/Analyzers/CSharp/Tests/Iterator/ChangeToIEnumerableTests.cs b/src/Analyzers/CSharp/Tests/Iterator/ChangeToIEnumerableTests.cs index d00343c169fac..d4101fe9d3790 100644 --- a/src/Analyzers/CSharp/Tests/Iterator/ChangeToIEnumerableTests.cs +++ b/src/Analyzers/CSharp/Tests/Iterator/ChangeToIEnumerableTests.cs @@ -11,408 +11,407 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.Iterator +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.Iterator; + +[Trait(Traits.Feature, Traits.Features.CodeActionsChangeToIEnumerable)] +public class ChangeToIEnumerableTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsChangeToIEnumerable)] - public class ChangeToIEnumerableTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public ChangeToIEnumerableTests(ITestOutputHelper logger) + : base(logger) { - public ChangeToIEnumerableTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpChangeToIEnumerableCodeFixProvider()); - - [Fact] - public async Task TestChangeToIEnumerableObjectMethod() - { - var initial = - """ - using System; - using System.Collections.Generic; - - class Program + } + + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpChangeToIEnumerableCodeFixProvider()); + + [Fact] + public async Task TestChangeToIEnumerableObjectMethod() + { + var initial = + """ + using System; + using System.Collections.Generic; + + class Program + { + static object [|M|]() { - static object [|M|]() - { - yield return 0; - } + yield return 0; } - """; + } + """; - var expected = - """ - using System; - using System.Collections.Generic; + var expected = + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - yield return 0; - } + yield return 0; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestChangeToIEnumerableTupleMethod() - { - var initial = - """ - using System; - using System.Collections.Generic; - - class Program + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } + + [Fact] + public async Task TestChangeToIEnumerableTupleMethod() + { + var initial = + """ + using System; + using System.Collections.Generic; + + class Program + { + static Tuple [|M|]() { - static Tuple [|M|]() - { - yield return 0; - } + yield return 0; } - """; + } + """; - var expected = - """ - using System; - using System.Collections.Generic; + var expected = + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + static IEnumerable> M() { - static IEnumerable> M() - { - yield return 0; - } + yield return 0; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestChangeToIEnumerableListMethod() - { - var initial = - """ - using System; - using System.Collections.Generic; - - class Program + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } + + [Fact] + public async Task TestChangeToIEnumerableListMethod() + { + var initial = + """ + using System; + using System.Collections.Generic; + + class Program + { + static IList [|M|]() { - static IList [|M|]() - { - yield return 0; - } + yield return 0; } - """; + } + """; - var expected = - """ - using System; - using System.Collections.Generic; + var expected = + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - yield return 0; - } + yield return 0; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task TestChangeToIEnumerableWithListReturningMethodWithNullableArgument() - { - var initial = - """ - #nullable enable + [Fact] + public async Task TestChangeToIEnumerableWithListReturningMethodWithNullableArgument() + { + var initial = + """ + #nullable enable - using System; - using System.Collections.Generic; + using System; + using System.Collections.Generic; - class Program + class Program + { + static IList [|M|]() { - static IList [|M|]() - { - yield return ""; - } + yield return ""; } - """; + } + """; - var expected = - """ - #nullable enable + var expected = + """ + #nullable enable - using System; - using System.Collections.Generic; + using System; + using System.Collections.Generic; - class Program + class Program + { + static IEnumerable M() { - static IEnumerable M() - { - yield return ""; - } + yield return ""; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task TestChangeToIEnumerableGenericIEnumerableMethod() - { - var initial = - """ - using System; - using System.Collections.Generic; - - class Program + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } + + [Fact] + public async Task TestChangeToIEnumerableGenericIEnumerableMethod() + { + var initial = + """ + using System; + using System.Collections.Generic; + + class Program + { + static IEnumerable [|M|]() { - static IEnumerable [|M|]() - { - yield return 0; - } + yield return 0; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestChangeToIEnumerableGenericIEnumeratorMethod() - { - var initial = - """ - using System; - using System.Collections.Generic; - - class Program + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } + + [Fact] + public async Task TestChangeToIEnumerableGenericIEnumeratorMethod() + { + var initial = + """ + using System; + using System.Collections.Generic; + + class Program + { + static IEnumerator [|M|]() { - static IEnumerator [|M|]() - { - yield return 0; - } + yield return 0; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestChangeToIEnumerableIEnumeratorMethod() - { - var initial = - """ - using System; - using System.Collections; - - class Program + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } + + [Fact] + public async Task TestChangeToIEnumerableIEnumeratorMethod() + { + var initial = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerator [|M|]() { - static IEnumerator [|M|]() - { - yield return 0; - } + yield return 0; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestChangeToIEnumerableIEnumerableMethod() - { - var initial = - """ - using System; - using System.Collections; - - class Program + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } + + [Fact] + public async Task TestChangeToIEnumerableIEnumerableMethod() + { + var initial = + """ + using System; + using System.Collections; + + class Program + { + static IEnumerable [|M|]() { - static IEnumerable [|M|]() - { - yield return 0; - } + yield return 0; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact] - public async Task TestChangeToIEnumerableVoidMethod() - { - var initial = - """ - using System; - using System.Collections; - - class Program + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } + + [Fact] + public async Task TestChangeToIEnumerableVoidMethod() + { + var initial = + """ + using System; + using System.Collections; + + class Program + { + static void [|M|]() { - static void [|M|]() - { - yield return 0; - } + yield return 0; } - """; - await TestMissingInRegularAndScriptAsync(initial); - } - - [Fact, WorkItem(7087, @"https://github.com/dotnet/roslyn/issues/7087")] - public async Task TestChangeToIEnumerableProperty() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; - - namespace Asdf + } + """; + await TestMissingInRegularAndScriptAsync(initial); + } + + [Fact, WorkItem(7087, @"https://github.com/dotnet/roslyn/issues/7087")] + public async Task TestChangeToIEnumerableProperty() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + + namespace Asdf + { + public class Test { - public class Test + public ISet Test { - public ISet Test + [|get|] { - [|get|] - { - yield return TestFactory.Create("yada yada yada"); - } ; - } + yield return TestFactory.Create("yada yada yada"); + } ; } + } - public static class TestFactory + public static class TestFactory + { + public static IMyInterface Create(string someIdentifier) { - public static IMyInterface Create(string someIdentifier) - { - return new MyClass(); - } + return new MyClass(); } + } - public interface IMyInterface : IEquatable - { - } + public interface IMyInterface : IEquatable + { + } - public class MyClass : IMyInterface + public class MyClass : IMyInterface + { + public bool Equals(IMyInterface other) { - public bool Equals(IMyInterface other) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """, - """ - using System; - using System.Collections.Generic; - - namespace Asdf + } + """, + """ + using System; + using System.Collections.Generic; + + namespace Asdf + { + public class Test { - public class Test + public IEnumerable Test { - public IEnumerable Test + get { - get - { - yield return TestFactory.Create("yada yada yada"); - } ; - } + yield return TestFactory.Create("yada yada yada"); + } ; } + } - public static class TestFactory + public static class TestFactory + { + public static IMyInterface Create(string someIdentifier) { - public static IMyInterface Create(string someIdentifier) - { - return new MyClass(); - } + return new MyClass(); } + } - public interface IMyInterface : IEquatable - { - } + public interface IMyInterface : IEquatable + { + } - public class MyClass : IMyInterface + public class MyClass : IMyInterface + { + public bool Equals(IMyInterface other) { - public bool Equals(IMyInterface other) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """); - } - - [Fact, WorkItem(7087, @"https://github.com/dotnet/roslyn/issues/7087")] - public async Task TestChangeToIEnumerableOperator() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections; - using System.Collections.Generic; - - namespace Asdf + } + """); + } + + [Fact, WorkItem(7087, @"https://github.com/dotnet/roslyn/issues/7087")] + public async Task TestChangeToIEnumerableOperator() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections; + using System.Collections.Generic; + + namespace Asdf + { + public class T { - public class T + public static ISet operator [|=|] (T left, T right) { - public static ISet operator [|=|] (T left, T right) - { - yield return 0; - } + yield return 0; } } - """, - """ - using System; - using System.Collections; - using System.Collections.Generic; - - namespace Asdf + } + """, + """ + using System; + using System.Collections; + using System.Collections.Generic; + + namespace Asdf + { + public class T { - public class T + public static IEnumerable operator = (T left, T right) { - public static IEnumerable operator = (T left, T right) - { - yield return 0; - } + yield return 0; } } - """); - } - - [Fact, WorkItem(7087, @"https://github.com/dotnet/roslyn/issues/7087")] - public async Task TestChangeToIEnumerableIndexer() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading.Tasks; - - class T + } + """); + } + + [Fact, WorkItem(7087, @"https://github.com/dotnet/roslyn/issues/7087")] + public async Task TestChangeToIEnumerableIndexer() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + class T + { + public T[] this[int i] { - public T[] this[int i] + [|get|] { - [|get|] - { - yield return new T(); - } + yield return new T(); } } - """, - """ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Threading.Tasks; - - class T + } + """, + """ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + + class T + { + public IEnumerable this[int i] { - public IEnumerable this[int i] + get { - get - { - yield return new T(); - } + yield return new T(); } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/MakeFieldReadonly/MakeFieldReadonlyTests.cs b/src/Analyzers/CSharp/Tests/MakeFieldReadonly/MakeFieldReadonlyTests.cs index 980df80b8c730..51d0abd5010cd 100644 --- a/src/Analyzers/CSharp/Tests/MakeFieldReadonly/MakeFieldReadonlyTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeFieldReadonly/MakeFieldReadonlyTests.cs @@ -16,219 +16,219 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeFieldReadonly +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeFieldReadonly; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)] +public class MakeFieldReadonlyTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)] - public class MakeFieldReadonlyTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor - { - private static readonly ParseOptions s_strictFeatureFlag = CSharpParseOptions.Default.WithFeatures([KeyValuePairUtil.Create("strict", "true")]); - - public MakeFieldReadonlyTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpMakeFieldReadonlyDiagnosticAnalyzer(), new CSharpMakeFieldReadonlyCodeFixProvider()); - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateField(string accessibility) - { - await TestMissingInRegularAndScriptAsync( + private static readonly ParseOptions s_strictFeatureFlag = CSharpParseOptions.Default.WithFeatures([KeyValuePairUtil.Create("strict", "true")]); + + public MakeFieldReadonlyTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpMakeFieldReadonlyDiagnosticAnalyzer(), new CSharpMakeFieldReadonlyCodeFixProvider()); + + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateField(string accessibility) + { + await TestMissingInRegularAndScriptAsync( $@"class MyClass {{ {accessibility} int[| _goo |]; }}"); - } + } - [Fact] - public async Task FieldIsEvent() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private event System.EventHandler [|Goo|]; - } - """); - } + [Fact] + public async Task FieldIsEvent() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private event System.EventHandler [|Goo|]; + } + """); + } - [Fact] - public async Task FieldIsReadonly() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private readonly int [|_goo|]; - } - """); - } + [Fact] + public async Task FieldIsReadonly() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private readonly int [|_goo|]; + } + """); + } - [Fact] - public async Task FieldIsConst() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private const int [|_goo|]; - } - """); - } + [Fact] + public async Task FieldIsConst() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private const int [|_goo|]; + } + """); + } - [Fact] - public async Task FieldNotAssigned() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - } - """, - """ - class MyClass - { - private readonly int _goo; - } - """); - } + [Fact] + public async Task FieldNotAssigned() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + } + """, + """ + class MyClass + { + private readonly int _goo; + } + """); + } - [Fact] - public async Task FieldNotAssigned_Struct() - { - await TestInRegularAndScript1Async( - """ - struct MyStruct - { - private int [|_goo|]; - } - """, - """ - struct MyStruct - { - private readonly int _goo; - } - """); - } + [Fact] + public async Task FieldNotAssigned_Struct() + { + await TestInRegularAndScript1Async( + """ + struct MyStruct + { + private int [|_goo|]; + } + """, + """ + struct MyStruct + { + private readonly int _goo; + } + """); + } - [Fact] - public async Task FieldAssignedInline() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|] = 0; - } - """, - """ - class MyClass - { - private readonly int _goo = 0; - } - """); - } + [Fact] + public async Task FieldAssignedInline() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|] = 0; + } + """, + """ + class MyClass + { + private readonly int _goo = 0; + } + """); + } - [Fact] - public async Task MultipleFieldsAssignedInline_AllCanBeReadonly() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|] = 0, _bar = 0; - } - """, - """ - class MyClass - { - private readonly int _goo = 0; - private int _bar = 0; - } - """); - } + [Fact] + public async Task MultipleFieldsAssignedInline_AllCanBeReadonly() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|] = 0, _bar = 0; + } + """, + """ + class MyClass + { + private readonly int _goo = 0; + private int _bar = 0; + } + """); + } - [Fact] - public async Task ThreeFieldsAssignedInline_AllCanBeReadonly_SeparatesAllAndKeepsThemInOrder() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int _goo = 0, [|_bar|] = 0, _fizz = 0; - } - """, - """ - class MyClass + [Fact] + public async Task ThreeFieldsAssignedInline_AllCanBeReadonly_SeparatesAllAndKeepsThemInOrder() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int _goo = 0, [|_bar|] = 0, _fizz = 0; + } + """, + """ + class MyClass + { + private int _goo = 0; + private readonly int _bar = 0; + private int _fizz = 0; + } + """); + } + + [Fact] + public async Task MultipleFieldsAssignedInline_OneIsAssignedInMethod() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int _goo = 0, [|_bar|] = 0; + Goo() { - private int _goo = 0; - private readonly int _bar = 0; - private int _fizz = 0; + _goo = 0; } - """); - } + } + """, + """ + class MyClass + { + private int _goo = 0; + private readonly int _bar = 0; - [Fact] - public async Task MultipleFieldsAssignedInline_OneIsAssignedInMethod() - { - await TestInRegularAndScript1Async( - """ - class MyClass + Goo() { - private int _goo = 0, [|_bar|] = 0; - Goo() - { - _goo = 0; - } + _goo = 0; } - """, - """ - class MyClass - { - private int _goo = 0; - private readonly int _bar = 0; + } + """); + } - Goo() - { - _goo = 0; - } - } - """); - } + [Fact] + public async Task MultipleFieldsAssignedInline_NoInitializer() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|], _bar = 0; + } + """, + """ + class MyClass + { + private readonly int _goo; + private int _bar = 0; + } + """); + } - [Fact] - public async Task MultipleFieldsAssignedInline_NoInitializer() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|], _bar = 0; - } - """, - """ - class MyClass - { - private readonly int _goo; - private int _bar = 0; - } - """); - } - - [Theory] - [InlineData("")] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task MultipleFieldsAssignedInline_LeadingCommentAndWhitespace(string leadingTrvia) - { - await TestInRegularAndScript1Async( + [Theory] + [InlineData("")] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task MultipleFieldsAssignedInline_LeadingCommentAndWhitespace(string leadingTrvia) + { + await TestInRegularAndScript1Async( $@"class MyClass {{ //Comment{leadingTrvia} @@ -240,2032 +240,2031 @@ await TestInRegularAndScript1Async( private int _goo = 0; private readonly int _bar = 0; }}"); - } + } - [Fact] - public async Task FieldAssignedInCtor() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - MyClass() - { - _goo = 0; - } - } - """, - """ - class MyClass - { - private readonly int _goo; - MyClass() - { - _goo = 0; - } - } - """); - } + [Fact] + public async Task FieldAssignedInCtor() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + MyClass() + { + _goo = 0; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + MyClass() + { + _goo = 0; + } + } + """); + } - [Fact] - public async Task FieldAssignedInSimpleLambdaInCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - public class MyClass + [Fact] + public async Task FieldAssignedInSimpleLambdaInCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + public class MyClass + { + private int [|_goo|]; + public MyClass() { - private int [|_goo|]; - public MyClass() - { - this.E = x => this._goo = 0; - } - - public Action E; + this.E = x => this._goo = 0; } - """); - } - - [Fact] - public async Task FieldAssignedInLambdaInCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - public class MyClass - { - private int [|_goo|]; - public MyClass() - { - this.E += (_, __) => this._goo = 0; - } - public event EventHandler E; - } - """); - } + public Action E; + } + """); + } - [Fact] - public async Task FieldAssignedInLambdaWithBlockInCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - public class MyClass + [Fact] + public async Task FieldAssignedInLambdaInCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + public class MyClass + { + private int [|_goo|]; + public MyClass() { - private int [|_goo|]; - public MyClass() - { - this.E += (_, __) => { this._goo = 0; } - } - - public event EventHandler E; + this.E += (_, __) => this._goo = 0; } - """); - } - - [Fact] - public async Task FieldAssignedInAnonymousFunctionInCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - public class MyClass - { - private int [|_goo|]; - public MyClass() - { - this.E = delegate { this._goo = 0; }; - } - public Action E; - } - """); - } + public event EventHandler E; + } + """); + } - [Fact] - public async Task FieldAssignedInLocalFunctionExpressionBodyInCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - public class MyClass + [Fact] + public async Task FieldAssignedInLambdaWithBlockInCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + public class MyClass + { + private int [|_goo|]; + public MyClass() { - private int [|_goo|]; - public MyClass() - { - void LocalFunction() => this._goo = 0; - } + this.E += (_, __) => { this._goo = 0; } } - """); - } - [Fact] - public async Task FieldAssignedInLocalFunctionBlockBodyInCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - public class MyClass - { - private int [|_goo|]; - public MyClass() - { - void LocalFunction() { this._goo = 0; } - } - } - """); - } + public event EventHandler E; + } + """); + } - [Fact] - public async Task FieldAssignedInCtor_DifferentInstance() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass + [Fact] + public async Task FieldAssignedInAnonymousFunctionInCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + public class MyClass + { + private int [|_goo|]; + public MyClass() { - private int [|_goo|]; - MyClass() - { - var goo = new MyClass(); - goo._goo = 0; - } + this.E = delegate { this._goo = 0; }; } - """); - } - [Fact] - public async Task FieldAssignedInCtor_DifferentInstance_ObjectInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - MyClass() - { - var goo = new MyClass { _goo = 0 }; - } - } - """); - } + public Action E; + } + """); + } - [Fact] - public async Task FieldAssignedInCtor_QualifiedWithThis() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - MyClass() - { - this._goo = 0; - } - } - """, - """ - class MyClass + [Fact] + public async Task FieldAssignedInLocalFunctionExpressionBodyInCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + public class MyClass + { + private int [|_goo|]; + public MyClass() { - private readonly int _goo; - MyClass() - { - this._goo = 0; - } + void LocalFunction() => this._goo = 0; } - """); - } + } + """); + } - [Fact] - public async Task FieldReturnedInProperty() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - int Goo - { - get { return _goo; } - } - } - """, - """ - class MyClass + [Fact] + public async Task FieldAssignedInLocalFunctionBlockBodyInCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + public class MyClass + { + private int [|_goo|]; + public MyClass() { - private readonly int _goo; - int Goo - { - get { return _goo; } - } + void LocalFunction() { this._goo = 0; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29746")] - public async Task FieldReturnedInMethod() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private string [|_s|]; - public MyClass(string s) => _s = s; - public string Method() - { - return _s; - } - } - """, - """ - class MyClass - { - private readonly string [|_s|]; - public MyClass(string s) => _s = s; - public string Method() - { - return _s; - } - } - """); - } + [Fact] + public async Task FieldAssignedInCtor_DifferentInstance() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + MyClass() + { + var goo = new MyClass(); + goo._goo = 0; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29746")] - public async Task FieldReadInMethod() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private string [|_s|]; - public MyClass(string s) => _s = s; - public string Method() - { - return _s.ToUpper(); - } - } - """, - """ - class MyClass + [Fact] + public async Task FieldAssignedInCtor_DifferentInstance_ObjectInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + MyClass() { - private readonly string [|_s|]; - public MyClass(string s) => _s = s; - public string Method() - { - return _s.ToUpper(); - } + var goo = new MyClass { _goo = 0 }; } - """); - } + } + """); + } - [Fact] - public async Task FieldAssignedInProperty() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - int Goo - { - get { return _goo; } - set { _goo = value; } - } - } - """); - } + [Fact] + public async Task FieldAssignedInCtor_QualifiedWithThis() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + MyClass() + { + this._goo = 0; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + MyClass() + { + this._goo = 0; + } + } + """); + } - [Fact] - public async Task FieldAssignedInMethod() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - int Goo() - { - _goo = 0; - } - } - """); - } + [Fact] + public async Task FieldReturnedInProperty() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + int Goo + { + get { return _goo; } + } + } + """, + """ + class MyClass + { + private readonly int _goo; + int Goo + { + get { return _goo; } + } + } + """); + } - [Fact] - public async Task FieldAssignedInNestedTypeConstructor() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29746")] + public async Task FieldReturnedInMethod() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private string [|_s|]; + public MyClass(string s) => _s = s; + public string Method() + { + return _s; + } + } + """, + """ + class MyClass + { + private readonly string [|_s|]; + public MyClass(string s) => _s = s; + public string Method() + { + return _s; + } + } + """); + } - class Derived : MyClass - { - Derived() - { - _goo = 1; - } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29746")] + public async Task FieldReadInMethod() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private string [|_s|]; + public MyClass(string s) => _s = s; + public string Method() + { + return _s.ToUpper(); + } + } + """, + """ + class MyClass + { + private readonly string [|_s|]; + public MyClass(string s) => _s = s; + public string Method() + { + return _s.ToUpper(); + } + } + """); + } - [Fact] - public async Task FieldAssignedInNestedTypeMethod() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; + [Fact] + public async Task FieldAssignedInProperty() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + int Goo + { + get { return _goo; } + set { _goo = value; } + } + } + """); + } - class Derived : MyClass - { - void Method() - { - _goo = 1; - } - } + [Fact] + public async Task FieldAssignedInMethod() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + int Goo() + { + _goo = 0; } - """); - } + } + """); + } - [Fact] - public async Task FieldInNestedTypeAssignedInConstructor() - { - await TestInRegularAndScript1Async( - """ - class MyClass + [Fact] + public async Task FieldAssignedInNestedTypeConstructor() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + + class Derived : MyClass { - class NestedType + Derived() { - private int [|_goo|]; - - public NestedType() - { - _goo = 0; - } + _goo = 1; } } - """, - """ - class MyClass + } + """); + } + + [Fact] + public async Task FieldAssignedInNestedTypeMethod() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + + class Derived : MyClass { - class NestedType + void Method() { - private readonly int _goo; - - public NestedType() - { - _goo = 0; - } + _goo = 1; } } - """); - } + } + """); + } - [Fact] - public async Task VariableAssignedToFieldInMethod() - { - await TestInRegularAndScript1Async( - """ - class MyClass + [Fact] + public async Task FieldInNestedTypeAssignedInConstructor() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + class NestedType { private int [|_goo|]; - int Goo() + + public NestedType() { - var i = _goo; + _goo = 0; } } - """, - """ - class MyClass + } + """, + """ + class MyClass + { + class NestedType { private readonly int _goo; - int Goo() - { - var i = _goo; - } - } - """); - } - [Fact] - public async Task FieldAssignedInMethodWithCompoundOperator() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|] = 0; - int Goo(int value) + public NestedType() { - _goo += value; + _goo = 0; } } - """); - } + } + """); + } + + [Fact] + public async Task VariableAssignedToFieldInMethod() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + int Goo() + { + var i = _goo; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + int Goo() + { + var i = _goo; + } + } + """); + } - [Fact] - public async Task FieldUsedWithPostfixIncrement() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass + [Fact] + public async Task FieldAssignedInMethodWithCompoundOperator() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|] = 0; + int Goo(int value) { - private int [|_goo|] = 0; - int Goo(int value) - { - _goo++; - } + _goo += value; } - """); - } + } + """); + } - [Fact] - public async Task FieldUsedWithPrefixDecrement() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass + [Fact] + public async Task FieldUsedWithPostfixIncrement() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|] = 0; + int Goo(int value) { - private int [|_goo|] = 0; - int Goo(int value) - { - --_goo; - } + _goo++; } - """); - } + } + """); + } - [Fact] - public async Task NotAssignedInPartialClass1() - { - await TestInRegularAndScript1Async( - """ - partial class MyClass + [Fact] + public async Task FieldUsedWithPrefixDecrement() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|] = 0; + int Goo(int value) { - private int [|_goo|]; + --_goo; } - """, - """ - partial class MyClass + } + """); + } + + [Fact] + public async Task NotAssignedInPartialClass1() + { + await TestInRegularAndScript1Async( + """ + partial class MyClass + { + private int [|_goo|]; + } + """, + """ + partial class MyClass + { + private readonly int _goo; + } + """); + } + + [Fact] + public async Task NotAssignedInPartialClass2() + { + await TestInRegularAndScript1Async( + """ + partial class MyClass + { + private int [|_goo|]; + } + partial class MyClass + { + } + """, + """ + partial class MyClass + { + private readonly int _goo; + } + partial class MyClass + { + } + """); + } + + [Fact] + public async Task NotAssignedInPartialClass3() + { + await TestInRegularAndScript1Async( + """ + + + partial class MyClass + { + private int [|_goo|]; + } + + partial class MyClass + { + void M() + { + } + } + + + + """, + """ + + + partial class MyClass + { + private readonly int _goo; + } + + partial class MyClass + { + void M() + { + } + } + + + + """); + } + + [Fact] + public async Task AssignedInPartialClass1() + { + await TestMissingInRegularAndScriptAsync( + """ + partial class MyClass + { + private int [|_goo|]; + + void SetGoo() { - private readonly int _goo; + _goo = 0; } - """); - } + } + """); + } + + [Fact] + public async Task AssignedInPartialClass2() + { + await TestMissingInRegularAndScriptAsync( + """ + partial class MyClass + { + private int [|_goo|]; + } + partial class MyClass + { + void SetGoo() + { + _goo = 0; + } + } + """); + } + + [Fact] + public async Task AssignedInPartialClass3() + { + await TestMissingInRegularAndScriptAsync( + """ + + + partial class MyClass + { + private int [|_goo|]; + } + + partial class MyClass + { + void SetGoo() + { + _goo = 0; + } + } + + + + """); + } - [Fact] - public async Task NotAssignedInPartialClass2() - { - await TestInRegularAndScript1Async( - """ - partial class MyClass + [Fact] + public async Task PassedAsParameter() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + void Goo() { - private int [|_goo|]; + Bar(_goo); } - partial class MyClass + void Bar(int goo) { } - """, - """ - partial class MyClass + } + """, + """ + class MyClass + { + private readonly int _goo; + void Goo() { - private readonly int _goo; + Bar(_goo); } - partial class MyClass - { - } - """); - } - - [Fact] - public async Task NotAssignedInPartialClass3() - { - await TestInRegularAndScript1Async( - """ - - - partial class MyClass - { - private int [|_goo|]; - } - - partial class MyClass - { - void M() - { - } - } - - - - """, - """ - - - partial class MyClass - { - private readonly int _goo; - } - - partial class MyClass - { - void M() - { - } - } - - - - """); - } - - [Fact] - public async Task AssignedInPartialClass1() - { - await TestMissingInRegularAndScriptAsync( - """ - partial class MyClass - { - private int [|_goo|]; - - void SetGoo() - { - _goo = 0; - } - } - """); - } - - [Fact] - public async Task AssignedInPartialClass2() - { - await TestMissingInRegularAndScriptAsync( - """ - partial class MyClass - { - private int [|_goo|]; - } - partial class MyClass - { - void SetGoo() - { - _goo = 0; - } - } - """); - } - - [Fact] - public async Task AssignedInPartialClass3() - { - await TestMissingInRegularAndScriptAsync( - """ - - - partial class MyClass - { - private int [|_goo|]; - } - - partial class MyClass - { - void SetGoo() - { - _goo = 0; - } - } - - - - """); - } - - [Fact] - public async Task PassedAsParameter() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - void Goo() - { - Bar(_goo); - } - void Bar(int goo) - { - } - } - """, - """ - class MyClass - { - private readonly int _goo; - void Goo() - { - Bar(_goo); - } - void Bar(int goo) - { - } - } - """); - } - - [Fact] - public async Task PassedAsOutParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - void Goo() - { - int.TryParse("123", out _goo); - } - } - """); - } - - [Fact] - public async Task PassedAsRefParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - void Goo() - { - Bar(ref _goo); - } - void Bar(ref int goo) - { - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef1() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - internal ref int Goo() - { - return ref _goo; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef2() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - internal ref int Goo() - => ref _goo; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef3() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - internal struct Accessor - { - private MyClass _instance; - internal ref int Goo => ref _instance._goo; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef4() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_a|]; - private int _b; - internal ref int Goo(bool first) - { - return ref (first ? ref _a : ref _b); - } - } - """); - - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int _a; - private int [|_b|]; - internal ref int Goo(bool first) - { - return ref (first ? ref _a : ref _b); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef5() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_a|]; - private int _b; - internal ref int Goo(bool first) - => ref (first ? ref _a : ref _b); - } - """); - - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int _a; - private int [|_b|]; - internal ref int Goo(bool first) - => ref (first ? ref _a : ref _b); - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef6() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private int [|_goo|]; - internal int Goo() - { - return Local(); - - ref int Local() - { - return ref _goo; - } - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef7() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - delegate ref int D(); - - private int [|_goo|]; - internal int Goo() - { - D d = () => ref _goo; - - return d(); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRef8() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - delegate ref int D(); - - private int [|_goo|]; - internal int Goo() - { - D d = delegate { return ref _goo; }; - - return d(); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly1() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - internal ref readonly int Goo() - { - return ref _goo; - } - } - """, - """ - class MyClass - { - private readonly int _goo; - internal ref readonly int Goo() - { - return ref _goo; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly2() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - internal ref readonly int Goo() - => ref _goo; - } - """, - """ - class MyClass - { - private readonly int _goo; - internal ref readonly int Goo() - => ref _goo; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly3() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - internal struct Accessor - { - private MyClass _instance; - internal ref readonly int Goo => ref _instance._goo; - } - } - """, - """ - class MyClass - { - private readonly int _goo; - internal struct Accessor - { - private MyClass _instance; - internal ref readonly int Goo => ref _instance._goo; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly4() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_a|]; - private int _b; - internal ref readonly int Goo(bool first) - { - return ref (first ? ref _a : ref _b); - } - } - """, - """ - class MyClass - { - private readonly int _a; - private int _b; - internal ref readonly int Goo(bool first) - { - return ref (first ? ref _a : ref _b); - } - } - """); - - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int _a; - private int [|_b|]; - internal ref readonly int Goo(bool first) - { - return ref (first ? ref _a : ref _b); - } - } - """, - """ - class MyClass - { - private int _a; - private readonly int _b; - internal ref readonly int Goo(bool first) - { - return ref (first ? ref _a : ref _b); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly5() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_a|]; - private int _b; - internal ref readonly int Goo(bool first) - => ref (first ? ref _a : ref _b); - } - """, - """ - class MyClass - { - private readonly int _a; - private int _b; - internal ref readonly int Goo(bool first) - => ref (first ? ref _a : ref _b); - } - """); - - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int _a; - private int [|_b|]; - internal ref readonly int Goo(bool first) - => ref (first ? ref _a : ref _b); - } - """, - """ - class MyClass - { - private int _a; - private readonly int _b; - internal ref readonly int Goo(bool first) - => ref (first ? ref _a : ref _b); - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly6() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - internal int Goo() - { - return Local(); - - ref readonly int Local() - { - return ref _goo; - } - } - } - """, - """ - class MyClass - { - private readonly int _goo; - internal int Goo() - { - return Local(); - - ref readonly int Local() - { - return ref _goo; - } - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly7() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - delegate ref readonly int D(); - - private int [|_goo|]; - internal int Goo() - { - D d = () => ref _goo; - - return d(); - } - } - """, - """ - class MyClass - { - delegate ref readonly int D(); - - private readonly int _goo; - internal int Goo() - { - D d = () => ref _goo; - - return d(); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ReturnedByRefReadonly8() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - delegate ref readonly int D(); - - private int [|_goo|]; - internal int Goo() - { - D d = delegate { return ref _goo; }; - - return d(); - } - } - """, - """ - class MyClass - { - delegate ref readonly int D(); - - private readonly int _goo; - internal int Goo() - { - D d = delegate { return ref _goo; }; - - return d(); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ConditionOfRefConditional1() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private bool [|_a|]; - private int _b; - internal ref int Goo() - { - return ref (_a ? ref _b : ref _b); - } - } - """, - """ - class MyClass - { - private readonly bool _a; - private int _b; - internal ref int Goo() - { - return ref (_a ? ref _b : ref _b); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] - public async Task ConditionOfRefConditional2() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private bool [|_a|]; - private int _b; - internal ref int Goo() - => ref (_a ? ref _b : ref _b); - } - """, - """ - class MyClass - { - private readonly bool _a; - private int _b; - internal ref int Goo() - => ref (_a ? ref _b : ref _b); - } - """); - } - - [Fact] - public async Task PassedAsOutParameterInCtor() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - MyClass() - { - int.TryParse("123", out _goo); - } - } - """, - """ - class MyClass - { - private readonly int _goo; - MyClass() - { - int.TryParse("123", out _goo); - } - } - """); - } - - [Fact] - public async Task PassedAsRefParameterInCtor() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int [|_goo|]; - MyClass() - { - Bar(ref _goo); - } - void Bar(ref int goo) - { - } - } - """, - """ - class MyClass - { - private readonly int _goo; - MyClass() - { - Bar(ref _goo); - } - void Bar(ref int goo) - { - } - } - """); - } - - [Fact] - public async Task StaticFieldAssignedInStaticCtor() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private static int [|_goo|]; - static MyClass() - { - _goo = 0; - } - } - """, - """ - class MyClass - { - private static readonly int _goo; - static MyClass() - { - _goo = 0; - } - } - """); - } - - [Fact] - public async Task StaticFieldAssignedInNonStaticCtor() - { - await TestMissingInRegularAndScriptAsync( - """ - class MyClass - { - private static int [|_goo|]; - MyClass() - { - _goo = 0; - } - } - """); - } - - [Fact] - public async Task FieldTypeIsMutableStruct() - { - await TestMissingInRegularAndScriptAsync( - """ - struct MyStruct - { - private int _goo; - } - class MyClass - { - private MyStruct [|_goo|]; - } - """); - } - - [Fact] - public async Task FieldTypeIsCustomImmutableStruct() - { - await TestInRegularAndScript1Async( - """ - struct MyStruct - { - private readonly int _goo; - private const int _bar = 0; - private static int _fizz; - } - class MyClass - { - private MyStruct [|_goo|]; - } - """, - """ - struct MyStruct - { - private readonly int _goo; - private const int _bar = 0; - private static int _fizz; - } - class MyClass - { - private readonly MyStruct _goo; - } - """); - } - - [Fact] - public async Task FixAll() - { - await TestInRegularAndScript1Async( - """ - class MyClass - { - private int {|FixAllInDocument:_goo|} = 0, _bar = 0; - private int _x = 0, _y = 0, _z = 0; - private int _fizz = 0; - - void Method() { _z = 1; } - } - """, - """ - class MyClass - { - private readonly int _goo = 0, _bar = 0; - private readonly int _x = 0; - private readonly int _y = 0; - private int _z = 0; - private readonly int _fizz = 0; - - void Method() { _z = 1; } - } - """); - } - - [Fact] - public async Task FixAll2() - { - await TestInRegularAndScript1Async( - """ - using System; - - partial struct MyClass - { - private static Func {|FixAllInDocument:_test1|} = x => x > 0; - private static Func _test2 = x => x < 0; - - private static Func _test3 = x => - { - return x == 0; - }; - - private static Func _test4 = x => - { - return x != 0; - }; - } - - partial struct MyClass { } - """, - """ - using System; - - partial struct MyClass - { - private static readonly Func _test1 = x => x > 0; - private static readonly Func _test2 = x => x < 0; - - private static readonly Func _test3 = x => - { - return x == 0; - }; - - private static readonly Func _test4 = x => - { - return x != 0; - }; - } - - partial struct MyClass { } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26262")] - public async Task FieldAssignedInCtor_InParens() - { - await TestInRegularAndScript1Async( - """ - class MyClass + void Bar(int goo) { - private int [|_goo|]; - MyClass() - { - (_goo) = 0; - } } - """, - """ - class MyClass + } + """); + } + + [Fact] + public async Task PassedAsOutParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + void Goo() { - private readonly int _goo; - MyClass() - { - (_goo) = 0; - } + int.TryParse("123", out _goo); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26262")] - public async Task FieldAssignedInCtor_QualifiedWithThis_InParens() - { - await TestInRegularAndScript1Async( - """ - class MyClass + [Fact] + public async Task PassedAsRefParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + void Goo() { - private int [|_goo|]; - MyClass() - { - (this._goo) = 0; - } + Bar(ref _goo); } - """, - """ - class MyClass + void Bar(ref int goo) { - private readonly int _goo; - MyClass() - { - (this._goo) = 0; - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] - public async Task FieldAssignedInMethod_InDeconstruction() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef1() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + internal ref int Goo() { - [|int i;|] - int j; - - void M() - { - (i, j) = (1, 2); - } + return ref _goo; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] - public async Task FieldAssignedInMethod_InDeconstruction_InParens() - { - await TestMissingAsync( - """ - class C - { - [|int i;|] - int j; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef2() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + internal ref int Goo() + => ref _goo; + } + """); + } - void M() - { - ((i, j), j) = ((1, 2), 3); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef3() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + internal struct Accessor + { + private MyClass _instance; + internal ref int Goo => ref _instance._goo; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] - public async Task FieldAssignedInMethod_InDeconstruction_WithThis_InParens() - { - await TestMissingAsync( - """ - class C - { - [|int i;|] - int j; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef4() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_a|]; + private int _b; + internal ref int Goo(bool first) + { + return ref (first ? ref _a : ref _b); + } + } + """); + + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int _a; + private int [|_b|]; + internal ref int Goo(bool first) + { + return ref (first ? ref _a : ref _b); + } + } + """); + } - void M() - { - ((this.i, j), j) = (1, 2); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef5() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_a|]; + private int _b; + internal ref int Goo(bool first) + => ref (first ? ref _a : ref _b); + } + """); + + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int _a; + private int [|_b|]; + internal ref int Goo(bool first) + => ref (first ? ref _a : ref _b); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] - public async Task FieldUsedInTupleExpressionOnRight() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef6() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private int [|_goo|]; + internal int Goo() { - [|int i;|] - int j; + return Local(); - void M() + ref int Local() { - (j, j) = (i, i); + return ref _goo; } } - """, - """ - class C + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef7() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + delegate ref int D(); + + private int [|_goo|]; + internal int Goo() { - readonly int i; - int j; + D d = () => ref _goo; - void M() - { - (j, j) = (i, i); - } + return d(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] - public async Task FieldInTypeWithGeneratedCode() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|private int i;|] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRef8() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + delegate ref int D(); - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - private int j; + private int [|_goo|]; + internal int Goo() + { + D d = delegate { return ref _goo; }; - void M() - { - } + return d(); } - """, - """ - class C - { - private readonly int i; + } + """); + } - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - private int j; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly1() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + internal ref readonly int Goo() + { + return ref _goo; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + internal ref readonly int Goo() + { + return ref _goo; + } + } + """); + } - void M() - { - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly2() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + internal ref readonly int Goo() + => ref _goo; + } + """, + """ + class MyClass + { + private readonly int _goo; + internal ref readonly int Goo() + => ref _goo; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26364")] - public async Task FieldIsFixed() - { - await TestMissingInRegularAndScriptAsync( - """ - unsafe struct S - { - [|private fixed byte b[8];|] - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly3() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + internal struct Accessor + { + private MyClass _instance; + internal ref readonly int Goo => ref _instance._goo; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + internal struct Accessor + { + private MyClass _instance; + internal ref readonly int Goo => ref _instance._goo; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38995")] - public async Task FieldAssignedToLocalRef() - { - await TestMissingAsync( - """ - class Program - { - [|int i;|] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly4() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_a|]; + private int _b; + internal ref readonly int Goo(bool first) + { + return ref (first ? ref _a : ref _b); + } + } + """, + """ + class MyClass + { + private readonly int _a; + private int _b; + internal ref readonly int Goo(bool first) + { + return ref (first ? ref _a : ref _b); + } + } + """); + + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int _a; + private int [|_b|]; + internal ref readonly int Goo(bool first) + { + return ref (first ? ref _a : ref _b); + } + } + """, + """ + class MyClass + { + private int _a; + private readonly int _b; + internal ref readonly int Goo(bool first) + { + return ref (first ? ref _a : ref _b); + } + } + """); + } - void M() - { - ref var value = ref i; - value += 1; - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly5() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_a|]; + private int _b; + internal ref readonly int Goo(bool first) + => ref (first ? ref _a : ref _b); + } + """, + """ + class MyClass + { + private readonly int _a; + private int _b; + internal ref readonly int Goo(bool first) + => ref (first ? ref _a : ref _b); + } + """); + + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int _a; + private int [|_b|]; + internal ref readonly int Goo(bool first) + => ref (first ? ref _a : ref _b); + } + """, + """ + class MyClass + { + private int _a; + private readonly int _b; + internal ref readonly int Goo(bool first) + => ref (first ? ref _a : ref _b); + } + """); + } - [Fact] - public async Task FieldAssignedToLocalReadOnlyRef() - { - await TestInRegularAndScript1Async( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly6() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + internal int Goo() { - [|int i;|] + return Local(); - void M() + ref readonly int Local() { - ref readonly var value = ref i; + return ref _goo; } } - """, - """ - class Program + } + """, + """ + class MyClass + { + private readonly int _goo; + internal int Goo() { - [|readonly int i;|] + return Local(); - void M() + ref readonly int Local() { - ref readonly var value = ref i; + return ref _goo; } } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly7() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + delegate ref readonly int D(); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26213")] - public async Task TestFieldAccessesOnLeftOfDot() - { - await TestInRegularAndScript1Async( - """ - interface IFaceServiceClient + private int [|_goo|]; + internal int Goo() { - void DetectAsync(); + D d = () => ref _goo; + + return d(); } + } + """, + """ + class MyClass + { + delegate ref readonly int D(); - public class Repro + private readonly int _goo; + internal int Goo() { - private static IFaceServiceClient [|faceServiceClient|] = null; + D d = () => ref _goo; - public static void Run() - { - faceServiceClient.DetectAsync(); - } + return d(); } - """, - """ - interface IFaceServiceClient + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ReturnedByRefReadonly8() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + delegate ref readonly int D(); + + private int [|_goo|]; + internal int Goo() { - void DetectAsync(); + D d = delegate { return ref _goo; }; + + return d(); } + } + """, + """ + class MyClass + { + delegate ref readonly int D(); - public class Repro + private readonly int _goo; + internal int Goo() { - private static readonly IFaceServiceClient faceServiceClient = null; + D d = delegate { return ref _goo; }; - public static void Run() - { - faceServiceClient.DetectAsync(); - } + return d(); } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ConditionOfRefConditional1() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private bool [|_a|]; + private int _b; + internal ref int Goo() + { + return ref (_a ? ref _b : ref _b); + } + } + """, + """ + class MyClass + { + private readonly bool _a; + private int _b; + internal ref int Goo() + { + return ref (_a ? ref _b : ref _b); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33009")] + public async Task ConditionOfRefConditional2() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private bool [|_a|]; + private int _b; + internal ref int Goo() + => ref (_a ? ref _b : ref _b); + } + """, + """ + class MyClass + { + private readonly bool _a; + private int _b; + internal ref int Goo() + => ref (_a ? ref _b : ref _b); + } + """); + } + + [Fact] + public async Task PassedAsOutParameterInCtor() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + MyClass() + { + int.TryParse("123", out _goo); + } + } + """, + """ + class MyClass + { + private readonly int _goo; + MyClass() + { + int.TryParse("123", out _goo); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42759")] - public async Task TestVolatileField1() - { - await TestInRegularAndScript1Async( - """ - class TestClass + [Fact] + public async Task PassedAsRefParameterInCtor() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + MyClass() { - private volatile object [|first|]; + Bar(ref _goo); } - """, - """ - class TestClass + void Bar(ref int goo) { - private readonly object first; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42759")] - public async Task TestVolatileField2() - { - await TestInRegularAndScript1Async( - """ - class TestClass + } + """, + """ + class MyClass + { + private readonly int _goo; + MyClass() { - private volatile object [|first|], second; + Bar(ref _goo); } - """, - """ - class TestClass + void Bar(ref int goo) { - private readonly object first; - private volatile object second; } - """); - } + } + """); + } + + [Fact] + public async Task StaticFieldAssignedInStaticCtor() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private static int [|_goo|]; + static MyClass() + { + _goo = 0; + } + } + """, + """ + class MyClass + { + private static readonly int _goo; + static MyClass() + { + _goo = 0; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42759")] - public async Task TestVolatileField3() - { - await TestInRegularAndScript1Async( - """ - class TestClass + [Fact] + public async Task StaticFieldAssignedInNonStaticCtor() + { + await TestMissingInRegularAndScriptAsync( + """ + class MyClass + { + private static int [|_goo|]; + MyClass() { - private volatile object first, [|second|]; + _goo = 0; } - """, - """ - class TestClass + } + """); + } + + [Fact] + public async Task FieldTypeIsMutableStruct() + { + await TestMissingInRegularAndScriptAsync( + """ + struct MyStruct + { + private int _goo; + } + class MyClass + { + private MyStruct [|_goo|]; + } + """); + } + + [Fact] + public async Task FieldTypeIsCustomImmutableStruct() + { + await TestInRegularAndScript1Async( + """ + struct MyStruct + { + private readonly int _goo; + private const int _bar = 0; + private static int _fizz; + } + class MyClass + { + private MyStruct [|_goo|]; + } + """, + """ + struct MyStruct + { + private readonly int _goo; + private const int _bar = 0; + private static int _fizz; + } + class MyClass + { + private readonly MyStruct _goo; + } + """); + } + + [Fact] + public async Task FixAll() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int {|FixAllInDocument:_goo|} = 0, _bar = 0; + private int _x = 0, _y = 0, _z = 0; + private int _fizz = 0; + + void Method() { _z = 1; } + } + """, + """ + class MyClass + { + private readonly int _goo = 0, _bar = 0; + private readonly int _x = 0; + private readonly int _y = 0; + private int _z = 0; + private readonly int _fizz = 0; + + void Method() { _z = 1; } + } + """); + } + + [Fact] + public async Task FixAll2() + { + await TestInRegularAndScript1Async( + """ + using System; + + partial struct MyClass + { + private static Func {|FixAllInDocument:_test1|} = x => x > 0; + private static Func _test2 = x => x < 0; + + private static Func _test3 = x => + { + return x == 0; + }; + + private static Func _test4 = x => + { + return x != 0; + }; + } + + partial struct MyClass { } + """, + """ + using System; + + partial struct MyClass + { + private static readonly Func _test1 = x => x > 0; + private static readonly Func _test2 = x => x < 0; + + private static readonly Func _test3 = x => + { + return x == 0; + }; + + private static readonly Func _test4 = x => + { + return x != 0; + }; + } + + partial struct MyClass { } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26262")] + public async Task FieldAssignedInCtor_InParens() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + MyClass() + { + (_goo) = 0; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + MyClass() + { + (_goo) = 0; + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26262")] + public async Task FieldAssignedInCtor_QualifiedWithThis_InParens() + { + await TestInRegularAndScript1Async( + """ + class MyClass + { + private int [|_goo|]; + MyClass() + { + (this._goo) = 0; + } + } + """, + """ + class MyClass + { + private readonly int _goo; + MyClass() + { + (this._goo) = 0; + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] + public async Task FieldAssignedInMethod_InDeconstruction() + { + await TestMissingAsync( + """ + class C + { + [|int i;|] + int j; + + void M() { - private volatile object first; - private readonly object second; + (i, j) = (1, 2); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46785")] - public async Task UsedAsRef_NoDiagnostic() - { - await TestMissingInRegularAndScriptAsync( - """ - public class C - { - private string [|x|] = string.Empty; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] + public async Task FieldAssignedInMethod_InDeconstruction_InParens() + { + await TestMissingAsync( + """ + class C + { + [|int i;|] + int j; - public bool M() - { - ref var myVar = ref x; - return myVar is null; - } + void M() + { + ((i, j), j) = ((1, 2), 3); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57983")] - public async Task UsedAsRef_NoDiagnostic_02() - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Runtime.CompilerServices; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] + public async Task FieldAssignedInMethod_InDeconstruction_WithThis_InParens() + { + await TestMissingAsync( + """ + class C + { + [|int i;|] + int j; - public class Test + void M() { - private ulong [|nextD3D12ComputeFenceValue|]; - - internal void Repro() - { - ref ulong d3D12FenceValue = ref Unsafe.NullRef(); - d3D12FenceValue = ref nextD3D12ComputeFenceValue; - d3D12FenceValue++; - } + ((this.i, j), j) = (1, 2); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42760")] - public async Task WithThreadStaticAttribute_NoDiagnostic() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] + public async Task FieldUsedInTupleExpressionOnRight() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|int i;|] + int j; - class Program + void M() { - [ThreadStatic] - private static object [|t_obj|]; + (j, j) = (i, i); } - """); - } + } + """, + """ + class C + { + readonly int i; + int j; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50925")] - public async Task Test_MemberUsedInGeneratedCode() - { - await TestMissingInRegularAndScriptAsync( - """ - - - - public sealed partial class Test + void M() { - private int [|_value|]; - - public static void M() - => _ = new Test { Value = 1 }; + (j, j) = (i, i); } - - - using System.CodeDom.Compiler; + } + """); + } - [GeneratedCode(null, null)] - public sealed partial class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26264")] + public async Task FieldInTypeWithGeneratedCode() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|private int i;|] + + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + private int j; + + void M() { - public int Value - { - get => _value; - set => _value = value; - } } - - - - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] - public async Task ShouldNotWarnForDataMemberFieldsInDataContractClasses() - { - await TestMissingAsync( - """ - - - - [System.Runtime.Serialization.DataContractAttribute] - public class MyClass - { - [System.Runtime.Serialization.DataMember] - private bool [|isReadOnly|]; - } - - - - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] - public async Task ShouldWarnForDataMemberFieldsInNonDataContractClasses() - { - await TestInRegularAndScript1Async( - """ - - - - public class MyClass - { - [System.Runtime.Serialization.DataMember] - private bool [|isReadOnly|]; - } - - - - """, - """ - - - - public class MyClass - { - [System.Runtime.Serialization.DataMember] - private readonly bool isReadOnly; - } - - - - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] - public async Task ShouldWarnForPrivateNonDataMemberFieldsInDataContractClasses() - { - await TestInRegularAndScript1Async( - """ - - - - [System.Runtime.Serialization.DataContractAttribute] - public class MyClass - { - [System.Runtime.Serialization.DataMember] - private bool isReadOnly; - - private bool [|isReadOnly2|]; - } - - - - """, - """ - - - - [System.Runtime.Serialization.DataContractAttribute] - public class MyClass - { - [System.Runtime.Serialization.DataMember] - private bool isReadOnly; - - private readonly bool isReadOnly2; - } - - - - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] - public async Task ShouldNotWarnForPublicImplicitDataMemberFieldsInDataContractClasses() - { - await TestMissingAsync( - """ - - - - [System.Runtime.Serialization.DataContractAttribute] - public class MyClass - { - public bool [|isReadOnly|]; - } - - - - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59577")] - public async Task TestInStruct() - { - await TestInRegularAndScript1Async( - """ - struct MyClass + } + """, + """ + class C + { + private readonly int i; + + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + private int j; + + void M() { - private int [|_goo|]; } - """, - """ - struct MyClass + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26364")] + public async Task FieldIsFixed() + { + await TestMissingInRegularAndScriptAsync( + """ + unsafe struct S + { + [|private fixed byte b[8];|] + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38995")] + public async Task FieldAssignedToLocalRef() + { + await TestMissingAsync( + """ + class Program + { + [|int i;|] + + void M() { - private readonly int _goo; + ref var value = ref i; + value += 1; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59577")] - public async Task MissingForMemberInStructThatOverwritesThis() - { - await TestMissingAsync( - """ - struct MyClass - { - private int [|_goo|]; + [Fact] + public async Task FieldAssignedToLocalReadOnlyRef() + { + await TestInRegularAndScript1Async( + """ + class Program + { + [|int i;|] - void M() - { - this = default; - } + void M() + { + ref readonly var value = ref i; } - """); - } + } + """, + """ + class Program + { + [|readonly int i;|] - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38468")] - public async Task PreserveLeadingTrivia1() - { - await TestInRegularAndScript1Async( - """ - public class C + void M() { - int x; - - int [|y|]; + ref readonly var value = ref i; } - """, - """ - public class C - { - int x; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26213")] + public async Task TestFieldAccessesOnLeftOfDot() + { + await TestInRegularAndScript1Async( + """ + interface IFaceServiceClient + { + void DetectAsync(); + } - readonly int y; + public class Repro + { + private static IFaceServiceClient [|faceServiceClient|] = null; + + public static void Run() + { + faceServiceClient.DetectAsync(); } - """); - } + } + """, + """ + interface IFaceServiceClient + { + void DetectAsync(); + } - [Fact, WorkItem(47197, "https://github.com/dotnet/roslyn/issues/47197")] - public async Task StrictFeatureFlagAssignment1() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + public class Repro + { + private static readonly IFaceServiceClient faceServiceClient = null; - class C + public static void Run() { - private static IEqualityComparer [|s_value|]; + faceServiceClient.DetectAsync(); + } + } + """); + } - static C() - { - C.s_value = null; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42759")] + public async Task TestVolatileField1() + { + await TestInRegularAndScript1Async( + """ + class TestClass + { + private volatile object [|first|]; + } + """, + """ + class TestClass + { + private readonly object first; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42759")] + public async Task TestVolatileField2() + { + await TestInRegularAndScript1Async( + """ + class TestClass + { + private volatile object [|first|], second; + } + """, + """ + class TestClass + { + private readonly object first; + private volatile object second; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42759")] + public async Task TestVolatileField3() + { + await TestInRegularAndScript1Async( + """ + class TestClass + { + private volatile object first, [|second|]; + } + """, + """ + class TestClass + { + private volatile object first; + private readonly object second; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46785")] + public async Task UsedAsRef_NoDiagnostic() + { + await TestMissingInRegularAndScriptAsync( + """ + public class C + { + private string [|x|] = string.Empty; + + public bool M() + { + ref var myVar = ref x; + return myVar is null; } - """, - """ - using System; - using System.Collections.Generic; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57983")] + public async Task UsedAsRef_NoDiagnostic_02() + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Runtime.CompilerServices; + + public class Test + { + private ulong [|nextD3D12ComputeFenceValue|]; - class C + internal void Repro() { - private static readonly IEqualityComparer s_value; + ref ulong d3D12FenceValue = ref Unsafe.NullRef(); + d3D12FenceValue = ref nextD3D12ComputeFenceValue; + d3D12FenceValue++; + } + } + """); + } - static C() - { - C.s_value = null; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42760")] + public async Task WithThreadStaticAttribute_NoDiagnostic() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class Program + { + [ThreadStatic] + private static object [|t_obj|]; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50925")] + public async Task Test_MemberUsedInGeneratedCode() + { + await TestMissingInRegularAndScriptAsync( + """ + + + + public sealed partial class Test + { + private int [|_value|]; + + public static void M() + => _ = new Test { Value = 1 }; + } + + + using System.CodeDom.Compiler; + + [GeneratedCode(null, null)] + public sealed partial class Test + { + public int Value + { + get => _value; + set => _value = value; + } + } + + + + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] + public async Task ShouldNotWarnForDataMemberFieldsInDataContractClasses() + { + await TestMissingAsync( + """ + + + + [System.Runtime.Serialization.DataContractAttribute] + public class MyClass + { + [System.Runtime.Serialization.DataMember] + private bool [|isReadOnly|]; + } + + + + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] + public async Task ShouldWarnForDataMemberFieldsInNonDataContractClasses() + { + await TestInRegularAndScript1Async( + """ + + + + public class MyClass + { + [System.Runtime.Serialization.DataMember] + private bool [|isReadOnly|]; + } + + + + """, + """ + + + + public class MyClass + { + [System.Runtime.Serialization.DataMember] + private readonly bool isReadOnly; + } + + + + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] + public async Task ShouldWarnForPrivateNonDataMemberFieldsInDataContractClasses() + { + await TestInRegularAndScript1Async( + """ + + + + [System.Runtime.Serialization.DataContractAttribute] + public class MyClass + { + [System.Runtime.Serialization.DataMember] + private bool isReadOnly; + + private bool [|isReadOnly2|]; + } + + + + """, + """ + + + + [System.Runtime.Serialization.DataContractAttribute] + public class MyClass + { + [System.Runtime.Serialization.DataMember] + private bool isReadOnly; + + private readonly bool isReadOnly2; + } + + + + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40644")] + public async Task ShouldNotWarnForPublicImplicitDataMemberFieldsInDataContractClasses() + { + await TestMissingAsync( + """ + + + + [System.Runtime.Serialization.DataContractAttribute] + public class MyClass + { + public bool [|isReadOnly|]; + } + + + + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59577")] + public async Task TestInStruct() + { + await TestInRegularAndScript1Async( + """ + struct MyClass + { + private int [|_goo|]; + } + """, + """ + struct MyClass + { + private readonly int _goo; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59577")] + public async Task MissingForMemberInStructThatOverwritesThis() + { + await TestMissingAsync( + """ + struct MyClass + { + private int [|_goo|]; + + void M() + { + this = default; } - """, parseOptions: s_strictFeatureFlag); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38468")] + public async Task PreserveLeadingTrivia1() + { + await TestInRegularAndScript1Async( + """ + public class C + { + int x; + + int [|y|]; + } + """, + """ + public class C + { + int x; + + readonly int y; + } + """); + } + + [Fact, WorkItem(47197, "https://github.com/dotnet/roslyn/issues/47197")] + public async Task StrictFeatureFlagAssignment1() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - [Fact, WorkItem(47197, "https://github.com/dotnet/roslyn/issues/47197")] - public async Task StrictFeatureFlagAssignment2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + class C + { + private static IEqualityComparer [|s_value|]; - class C + static C() { - private static IEqualityComparer [|s_value|]; + C.s_value = null; + } + } + """, + """ + using System; + using System.Collections.Generic; - static C() - { - C.s_value = null; - } + class C + { + private static readonly IEqualityComparer s_value; + + static C() + { + C.s_value = null; } - """, new TestParameters(parseOptions: s_strictFeatureFlag)); - } + } + """, parseOptions: s_strictFeatureFlag); + } + + [Fact, WorkItem(47197, "https://github.com/dotnet/roslyn/issues/47197")] + public async Task StrictFeatureFlagAssignment2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - [Fact, WorkItem(47197, "https://github.com/dotnet/roslyn/issues/47197")] - public async Task StrictFeatureFlagAssignment3() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + class C + { + private static IEqualityComparer [|s_value|]; - class C + static C() { - private static IEqualityComparer [|s_value|]; + C.s_value = null; + } + } + """, new TestParameters(parseOptions: s_strictFeatureFlag)); + } - static C() - { - C.s_value = null; - } + [Fact, WorkItem(47197, "https://github.com/dotnet/roslyn/issues/47197")] + public async Task StrictFeatureFlagAssignment3() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + + class C + { + private static IEqualityComparer [|s_value|]; + + static C() + { + C.s_value = null; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/MakeLocalFunctionStatic/MakeLocalFunctionStaticTests.cs b/src/Analyzers/CSharp/Tests/MakeLocalFunctionStatic/MakeLocalFunctionStaticTests.cs index 13fc757e220c5..218b08660ad06 100644 --- a/src/Analyzers/CSharp/Tests/MakeLocalFunctionStatic/MakeLocalFunctionStaticTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeLocalFunctionStatic/MakeLocalFunctionStaticTests.cs @@ -15,204 +15,204 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeLocalFunctionStatic +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeLocalFunctionStatic; + +public partial class MakeLocalFunctionStaticTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - public partial class MakeLocalFunctionStaticTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public MakeLocalFunctionStaticTests(ITestOutputHelper logger) + : base(logger) { - public MakeLocalFunctionStaticTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new MakeLocalFunctionStaticDiagnosticAnalyzer(), new MakeLocalFunctionStaticCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new MakeLocalFunctionStaticDiagnosticAnalyzer(), new MakeLocalFunctionStaticCodeFixProvider()); - private static readonly ParseOptions CSharp72ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_2); - private static readonly ParseOptions CSharp8ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); + private static readonly ParseOptions CSharp72ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_2); + private static readonly ParseOptions CSharp8ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestAboveCSharp8() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestAboveCSharp8() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() + int [||]fibonacci(int n) { - int [||]fibonacci(int n) - { - return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M() { - void M() + static int fibonacci(int n) { - static int fibonacci(int n) - { - return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, + } + """, parseOptions: CSharp8ParseOptions); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] - public async Task TestWithOptionOff() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] + public async Task TestWithOptionOff() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() + int [||]fibonacci(int n) { - int [||]fibonacci(int n) - { - return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, + } + """, new TestParameters( - parseOptions: CSharp8ParseOptions, - options: Option(CSharpCodeStyleOptions.PreferStaticLocalFunction, CodeStyleOption2.FalseWithSilentEnforcement))); - } +parseOptions: CSharp8ParseOptions, +options: Option(CSharpCodeStyleOptions.PreferStaticLocalFunction, CodeStyleOption2.FalseWithSilentEnforcement))); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingIfAlreadyStatic() - { - await TestMissingAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingIfAlreadyStatic() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + static int [||]fibonacci(int n) { - static int [||]fibonacci(int n) - { - return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); - } + } + """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingPriorToCSharp8() - { - await TestMissingAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingPriorToCSharp8() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + int [||]fibonacci(int n) { - int [||]fibonacci(int n) - { - return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, parameters: new TestParameters(parseOptions: CSharp72ParseOptions)); - } + } + """, parameters: new TestParameters(parseOptions: CSharp72ParseOptions)); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingIfCapturesValue() - { - await TestMissingAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingIfCapturesValue() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(int i) { - void M(int i) + int [||]fibonacci(int n) { - int [||]fibonacci(int n) - { - return i <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + return i <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); - } + } + """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingIfCapturesThis() - { - await TestMissingAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingIfCapturesThis() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + int [||]fibonacci(int n) { - int [||]fibonacci(int n) - { - M(); - return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); - } + M(); + return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2); } } - """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestAsyncFunction() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + } + """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestAsyncFunction() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + async Task [||]fibonacci(int n) { - async Task [||]fibonacci(int n) - { - return n <= 1 ? n : await fibonacci(n - 1) + await fibonacci(n - 2); - } + return n <= 1 ? n : await fibonacci(n - 1) + await fibonacci(n - 2); } } - """, - """ - using System; - using System.Threading.Tasks; - - class C + } + """, + """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + static async Task fibonacci(int n) { - static async Task fibonacci(int n) - { - return n <= 1 ? n : await fibonacci(n - 1) + await fibonacci(n - 2); - } + return n <= 1 ? n : await fibonacci(n - 1) + await fibonacci(n - 2); } } - """, + } + """, parseOptions: CSharp8ParseOptions); - } + } - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [InlineData("")] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task TestLeadingTriviaAfterSemicolon(string leadingTrivia) - { - await TestInRegularAndScriptAsync( + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [InlineData("")] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task TestLeadingTriviaAfterSemicolon(string leadingTrivia) + { + await TestInRegularAndScriptAsync( $@"using System; class C @@ -243,15 +243,15 @@ static int fibonacci(int n) } """, parseOptions: CSharp8ParseOptions); - } + } - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [InlineData("")] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task TestLeadingTriviaAfterOpenBrace(string leadingTrivia) - { - await TestInRegularAndScriptAsync( + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [InlineData("")] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task TestLeadingTriviaAfterOpenBrace(string leadingTrivia) + { + await TestInRegularAndScriptAsync( $@"using System; class C @@ -279,15 +279,15 @@ static int fibonacci(int n) } """, parseOptions: CSharp8ParseOptions); - } + } - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [InlineData("")] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task TestLeadingTriviaAfterLocalFunction(string leadingTrivia) - { - await TestInRegularAndScriptAsync( + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [InlineData("")] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task TestLeadingTriviaAfterLocalFunction(string leadingTrivia) + { + await TestInRegularAndScriptAsync( $@"using System; class C @@ -324,15 +324,15 @@ static int fibonacci(int n) } """, parseOptions: CSharp8ParseOptions); - } + } - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [InlineData("")] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task TestLeadingTriviaAfterExpressionBodyLocalFunction(string leadingTrivia) - { - await TestInRegularAndScriptAsync( + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [InlineData("")] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task TestLeadingTriviaAfterExpressionBodyLocalFunction(string leadingTrivia) + { + await TestInRegularAndScriptAsync( $@"using System; class C @@ -357,15 +357,15 @@ void M() } """, parseOptions: CSharp8ParseOptions); - } + } - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [InlineData("")] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task TestLeadingTriviaAfterComment(string leadingTrivia) - { - await TestInRegularAndScriptAsync( + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [InlineData("")] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task TestLeadingTriviaAfterComment(string leadingTrivia) + { + await TestInRegularAndScriptAsync( $@"using System; class C @@ -393,14 +393,14 @@ static int fibonacci(int n) }} }}", parseOptions: CSharp8ParseOptions); - } + } - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [InlineData("\r\n")] - [InlineData("\r\n\r\n")] - public async Task TestLeadingTriviaBeforeComment(string leadingTrivia) - { - await TestInRegularAndScriptAsync( + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [InlineData("\r\n")] + [InlineData("\r\n\r\n")] + public async Task TestLeadingTriviaBeforeComment(string leadingTrivia) + { + await TestInRegularAndScriptAsync( $@"using System; class C @@ -428,153 +428,152 @@ static int fibonacci(int n) }} }}", parseOptions: CSharp8ParseOptions); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [WorkItem("https://github.com/dotnet/roslyn/issues/46858")] - public async Task TestMissingIfAnotherLocalFunctionCalled() - { - await TestMissingAsync( - """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [WorkItem("https://github.com/dotnet/roslyn/issues/46858")] + public async Task TestMissingIfAnotherLocalFunctionCalled() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + void [||]A() { - void [||]A() - { - B(); - } + B(); + } - void B() - { - } + void B() + { } } - """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestCallingStaticLocalFunction() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + } + """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions)); + } - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestCallingStaticLocalFunction() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + void [||]A() { - void [||]A() - { - B(); - } + B(); + } - static void B() - { - } + static void B() + { } } - """, - """ - using System; - using System.Threading.Tasks; - - class C + } + """, + """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + static void A() { - static void A() - { - B(); - } + B(); + } - static void B() - { - } + static void B() + { } } - """, + } + """, parseOptions: CSharp8ParseOptions); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestCallingNestedLocalFunction() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + } - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestCallingNestedLocalFunction() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + void [||]A() { - void [||]A() - { - B(); + B(); - void B() - { - } + void B() + { } } } - """, - """ - using System; - using System.Threading.Tasks; - - class C + } + """, + """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + static void A() { - static void A() - { - B(); + B(); - void B() - { - } + void B() + { } } } - """, + } + """, parseOptions: CSharp8ParseOptions); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [WorkItem("https://github.com/dotnet/roslyn/issues/53179")] - public async Task TestLocalFunctionAsTopLevelStatement() - { - await TestAsync(""" - void [||]A() - { - } - """, """ - static void A() - { - } - """, + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [WorkItem("https://github.com/dotnet/roslyn/issues/53179")] + public async Task TestLocalFunctionAsTopLevelStatement() + { + await TestAsync(""" + void [||]A() + { + } + """, """ + static void A() + { + } + """, parseOptions: CSharp8ParseOptions); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - [WorkItem("https://github.com/dotnet/roslyn/issues/59286")] - public async Task TestUnsafeLocalFunction() - { - await TestAsync(""" - unsafe void [||]A() - { - } - """, """ - static unsafe void A() - { - } - """, + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + [WorkItem("https://github.com/dotnet/roslyn/issues/59286")] + public async Task TestUnsafeLocalFunction() + { + await TestAsync(""" + unsafe void [||]A() + { + } + """, """ + static unsafe void A() + { + } + """, parseOptions: CSharp8ParseOptions); - } } } diff --git a/src/Analyzers/CSharp/Tests/MakeMemberRequired/MakeMemberRequiredTests.cs b/src/Analyzers/CSharp/Tests/MakeMemberRequired/MakeMemberRequiredTests.cs index abdccdebc290b..877aaf5f02adb 100644 --- a/src/Analyzers/CSharp/Tests/MakeMemberRequired/MakeMemberRequiredTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeMemberRequired/MakeMemberRequiredTests.cs @@ -11,645 +11,644 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.MakeMemberRequired +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.MakeMemberRequired; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpMakeMemberRequiredCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeMemberRequired)] +public sealed class MakeMemberRequiredTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpMakeMemberRequiredCodeFixProvider>; + public static IEnumerable MemberAccessibilityModifierCombinationsWhereShouldProvideFix() + { + yield return new[] { "public", "public", "public" }; + yield return new[] { "public", "private", "public" }; + yield return new[] { "public", "private", "internal" }; + yield return new[] { "public", "private", "protected internal" }; + yield return new[] { "public", "protected", "public" }; + yield return new[] { "public", "internal", "public" }; + yield return new[] { "public", "internal", "internal" }; + yield return new[] { "public", "internal", "protected internal" }; + yield return new[] { "public", "private protected", "public" }; + yield return new[] { "public", "private protected", "internal" }; + yield return new[] { "public", "private protected", "protected internal" }; + yield return new[] { "public", "protected internal", "public" }; + yield return new[] { "internal", "public", "public" }; + yield return new[] { "internal", "public", "internal" }; + yield return new[] { "internal", "public", "protected internal" }; + yield return new[] { "internal", "private", "public" }; + yield return new[] { "internal", "private", "internal" }; + yield return new[] { "internal", "private", "protected internal" }; + yield return new[] { "internal", "protected", "public" }; + yield return new[] { "internal", "protected", "internal" }; + yield return new[] { "internal", "protected", "protected internal" }; + yield return new[] { "internal", "internal", "public" }; + yield return new[] { "internal", "internal", "internal" }; + yield return new[] { "internal", "internal", "protected internal" }; + yield return new[] { "internal", "private protected", "public" }; + yield return new[] { "internal", "private protected", "internal" }; + yield return new[] { "internal", "private protected", "protected internal" }; + yield return new[] { "internal", "protected internal", "public" }; + yield return new[] { "internal", "protected internal", "internal" }; + yield return new[] { "internal", "protected internal", "protected internal" }; + } - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMemberRequired)] - public sealed class MakeMemberRequiredTests + public static IEnumerable MemberAccessibilityModifierCombinationsWhereShouldNotProvideFix() { - public static IEnumerable MemberAccessibilityModifierCombinationsWhereShouldProvideFix() - { - yield return new[] { "public", "public", "public" }; - yield return new[] { "public", "private", "public" }; - yield return new[] { "public", "private", "internal" }; - yield return new[] { "public", "private", "protected internal" }; - yield return new[] { "public", "protected", "public" }; - yield return new[] { "public", "internal", "public" }; - yield return new[] { "public", "internal", "internal" }; - yield return new[] { "public", "internal", "protected internal" }; - yield return new[] { "public", "private protected", "public" }; - yield return new[] { "public", "private protected", "internal" }; - yield return new[] { "public", "private protected", "protected internal" }; - yield return new[] { "public", "protected internal", "public" }; - yield return new[] { "internal", "public", "public" }; - yield return new[] { "internal", "public", "internal" }; - yield return new[] { "internal", "public", "protected internal" }; - yield return new[] { "internal", "private", "public" }; - yield return new[] { "internal", "private", "internal" }; - yield return new[] { "internal", "private", "protected internal" }; - yield return new[] { "internal", "protected", "public" }; - yield return new[] { "internal", "protected", "internal" }; - yield return new[] { "internal", "protected", "protected internal" }; - yield return new[] { "internal", "internal", "public" }; - yield return new[] { "internal", "internal", "internal" }; - yield return new[] { "internal", "internal", "protected internal" }; - yield return new[] { "internal", "private protected", "public" }; - yield return new[] { "internal", "private protected", "internal" }; - yield return new[] { "internal", "private protected", "protected internal" }; - yield return new[] { "internal", "protected internal", "public" }; - yield return new[] { "internal", "protected internal", "internal" }; - yield return new[] { "internal", "protected internal", "protected internal" }; - } - - public static IEnumerable MemberAccessibilityModifierCombinationsWhereShouldNotProvideFix() - { - yield return new[] { "public", "public", "private" }; - yield return new[] { "public", "public", "protected" }; - yield return new[] { "public", "public", "internal" }; - yield return new[] { "public", "public", "private protected" }; - yield return new[] { "public", "public", "protected internal" }; - yield return new[] { "public", "private", "private" }; - yield return new[] { "public", "private", "protected" }; - yield return new[] { "public", "private", "private protected" }; - yield return new[] { "public", "protected", "private" }; - yield return new[] { "public", "protected", "protected" }; - yield return new[] { "public", "protected", "internal" }; - yield return new[] { "public", "protected", "private protected" }; - yield return new[] { "public", "protected", "protected internal" }; - yield return new[] { "public", "internal", "private" }; - yield return new[] { "public", "internal", "protected" }; - yield return new[] { "public", "internal", "private protected" }; - yield return new[] { "public", "private protected", "private" }; - yield return new[] { "public", "private protected", "protected" }; - yield return new[] { "public", "private protected", "private protected" }; - yield return new[] { "public", "protected internal", "private" }; - yield return new[] { "public", "protected internal", "protected" }; - yield return new[] { "public", "protected internal", "internal" }; - yield return new[] { "public", "protected internal", "private protected" }; - yield return new[] { "public", "protected internal", "protected internal" }; - yield return new[] { "internal", "public", "private" }; - yield return new[] { "internal", "public", "protected" }; - yield return new[] { "internal", "public", "private protected" }; - yield return new[] { "internal", "private", "private" }; - yield return new[] { "internal", "private", "protected" }; - yield return new[] { "internal", "private", "private protected" }; - yield return new[] { "internal", "protected", "private" }; - yield return new[] { "internal", "protected", "protected" }; - yield return new[] { "internal", "protected", "private protected" }; - yield return new[] { "internal", "internal", "private" }; - yield return new[] { "internal", "internal", "protected" }; - yield return new[] { "internal", "internal", "private protected" }; - yield return new[] { "internal", "private protected", "private" }; - yield return new[] { "internal", "private protected", "protected" }; - yield return new[] { "internal", "private protected", "private protected" }; - yield return new[] { "internal", "protected internal", "private" }; - yield return new[] { "internal", "protected internal", "protected" }; - yield return new[] { "internal", "protected internal", "private protected" }; - } - - public static IEnumerable AccessorAccessibilityModifierCombinationsWhereShouldProvideFix() - { - yield return new[] { "public", "" }; - yield return new[] { "internal", "" }; - yield return new[] { "internal", "internal" }; - yield return new[] { "internal", "protected internal" }; - } + yield return new[] { "public", "public", "private" }; + yield return new[] { "public", "public", "protected" }; + yield return new[] { "public", "public", "internal" }; + yield return new[] { "public", "public", "private protected" }; + yield return new[] { "public", "public", "protected internal" }; + yield return new[] { "public", "private", "private" }; + yield return new[] { "public", "private", "protected" }; + yield return new[] { "public", "private", "private protected" }; + yield return new[] { "public", "protected", "private" }; + yield return new[] { "public", "protected", "protected" }; + yield return new[] { "public", "protected", "internal" }; + yield return new[] { "public", "protected", "private protected" }; + yield return new[] { "public", "protected", "protected internal" }; + yield return new[] { "public", "internal", "private" }; + yield return new[] { "public", "internal", "protected" }; + yield return new[] { "public", "internal", "private protected" }; + yield return new[] { "public", "private protected", "private" }; + yield return new[] { "public", "private protected", "protected" }; + yield return new[] { "public", "private protected", "private protected" }; + yield return new[] { "public", "protected internal", "private" }; + yield return new[] { "public", "protected internal", "protected" }; + yield return new[] { "public", "protected internal", "internal" }; + yield return new[] { "public", "protected internal", "private protected" }; + yield return new[] { "public", "protected internal", "protected internal" }; + yield return new[] { "internal", "public", "private" }; + yield return new[] { "internal", "public", "protected" }; + yield return new[] { "internal", "public", "private protected" }; + yield return new[] { "internal", "private", "private" }; + yield return new[] { "internal", "private", "protected" }; + yield return new[] { "internal", "private", "private protected" }; + yield return new[] { "internal", "protected", "private" }; + yield return new[] { "internal", "protected", "protected" }; + yield return new[] { "internal", "protected", "private protected" }; + yield return new[] { "internal", "internal", "private" }; + yield return new[] { "internal", "internal", "protected" }; + yield return new[] { "internal", "internal", "private protected" }; + yield return new[] { "internal", "private protected", "private" }; + yield return new[] { "internal", "private protected", "protected" }; + yield return new[] { "internal", "private protected", "private protected" }; + yield return new[] { "internal", "protected internal", "private" }; + yield return new[] { "internal", "protected internal", "protected" }; + yield return new[] { "internal", "protected internal", "private protected" }; + } - public static IEnumerable AccessorAccessibilityModifierCombinationsWhereShouldNotProvideFix() + public static IEnumerable AccessorAccessibilityModifierCombinationsWhereShouldProvideFix() + { + yield return new[] { "public", "" }; + yield return new[] { "internal", "" }; + yield return new[] { "internal", "internal" }; + yield return new[] { "internal", "protected internal" }; + } + + public static IEnumerable AccessorAccessibilityModifierCombinationsWhereShouldNotProvideFix() + { + yield return new[] { "public", "internal" }; + yield return new[] { "public", "protected" }; + yield return new[] { "public", "private" }; + yield return new[] { "public", "private protected" }; + yield return new[] { "public", "protected internal" }; + yield return new[] { "internal", "protected" }; + yield return new[] { "internal", "private" }; + yield return new[] { "internal", "private protected" }; + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68478")] + public async Task SimpleSetPropertyMissingRequiredAttribute() + { + var code = + """ + #nullable enable + class MyClass + { + public string {|CS8618:MyProperty|} { get; set; } + } + """; + + await new VerifyCS.Test { - yield return new[] { "public", "internal" }; - yield return new[] { "public", "protected" }; - yield return new[] { "public", "private" }; - yield return new[] { "public", "private protected" }; - yield return new[] { "public", "protected internal" }; - yield return new[] { "internal", "protected" }; - yield return new[] { "internal", "private" }; - yield return new[] { "internal", "private protected" }; - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68478")] - public async Task SimpleSetPropertyMissingRequiredAttribute() + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + }.RunAsync(); + } + + [Fact] + public async Task SimpleSetProperty() + { + await new VerifyCS.Test { - var code = - """ + TestCode = """ #nullable enable class MyClass { public string {|CS8618:MyProperty|} { get; set; } } - """; + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string MyProperty { get; set; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - }.RunAsync(); - } - - [Fact] - public async Task SimpleSetProperty() - { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:MyProperty|} { get; set; } - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string MyProperty { get; set; } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task SimpleInitProperty() - { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:MyProperty|} { get; init; } - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string MyProperty { get; init; } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task NotOnGetOnlyProperty() + [Fact] + public async Task SimpleInitProperty() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ #nullable enable - class MyClass { - public string {|CS8618:MyProperty|} { get; } + public string {|CS8618:MyProperty|} { get; init; } } - """; + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string MyProperty { get; init; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldProvideFix))] - public async Task TestEffectivePropertyAccessibilityWhereShouldProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string propertyAccessibility) - { - await new VerifyCS.Test + [Fact] + public async Task NotOnGetOnlyProperty() + { + var code = """ + #nullable enable + + class MyClass { - TestCode = $$""" - #nullable enable - - {{outerClassAccessibility}} class C - { - {{containingTypeAccessibility}} class MyClass - { - {{propertyAccessibility}} string {|CS8618:MyProperty|} { get; set; } - } - } - """, - FixedCode = $$""" - #nullable enable - - {{outerClassAccessibility}} class C - { - {{containingTypeAccessibility}} class MyClass - { - {{propertyAccessibility}} required string MyProperty { get; set; } - } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldNotProvideFix))] - public async Task TestEffectivePropertyAccessibilityWhereShouldNotProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string propertyAccessibility) + public string {|CS8618:MyProperty|} { get; } + } + """; + + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - #nullable enable - - {{outerClassAccessibility}} class C - { - {{containingTypeAccessibility}} class MyClass - { - {{propertyAccessibility}} string {|CS8618:MyProperty|} { get; set; } - } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldProvideFix))] - public async Task TestSetAccessorAccessibilityWhereShouldProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldProvideFix))] + public async Task TestEffectivePropertyAccessibilityWhereShouldProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string propertyAccessibility) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - #nullable enable - + TestCode = $$""" + #nullable enable + + {{outerClassAccessibility}} class C + { {{containingTypeAccessibility}} class MyClass { - public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} set; } + {{propertyAccessibility}} string {|CS8618:MyProperty|} { get; set; } } - """, - FixedCode = $$""" - #nullable enable - + } + """, + FixedCode = $$""" + #nullable enable + + {{outerClassAccessibility}} class C + { {{containingTypeAccessibility}} class MyClass { - public required string MyProperty { get; {{setAccessorAccessibility}} set; } + {{propertyAccessibility}} required string MyProperty { get; set; } } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldNotProvideFix))] - public async Task TestSetAccessorAccessibilityWhereShouldNotProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldNotProvideFix))] + public async Task TestEffectivePropertyAccessibilityWhereShouldNotProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string propertyAccessibility) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - #nullable enable - + TestCode = $$""" + #nullable enable + + {{outerClassAccessibility}} class C + { {{containingTypeAccessibility}} class MyClass { - public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} set; } + {{propertyAccessibility}} string {|CS8618:MyProperty|} { get; set; } } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldProvideFix))] - public async Task TestInitAccessorAccessibilityWhereShouldProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldProvideFix))] + public async Task TestSetAccessorAccessibilityWhereShouldProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - #nullable enable - + TestCode = $$""" + #nullable enable + + {{containingTypeAccessibility}} class MyClass + { + public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} set; } + } + """, + FixedCode = $$""" + #nullable enable + + {{containingTypeAccessibility}} class MyClass + { + public required string MyProperty { get; {{setAccessorAccessibility}} set; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldNotProvideFix))] + public async Task TestSetAccessorAccessibilityWhereShouldNotProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + { + await new VerifyCS.Test + { + TestCode = $$""" + #nullable enable + + {{containingTypeAccessibility}} class MyClass + { + public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} set; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldProvideFix))] + public async Task TestInitAccessorAccessibilityWhereShouldProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + { + await new VerifyCS.Test + { + TestCode = $$""" + #nullable enable + + {{containingTypeAccessibility}} class MyClass + { + public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} init; } + } + """, + FixedCode = $$""" + #nullable enable + + {{containingTypeAccessibility}} class MyClass + { + public required string MyProperty { get; {{setAccessorAccessibility}} init; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldNotProvideFix))] + public async Task TestInitAccessorAccessibilityWhereShouldNotProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + { + await new VerifyCS.Test + { + TestCode = $$""" + #nullable enable + + {{containingTypeAccessibility}} class MyClass + { + public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} init; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task SimpleField() + { + await new VerifyCS.Test + { + TestCode = """ + #nullable enable + + class MyClass + { + public string {|CS8618:_myField|}; + } + """, + FixedCode = """ + #nullable enable + + class MyClass + { + public required string _myField; + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldProvideFix))] + public async Task TestEffectiveFieldAccessibilityWhereShouldProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string fieldAccessibility) + { + await new VerifyCS.Test + { + TestCode = $$""" + #nullable enable + + {{outerClassAccessibility}} class C + { {{containingTypeAccessibility}} class MyClass { - public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} init; } + {{fieldAccessibility}} string {|CS8618:_myField|}; } - """, - FixedCode = $$""" - #nullable enable - + } + """, + FixedCode = $$""" + #nullable enable + + {{outerClassAccessibility}} class C + { {{containingTypeAccessibility}} class MyClass { - public required string MyProperty { get; {{setAccessorAccessibility}} init; } + {{fieldAccessibility}} required string _myField; } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(AccessorAccessibilityModifierCombinationsWhereShouldNotProvideFix))] - public async Task TestInitAccessorAccessibilityWhereShouldNotProvideFix(string containingTypeAccessibility, string setAccessorAccessibility) + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldNotProvideFix))] + public async Task TestEffectiveFieldAccessibilityWhereShouldNotProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string fieldAccessibility) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - #nullable enable - + TestCode = $$""" + #nullable enable + + {{outerClassAccessibility}} class C + { {{containingTypeAccessibility}} class MyClass { - public string {|CS8618:MyProperty|} { get; {{setAccessorAccessibility}} init; } + {{fieldAccessibility}} string {|CS8618:_myField|}; } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task SimpleField() - { - await new VerifyCS.Test + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task NotForLowerVersionOfCSharp() + { + var code = """ + #nullable enable + + class MyClass { - TestCode = """ - #nullable enable - - class MyClass - { - public string {|CS8618:_myField|}; - } - """, - FixedCode = """ - #nullable enable - - class MyClass - { - public required string _myField; - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldProvideFix))] - public async Task TestEffectiveFieldAccessibilityWhereShouldProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string fieldAccessibility) + public string {|CS8618:MyProperty|} { get; set; } + } + """; + + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp10, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task NotOnConstructorDeclaration() + { + var code = """ + #nullable enable + + class MyClass { - TestCode = $$""" - #nullable enable - - {{outerClassAccessibility}} class C - { - {{containingTypeAccessibility}} class MyClass - { - {{fieldAccessibility}} string {|CS8618:_myField|}; - } - } - """, - FixedCode = $$""" - #nullable enable - - {{outerClassAccessibility}} class C - { - {{containingTypeAccessibility}} class MyClass - { - {{fieldAccessibility}} required string _myField; - } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(MemberAccessibilityModifierCombinationsWhereShouldNotProvideFix))] - public async Task TestEffectiveFieldAccessibilityWhereShouldNotProvideFix(string outerClassAccessibility, string containingTypeAccessibility, string fieldAccessibility) + public string MyProperty { get; set; } + public {|CS8618:MyClass|}() { } + } + """; + + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task NotOnEventDeclaration() + { + var code = """ + #nullable enable + + class MyClass { - TestCode = $$""" - #nullable enable - - {{outerClassAccessibility}} class C - { - {{containingTypeAccessibility}} class MyClass - { - {{fieldAccessibility}} string {|CS8618:_myField|}; - } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task NotForLowerVersionOfCSharp() + public event System.EventHandler {|CS8618:MyEvent|}; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task FixAll1() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ #nullable enable - class MyClass { public string {|CS8618:MyProperty|} { get; set; } + public string {|CS8618:MyProperty1|} { get; set; } } - """; + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string MyProperty { get; set; } + public required string MyProperty1 { get; set; } + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp10, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task NotOnConstructorDeclaration() + [Fact] + public async Task FixAll2() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ #nullable enable - class MyClass { - public string MyProperty { get; set; } - public {|CS8618:MyClass|}() { } + public string {|CS8618:_myField|}; + public string {|CS8618:_myField1|}; } - """; + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string _myField; + public required string _myField1; + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task NotOnEventDeclaration() + [Fact] + public async Task FixAll3() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ #nullable enable - class MyClass { - public event System.EventHandler {|CS8618:MyEvent|}; + public string {|CS8618:_myField|}, {|CS8618:_myField1|}; } - """; + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string _myField, _myField1; + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task FixAll1() - { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:MyProperty|} { get; set; } - public string {|CS8618:MyProperty1|} { get; set; } - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string MyProperty { get; set; } - public required string MyProperty1 { get; set; } - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task FixAll2() - { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:_myField|}; - public string {|CS8618:_myField1|}; - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string _myField; - public required string _myField1; - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task FixAll3() - { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:_myField|}, {|CS8618:_myField1|}; - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string _myField, _myField1; - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task FixAll4() + [Fact] + public async Task FixAll4() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:_myField|}, {|CS8618:_myField1|}, {|CS8618:_myField2|}; - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string _myField, _myField1, _myField2; - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task FixAll5() + TestCode = """ + #nullable enable + class MyClass + { + public string {|CS8618:_myField|}, {|CS8618:_myField1|}, {|CS8618:_myField2|}; + } + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string _myField, _myField1, _myField2; + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task FixAll5() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:_myField|}, {|CS8618:_myField1|}; - public string {|CS8618:_myField2|}, {|CS8618:_myField3|}; - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string _myField, _myField1; - public required string _myField2, _myField3; - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } - - [Fact] - public async Task TwoFieldDeclaratorsWithOneIssue() + TestCode = """ + #nullable enable + class MyClass + { + public string {|CS8618:_myField|}, {|CS8618:_myField1|}; + public string {|CS8618:_myField2|}, {|CS8618:_myField3|}; + } + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string _myField, _myField1; + public required string _myField2, _myField3; + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact] + public async Task TwoFieldDeclaratorsWithOneIssue() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - #nullable enable - class MyClass - { - public string {|CS8618:_myField|}, _myField1 = ""; - } - """, - FixedCode = """ - #nullable enable - class MyClass - { - public required string _myField, _myField1 = ""; - } - """, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70 - }.RunAsync(); - } + TestCode = """ + #nullable enable + class MyClass + { + public string {|CS8618:_myField|}, _myField1 = ""; + } + """, + FixedCode = """ + #nullable enable + class MyClass + { + public required string _myField, _myField1 = ""; + } + """, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/MakeMemberStatic/MakeMemberStaticTests.cs b/src/Analyzers/CSharp/Tests/MakeMemberStatic/MakeMemberStaticTests.cs index 9932fbaf28248..f97a4f16e94ed 100644 --- a/src/Analyzers/CSharp/Tests/MakeMemberStatic/MakeMemberStaticTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeMemberStatic/MakeMemberStaticTests.cs @@ -10,138 +10,137 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeMemberStatic +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeMemberStatic; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpMakeMemberStaticCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeMemberStatic)] +public class MakeMemberStaticTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpMakeMemberStaticCodeFixProvider>; + [Fact] + public async Task TestField() + { + await VerifyCS.VerifyCodeFixAsync( + """ + public static class Foo + { + int {|CS0708:i|}; + } + """, + """ + public static class Foo + { + static int i; + } + """); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMemberStatic)] - public class MakeMemberStaticTests + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54202")] + public async Task TestTrivia() { - [Fact] - public async Task TestField() - { - await VerifyCS.VerifyCodeFixAsync( - """ - public static class Foo - { - int {|CS0708:i|}; - } - """, - """ - public static class Foo - { - static int i; - } - """); - } + await VerifyCS.VerifyCodeFixAsync( + """ + public static class Foo + { + // comment + readonly int {|CS0708:i|}; + } + """, + """ + public static class Foo + { + // comment + static readonly int i; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54202")] - public async Task TestTrivia() - { - await VerifyCS.VerifyCodeFixAsync( - """ - public static class Foo - { - // comment - readonly int {|CS0708:i|}; - } - """, - """ - public static class Foo - { - // comment - static readonly int i; - } - """); - } + [Fact] + public async Task TestMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + public static class Foo + { + void {|CS0708:M|}() { } + } + """, + """ + public static class Foo + { + static void M() { } + } + """); + } - [Fact] - public async Task TestMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - public static class Foo - { - void {|CS0708:M|}() { } - } - """, - """ - public static class Foo - { - static void M() { } - } - """); - } + [Fact] + public async Task TestProperty() + { + await VerifyCS.VerifyCodeFixAsync( + """ + public static class Foo + { + object {|CS0708:P|} { get; set; } + } + """, + """ + public static class Foo + { + static object P { get; set; } + } + """); + } - [Fact] - public async Task TestProperty() - { - await VerifyCS.VerifyCodeFixAsync( - """ - public static class Foo - { - object {|CS0708:P|} { get; set; } - } - """, - """ - public static class Foo - { - static object P { get; set; } - } - """); - } + [Fact] + public async Task TestEventField() + { + await VerifyCS.VerifyCodeFixAsync( + """ + public static class Foo + { + event System.Action {|CS0708:E|}; + } + """, + """ + public static class Foo + { + static event System.Action E; + } + """); + } - [Fact] - public async Task TestEventField() - { - await VerifyCS.VerifyCodeFixAsync( - """ + [Fact] + public async Task FixAll() + { + await VerifyCS.VerifyCodeFixAsync( + """ + namespace NS + { public static class Foo { + int {|CS0708:i|}; + void {|CS0708:M|}() { } + object {|CS0708:P|} { get; set; } event System.Action {|CS0708:E|}; } - """, - """ + } + """, + """ + namespace NS + { public static class Foo { - static event System.Action E; - } - """); - } - - [Fact] - public async Task FixAll() - { - await VerifyCS.VerifyCodeFixAsync( - """ - namespace NS - { - public static class Foo - { - int {|CS0708:i|}; - void {|CS0708:M|}() { } - object {|CS0708:P|} { get; set; } - event System.Action {|CS0708:E|}; - } - } - """, - """ - namespace NS - { - public static class Foo - { - static int i; + static int i; - static void M() { } + static void M() { } - static object P { get; set; } + static object P { get; set; } - static event System.Action E; - } + static event System.Action E; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs b/src/Analyzers/CSharp/Tests/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs index c00f0094868f2..254bb350030a9 100644 --- a/src/Analyzers/CSharp/Tests/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeMethodAsynchronous/MakeMethodAsynchronousTests.cs @@ -13,755 +13,790 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeMethodAsynchronous +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeMethodAsynchronous; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] +public partial class MakeMethodAsynchronousTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] - public partial class MakeMethodAsynchronousTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public MakeMethodAsynchronousTests(ITestOutputHelper logger) + : base(logger) { - public MakeMethodAsynchronousTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpMakeMethodAsynchronousCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpMakeMethodAsynchronousCodeFixProvider()); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AwaitInVoidMethodWithModifiers() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AwaitInVoidMethodWithModifiers() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public static void Test() { - public static void Test() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public static async void Test() { - public static async void Test() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected, index: 1); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected, index: 1); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26312")] - public async Task AwaitInTaskMainMethodWithModifiers() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26312")] + public async Task AwaitInTaskMainMethodWithModifiers() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public static void Main() { - public static void Main() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public static async Task Main() { - public static async Task Main() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestAsync(initial, expected, parseOptions: CSharpParseOptions.Default, - compilationOptions: new CSharpCompilationOptions(OutputKind.ConsoleApplication)); + } + """; + await TestAsync(initial, expected, parseOptions: CSharpParseOptions.Default, + compilationOptions: new CSharpCompilationOptions(OutputKind.ConsoleApplication)); - // no option offered to keep void - await TestActionCountAsync(initial, count: 1, new TestParameters(compilationOptions: new CSharpCompilationOptions(OutputKind.ConsoleApplication))); - } + // no option offered to keep void + await TestActionCountAsync(initial, count: 1, new TestParameters(compilationOptions: new CSharpCompilationOptions(OutputKind.ConsoleApplication))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26312")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AwaitInVoidMainMethodWithModifiers_NotEntryPoint() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26312")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AwaitInVoidMainMethodWithModifiers_NotEntryPoint() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public void Main() { - public void Main() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public async void Main() { - public async void Main() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected, index: 1); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected, index: 1); + } - [Fact] - public async Task AwaitInVoidMethodWithModifiers2() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task AwaitInVoidMethodWithModifiers2() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public static void Test() { - public static void Test() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public static async Task TestAsync() { - public static async Task TestAsync() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AwaitInTaskMethodNoModifiers() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AwaitInTaskMethodNoModifiers() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + Task Test() { - Task Test() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + async Task Test() { - async Task Test() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AwaitInTaskMethodWithModifiers() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AwaitInTaskMethodWithModifiers() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public/*Comment*/static/*Comment*/Task/*Comment*/Test() { - public/*Comment*/static/*Comment*/Task/*Comment*/Test() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + public/*Comment*/static/*Comment*/async Task/*Comment*/Test() { - public/*Comment*/static/*Comment*/async Task/*Comment*/Test() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task AwaitInLambdaFunction() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task AwaitInLambdaFunction() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a = () => Console.WriteLine(); - Func b = () => [|await Task.Run(a);|] - } + Action a = () => Console.WriteLine(); + Func b = () => [|await Task.Run(a);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a = () => Console.WriteLine(); - Func b = async () => await Task.Run(a); - } + Action a = () => Console.WriteLine(); + Func b = async () => await Task.Run(a); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task AwaitInLambdaAction() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task AwaitInLambdaAction() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a = () => [|await Task.Delay(1);|] - } + Action a = () => [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a = async () => await Task.Delay(1); - } - } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInNonAsyncMethod() - { - var initial = - """ - using System.Threading.Tasks; - class Program - { - void Test() - { - [|await Task.Delay(1);|] - } + Action a = async () => await Task.Delay(1); } - """; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - using System.Threading.Tasks; - class Program - { - async void Test() - { - await Task.Delay(1); - } - } - """; - await TestInRegularAndScriptAsync(initial, expected, index: 1); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInNonAsyncMethod() + { + var initial = + """ + using System.Threading.Tasks; + class Program + { + void Test() + { + [|await Task.Delay(1);|] + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + class Program + { + async void Test() + { + await Task.Delay(1); + } + } + """; + await TestInRegularAndScriptAsync(initial, expected, index: 1); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInNonAsyncMethod2() - { - var initial = - """ - using System.Threading.Tasks; - class Program - { - Task Test() - { - [|await Task.Delay(1);|] - } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInNonAsyncMethod2() + { + var initial = + """ + using System.Threading.Tasks; + class Program + { + Task Test() + { + [|await Task.Delay(1);|] + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + class Program + { + async Task Test() + { + await Task.Delay(1); + } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - using System.Threading.Tasks; - class Program - { - async Task Test() - { - await Task.Delay(1); - } - } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInNonAsyncMethod3() + { + var initial = + """ + using System.Threading.Tasks; + class Program + { + Task Test() + { + [|await Task.Delay(1);|] + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + class Program + { + async Task Test() + { + await Task.Delay(1); + } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInNonAsyncMethod3() - { - var initial = - """ - using System.Threading.Tasks; - class Program - { - Task Test() - { - [|await Task.Delay(1);|] - } - } - """; + [Fact] + public async Task BadAwaitInNonAsyncMethod4() + { + var initial = + """ + using System.Threading.Tasks; + class Program + { + int Test() + { + [|await Task.Delay(1);|] + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + class Program + { + async Task TestAsync() + { + await Task.Delay(1); + } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - using System.Threading.Tasks; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInNonAsyncMethod5() + { + var initial = + """ + class Program + { + void Test() { - async Task Test() - { - await Task.Delay(1); - } + [|await Task.Delay(1);|] } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; - [Fact] - public async Task BadAwaitInNonAsyncMethod4() - { - var initial = - """ - using System.Threading.Tasks; - class Program + var expected = + """ + class Program + { + async void Test() { - int Test() - { - [|await Task.Delay(1);|] - } + await Task.Delay(1); } - """; + } + """; + await TestInRegularAndScriptAsync(initial, expected, index: 1); + } - var expected = - """ - using System.Threading.Tasks; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInNonAsyncMethod6() + { + var initial = + """ + class Program + { + Task Test() { - async Task TestAsync() - { - await Task.Delay(1); - } + [|await Task.Delay(1);|] } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInNonAsyncMethod5() - { - var initial = - """ - class Program + var expected = + """ + class Program + { + async Task Test() { - void Test() - { - [|await Task.Delay(1);|] - } + await Task.Delay(1); } - """; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInNonAsyncMethod7() + { + var initial = + """ + class Program + { + Task Test() { - async void Test() - { - await Task.Delay(1); - } + [|await Task.Delay(1);|] } - """; - await TestInRegularAndScriptAsync(initial, expected, index: 1); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInNonAsyncMethod6() - { - var initial = - """ - class Program + var expected = + """ + class Program + { + async Task Test() { - Task Test() - { - [|await Task.Delay(1);|] - } + await Task.Delay(1); } - """; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - class Program + [Fact] + public async Task BadAwaitInNonAsyncMethod8() + { + var initial = + """ + class Program + { + int Test() { - async Task Test() - { - await Task.Delay(1); - } + [|await Task.Delay(1);|] } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInNonAsyncMethod7() - { - var initial = - """ - class Program - { - Task Test() - { - [|await Task.Delay(1);|] - } - } - """; + var expected = + """ + using System.Threading.Tasks; - var expected = - """ - class Program + class Program + { + async Task TestAsync() { - async Task Test() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task BadAwaitInNonAsyncMethod8() - { - var initial = - """ - class Program + [Fact] + public async Task BadAwaitInNonAsyncMethod9() + { + var initial = + """ + class Program + { + Program Test() { - int Test() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; - - var expected = - """ - using System.Threading.Tasks; + } + """; - class Program - { - async Task TestAsync() - { - await Task.Delay(1); - } - } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + var expected = + """ + using System.Threading.Tasks; - [Fact] - public async Task BadAwaitInNonAsyncMethod9() - { - var initial = - """ - class Program + class Program + { + async Task TestAsync() { - Program Test() - { - [|await Task.Delay(1);|] - } + await Task.Delay(1); } - """; - - var expected = - """ - using System.Threading.Tasks; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - class Program + [Fact] + public async Task BadAwaitInNonAsyncMethod10() + { + var initial = + """ + class Program + { + asdf Test() { - async Task TestAsync() - { - await Task.Delay(1); - } + [|await Task.Delay(1);|] } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; - [Fact] - public async Task BadAwaitInNonAsyncMethod10() - { - var initial = - """ - class Program + var expected = + """ + class Program + { + async System.Threading.Tasks.Task TestAsync() { - asdf Test() - { - [|await Task.Delay(1);|] - } + await Task.Delay(1); } - """; + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - class Program - { - async System.Threading.Tasks.Task TestAsync() - { - await Task.Delay(1); - } - } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + [Fact] + public async Task BadAwaitInEnumerableMethod() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerable Test() + { + yield return 1; + [|await Task.Delay(1);|] + } + } + """ + IAsyncEnumerable; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerable TestAsync() + { + yield return 1; + await Task.Delay(1); + } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task BadAwaitInEnumerableMethod() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - IEnumerable Test() - { - yield return 1; - [|await Task.Delay(1);|] - } - } - """ + IAsyncEnumerable; + [Fact] + public async Task BadAwaitInEnumerableMethodMissingIAsyncEnumerableType() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerable Test() + { + yield return 1; + [|await Task.Delay(1);|] + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerable TestAsync() + { + yield return 1; + await Task.Delay(1); + } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async IAsyncEnumerable TestAsync() - { - yield return 1; - await Task.Delay(1); - } - } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } + [Fact] + public async Task BadAwaitInEnumerableMethodWithReturn() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerable Test() + { + [|await Task.Delay(1);|] + return null; + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async Task> TestAsync() + { + await Task.Delay(1); + return null; + } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task BadAwaitInEnumerableMethodMissingIAsyncEnumerableType() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + [Fact] + public async Task BadAwaitInEnumerableMethodWithYieldInsideLocalFunction() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerable Test() { - IEnumerable Test() - { - yield return 1; - [|await Task.Delay(1);|] - } - } - """; + [|await Task.Delay(1);|] + return local(); - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async IAsyncEnumerable TestAsync() + IEnumerable local() { yield return 1; - await Task.Delay(1); } } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; - [Fact] - public async Task BadAwaitInEnumerableMethodWithReturn() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async Task> TestAsync() { - IEnumerable Test() - { - [|await Task.Delay(1);|] - return null; - } - } - """; + await Task.Delay(1); + return local(); - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async Task> TestAsync() + IEnumerable local() { - await Task.Delay(1); - return null; - } - } - """; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task BadAwaitInEnumerableMethodWithYieldInsideLocalFunction() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - IEnumerable Test() - { - [|await Task.Delay(1);|] - return local(); - - IEnumerable local() - { - yield return 1; - } - } - } - """; - - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async Task> TestAsync() - { - await Task.Delay(1); - return local(); - - IEnumerable local() - { - yield return 1; - } + yield return 1; } } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task BadAwaitInEnumeratorMethodWithReturn() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - IEnumerator Test() - { - [|await Task.Delay(1);|] - return null; - } - } - """; + [Fact] + public async Task BadAwaitInEnumeratorMethodWithReturn() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerator Test() + { + [|await Task.Delay(1);|] + return null; + } + } + """; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async Task> TestAsync() + { + await Task.Delay(1); + return null; + } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async Task> TestAsync() - { - await Task.Delay(1); - return null; - } - } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + [Fact] + public async Task BadAwaitInEnumeratorMethod() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerator Test() + { + yield return 1; + [|await Task.Delay(1);|] + } + } + """ + IAsyncEnumerable; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerator TestAsync() + { + yield return 1; + await Task.Delay(1); + } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task BadAwaitInEnumeratorMethod() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + [Fact] + public async Task BadAwaitInEnumeratorLocalFunction() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + void M() { IEnumerator Test() { @@ -769,13 +804,16 @@ IEnumerator Test() [|await Task.Delay(1);|] } } - """ + IAsyncEnumerable; + } + """ + IAsyncEnumerable; - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + void M() { async IAsyncEnumerator TestAsync() { @@ -783,814 +821,775 @@ async IAsyncEnumerator TestAsync() await Task.Delay(1); } } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task BadAwaitInEnumeratorLocalFunction() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - void M() - { - IEnumerator Test() - { - yield return 1; - [|await Task.Delay(1);|] - } - } - } - """ + IAsyncEnumerable; - - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - void M() - { - async IAsyncEnumerator TestAsync() - { - yield return 1; - await Task.Delay(1); - } - } - } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInIAsyncEnumerableMethod() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - IAsyncEnumerable Test() - { - yield return 1; - [|await Task.Delay(1);|] - } - } - """ + IAsyncEnumerable; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInIAsyncEnumerableMethod() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IAsyncEnumerable Test() + { + yield return 1; + [|await Task.Delay(1);|] + } + } + """ + IAsyncEnumerable; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerable Test() + { + yield return 1; + await Task.Delay(1); + } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async IAsyncEnumerable Test() - { - yield return 1; - await Task.Delay(1); - } - } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task BadAwaitInIAsyncEnumeratorMethod() + { + var initial = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IAsyncEnumerator Test() + { + yield return 1; + [|await Task.Delay(1);|] + } + } + """ + IAsyncEnumerable; + + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerator Test() + { + yield return 1; + await Task.Delay(1); + } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task BadAwaitInIAsyncEnumeratorMethod() - { - var initial = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - IAsyncEnumerator Test() - { - yield return 1; - [|await Task.Delay(1);|] - } - } - """ + IAsyncEnumerable; + [Fact] + public async Task AwaitInMember() + { + var code = + """ + using System.Threading.Tasks; + + class Program + { + var x = [|await Task.Delay(3)|]; + } + """; + await TestMissingInRegularAndScriptAsync(code); + } - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - async IAsyncEnumerator Test() - { - yield return 1; - await Task.Delay(1); - } - } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } + [Fact] + public async Task AddAsyncInDelegate() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class Program + { + private async void method() + { + string content = await Task.Run(delegate () { + [|await Task.Delay(1000)|]; + return "Test"; + }); + } + } + """, + """ + using System; + using System.Threading.Tasks; + + class Program + { + private async void method() + { + string content = await Task.Run(async delegate () { + await Task.Delay(1000); + return "Test"; + }); + } + } + """); + } - [Fact] - public async Task AwaitInMember() - { - var code = - """ - using System.Threading.Tasks; + [Fact] + public async Task AddAsyncInDelegate2() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class Program + { + private void method() + { + string content = await Task.Run(delegate () { + [|await Task.Delay(1000)|]; + return "Test"; + }); + } + } + """, + """ + using System; + using System.Threading.Tasks; + + class Program + { + private void method() + { + string content = await Task.Run(async delegate () { + await Task.Delay(1000); + return "Test"; + }); + } + } + """); + } - class Program - { - var x = [|await Task.Delay(3)|]; - } - """; - await TestMissingInRegularAndScriptAsync(code); - } + [Fact] + public async Task AddAsyncInDelegate3() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class Program + { + private void method() + { + string content = await Task.Run(delegate () { + [|await Task.Delay(1000)|]; + return "Test"; + }); + } + } + """, + """ + using System; + using System.Threading.Tasks; + + class Program + { + private void method() + { + string content = await Task.Run(async delegate () { + await Task.Delay(1000); + return "Test"; + }); + } + } + """); + } - [Fact] - public async Task AddAsyncInDelegate() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem(6477, @"https://github.com/dotnet/roslyn/issues/6477")] + public async Task NullNodeCrash() + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Threading.Tasks; - class Program + class C + { + static async void Main() { - private async void method() + try { - string content = await Task.Run(delegate () { - [|await Task.Delay(1000)|]; - return "Test"; - }); + [|await|] await Task.Delay(100); } - } - """, - """ - using System; - using System.Threading.Tasks; - - class Program - { - private async void method() + finally { - string content = await Task.Run(async delegate () { - await Task.Delay(1000); - return "Test"; - }); } } - """); - } + } + """); + } - [Fact] - public async Task AddAsyncInDelegate2() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + [WorkItem("https://github.com/dotnet/roslyn/issues/17470")] + public async Task AwaitInValueTaskMethod() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class Program + namespace System.Threading.Tasks { + struct ValueTask { - private void method() - { - string content = await Task.Run(delegate () { - [|await Task.Delay(1000)|]; - return "Test"; - }); - } } - """, - """ - using System; - using System.Threading.Tasks; + } - class Program + class Program + { + ValueTask Test() { - private void method() - { - string content = await Task.Run(async delegate () { - await Task.Delay(1000); - return "Test"; - }); - } + [|await Task.Delay(1);|] } - """); - } + } + """; - [Fact] - public async Task AddAsyncInDelegate3() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - class Program + namespace System.Threading.Tasks { + struct ValueTask { - private void method() - { - string content = await Task.Run(delegate () { - [|await Task.Delay(1000)|]; - return "Test"; - }); - } } - """, - """ - using System; - using System.Threading.Tasks; + } - class Program + class Program + { + async ValueTask Test() { - private void method() - { - string content = await Task.Run(async delegate () { - await Task.Delay(1000); - return "Test"; - }); - } + await Task.Delay(1); } - """); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact, WorkItem(6477, @"https://github.com/dotnet/roslyn/issues/6477")] - public async Task NullNodeCrash() - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task AwaitInValueTaskWithoutGenericMethod() + { + var initial = + """ + using System; + using System.Threading.Tasks; - class C + namespace System.Threading.Tasks { + struct ValueTask { - static async void Main() - { - try - { - [|await|] await Task.Delay(100); - } - finally - { - } - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - [WorkItem("https://github.com/dotnet/roslyn/issues/17470")] - public async Task AwaitInValueTaskMethod() - { - var initial = - """ - using System; - using System.Threading.Tasks; - - namespace System.Threading.Tasks { - struct ValueTask - { - } } + } - class Program + class Program + { + ValueTask Test() { - ValueTask Test() - { - [|await Task.Delay(1);|] - } + [|await Task.Delay(1);|] } - """; + } + """; - var expected = - """ - using System; - using System.Threading.Tasks; + var expected = + """ + using System; + using System.Threading.Tasks; - namespace System.Threading.Tasks { - struct ValueTask - { - } + namespace System.Threading.Tasks { + struct ValueTask + { } + } - class Program + class Program + { + async ValueTask Test() { - async ValueTask Test() - { - await Task.Delay(1); - } + await Task.Delay(1); } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """; + await TestInRegularAndScriptAsync(initial, expected); + } - [Fact] - public async Task AwaitInValueTaskWithoutGenericMethod() - { - var initial = - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14133")] + public async Task AddAsyncInLocalFunction() + { + await TestInRegularAndScriptAsync( + """ + using System.Threading.Tasks; - namespace System.Threading.Tasks { - struct ValueTask + class C + { + public void M1() + { + void M2() { + [|await M3Async();|] } } - class Program + async Task M3Async() { - ValueTask Test() - { - [|await Task.Delay(1);|] - } + return 1; } - """; + } + """, + """ + using System.Threading.Tasks; - var expected = - """ - using System; - using System.Threading.Tasks; - - namespace System.Threading.Tasks { - struct ValueTask + class C + { + public void M1() + { + async Task M2Async() { + await M3Async(); } } - class Program + async Task M3Async() { - async ValueTask Test() - { - await Task.Delay(1); - } + return 1; } - """; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14133")] - public async Task AddAsyncInLocalFunction() - { - await TestInRegularAndScriptAsync( - """ - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14133")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AddAsyncInLocalFunctionKeepVoidReturn() + { + await TestInRegularAndScriptAsync( + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - void M2() - { - [|await M3Async();|] - } - } - - async Task M3Async() + void M2() { - return 1; + [|await M3Async();|] } } - """, - """ - using System.Threading.Tasks; - class C + async Task M3Async() { - public void M1() - { - async Task M2Async() - { - await M3Async(); - } - } - - async Task M3Async() - { - return 1; - } + return 1; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14133")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AddAsyncInLocalFunctionKeepVoidReturn() - { - await TestInRegularAndScriptAsync( - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - void M2() - { - [|await M3Async();|] - } - } - - async Task M3Async() + async void M2() { - return 1; + await M3Async(); } } - """, - """ - using System.Threading.Tasks; - class C + async Task M3Async() { - public void M1() - { - async void M2() - { - await M3Async(); - } - } - - async Task M3Async() - { - return 1; - } + return 1; } - """, + } + """, index: 1); - } - - [Theory] - [InlineData(0, "void", "Task", "M2Async")] - [InlineData(1, "void", "void", "M2")] - [InlineData(0, "int", "Task", "M2Async")] - [InlineData(0, "Task", "Task", "M2")] - [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AddAsyncInLocalFunctionKeepsTrivia(int codeFixIndex, string initialReturn, string expectedReturn, string expectedName) - { - await TestInRegularAndScriptAsync( - $$""" - using System.Threading.Tasks; - - class C - { - public void M1() - { - // Leading trivia - /*1*/ {{initialReturn}} /*2*/ M2/*3*/() /*4*/ - { - [|await M3Async();|] - } - } - - async Task M3Async() - { - return 1; - } - } - """, - $$""" - using System.Threading.Tasks; + } - class C - { - public void M1() - { - // Leading trivia - /*1*/ async {{expectedReturn}} /*2*/ {{expectedName}}/*3*/() /*4*/ - { - await M3Async(); - } - } + [Theory] + [InlineData(0, "void", "Task", "M2Async")] + [InlineData(1, "void", "void", "M2")] + [InlineData(0, "int", "Task", "M2Async")] + [InlineData(0, "Task", "Task", "M2")] + [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AddAsyncInLocalFunctionKeepsTrivia(int codeFixIndex, string initialReturn, string expectedReturn, string expectedName) + { + await TestInRegularAndScriptAsync( + $$""" + using System.Threading.Tasks; - async Task M3Async() - { - return 1; - } - } - """, - index: codeFixIndex); - } - - [Theory] - [InlineData("", 0, "Task", "M2Async")] - [InlineData("", 1, "void", "M2")] - [InlineData("public", 0, "Task", "M2Async")] - [InlineData("public", 1, "void", "M2")] - [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] - public async Task AddAsyncKeepsTrivia(string modifiers, int codeFixIndex, string expectedReturn, string expectedName) - { - await TestInRegularAndScriptAsync( - $$""" - using System.Threading.Tasks; - - class C + class C + { + public void M1() { // Leading trivia - {{modifiers}}/*1*/ void /*2*/ M2/*3*/() /*4*/ + /*1*/ {{initialReturn}} /*2*/ M2/*3*/() /*4*/ { [|await M3Async();|] } + } - async Task M3Async() - { - return 1; - } + async Task M3Async() + { + return 1; } - """, - $$""" - using System.Threading.Tasks; + } + """, + $$""" + using System.Threading.Tasks; - class C + class C + { + public void M1() { // Leading trivia - {{modifiers}}/*1*/ async {{expectedReturn}} /*2*/ {{expectedName}}/*3*/() /*4*/ + /*1*/ async {{expectedReturn}} /*2*/ {{expectedName}}/*3*/() /*4*/ { await M3Async(); } - - async Task M3Async() - { - return 1; - } } - """, - index: codeFixIndex); - } - [Fact] - public async Task MethodWithAwaitUsing() - { - await TestInRegularAndScriptAsync( - """ - class C + async Task M3Async() { - void M() - { - [|await using (var x = new object())|] - { - } - } + return 1; } - """, - """ - using System.Threading.Tasks; + } + """, + index: codeFixIndex); + } - class C + [Theory] + [InlineData("", 0, "Task", "M2Async")] + [InlineData("", 1, "void", "M2")] + [InlineData("public", 0, "Task", "M2Async")] + [InlineData("public", 1, "void", "M2")] + [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33082")] + public async Task AddAsyncKeepsTrivia(string modifiers, int codeFixIndex, string expectedReturn, string expectedName) + { + await TestInRegularAndScriptAsync( + $$""" + using System.Threading.Tasks; + + class C + { + // Leading trivia + {{modifiers}}/*1*/ void /*2*/ M2/*3*/() /*4*/ { - async Task MAsync() - { - await using (var x = new object()) - { - } - } + [|await M3Async();|] } - """); - } - [Fact] - public async Task MethodWithRegularUsing() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + async Task M3Async() { - void M() - { - [|using (var x = new object())|] - { - } - } + return 1; } - """); - } + } + """, + $$""" + using System.Threading.Tasks; - [Fact] - public async Task MethodWithAwaitForEach() - { - await TestInRegularAndScriptAsync( - """ - class C + class C + { + // Leading trivia + {{modifiers}}/*1*/ async {{expectedReturn}} /*2*/ {{expectedName}}/*3*/() /*4*/ { - void M() - { - [|await foreach (var n in new int[] { })|] - { - } - } + await M3Async(); } - """, - """ - using System.Threading.Tasks; - class C + async Task M3Async() { - async Task MAsync() - { - await foreach (var n in new int[] { }) - { - } - } + return 1; } - """); - } + } + """, + index: codeFixIndex); + } - [Fact] - public async Task MethodWithRegularForEach() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task MethodWithAwaitUsing() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|await using (var x = new object())|] { - [|foreach (var n in new int[] { })|] - { - } } } - """); - } + } + """, + """ + using System.Threading.Tasks; - [Fact] - public async Task MethodWithAwaitForEachVariable() - { - await TestInRegularAndScriptAsync( - """ - class C + class C + { + async Task MAsync() { - void M() + await using (var x = new object()) { - [|await foreach (var (a, b) in new(int, int)[] { })|] - { - } } } - """, - """ - using System.Threading.Tasks; + } + """); + } - class C + [Fact] + public async Task MethodWithRegularUsing() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - async Task MAsync() + [|using (var x = new object())|] { - await foreach (var (a, b) in new(int, int)[] { }) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task MethodWithRegularForEachVariable() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task MethodWithAwaitForEach() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|await foreach (var n in new int[] { })|] { - [|foreach (var (a, b) in new(int, int)[] { })|] - { - } } } - """); - } + } + """, + """ + using System.Threading.Tasks; - [Fact] - public async Task MethodWithNullableReturn() - { - await TestInRegularAndScriptAsync( - """ - #nullable enable - using System.Threading.Tasks; - class C + class C + { + async Task MAsync() { - string? M() + await foreach (var n in new int[] { }) { - [|await Task.Delay(1);|] - return null; } } - """, - """ - #nullable enable - using System.Threading.Tasks; - class C + } + """); + } + + [Fact] + public async Task MethodWithRegularForEach() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - async Task MAsync() + [|foreach (var n in new int[] { })|] { - await Task.Delay(1); - return null; } } - """); - } + } + """); + } - [Fact] - public async Task EnumerableMethodWithNullableType() - { - var initial = - """ - #nullable enable - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + [Fact] + public async Task MethodWithAwaitForEachVariable() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - IEnumerable Test() + [|await foreach (var (a, b) in new(int, int)[] { })|] { - yield return string.Empty; - [|await Task.Delay(1);|] } } - """ + IAsyncEnumerable; + } + """, + """ + using System.Threading.Tasks; - var expected = - """ - #nullable enable - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + class C + { + async Task MAsync() { - async IAsyncEnumerable TestAsync() + await foreach (var (a, b) in new(int, int)[] { }) { - yield return string.Empty; - await Task.Delay(1); - } - } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } - - [Fact] - public async Task EnumeratorMethodWithNullableType() - { - var initial = - """ - #nullable enable - using System.Threading.Tasks; - using System.Collections.Generic; - class Program - { - IEnumerator Test() - { - yield return string.Empty; - [|await Task.Delay(1);|] } } - """ + IAsyncEnumerable; + } + """); + } - var expected = - """ - #nullable enable - using System.Threading.Tasks; - using System.Collections.Generic; - class Program + [Fact] + public async Task MethodWithRegularForEachVariable() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - async IAsyncEnumerator TestAsync() + [|foreach (var (a, b) in new(int, int)[] { })|] { - yield return string.Empty; - await Task.Delay(1); } } - """ + IAsyncEnumerable; - await TestInRegularAndScriptAsync(initial, expected); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25446")] - public async Task TestOnAwaitParsedAsType() - { - var initial = - """ - using System.Threading.Tasks; + [Fact] + public async Task MethodWithNullableReturn() + { + await TestInRegularAndScriptAsync( + """ + #nullable enable + using System.Threading.Tasks; + class C + { + string? M() + { + [|await Task.Delay(1);|] + return null; + } + } + """, + """ + #nullable enable + using System.Threading.Tasks; + class C + { + async Task MAsync() + { + await Task.Delay(1); + return null; + } + } + """); + } - class C + [Fact] + public async Task EnumerableMethodWithNullableType() + { + var initial = + """ + #nullable enable + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerable Test() + { + yield return string.Empty; + [|await Task.Delay(1);|] + } + } + """ + IAsyncEnumerable; + + var expected = + """ + #nullable enable + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerable TestAsync() + { + yield return string.Empty; + await Task.Delay(1); + } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } + + [Fact] + public async Task EnumeratorMethodWithNullableType() + { + var initial = + """ + #nullable enable + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + IEnumerator Test() + { + yield return string.Empty; + [|await Task.Delay(1);|] + } + } + """ + IAsyncEnumerable; + + var expected = + """ + #nullable enable + using System.Threading.Tasks; + using System.Collections.Generic; + class Program + { + async IAsyncEnumerator TestAsync() + { + yield return string.Empty; + await Task.Delay(1); + } + } + """ + IAsyncEnumerable; + await TestInRegularAndScriptAsync(initial, expected); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25446")] + public async Task TestOnAwaitParsedAsType() + { + var initial = + """ + using System.Threading.Tasks; + + class C + { + void M() { - void M() - { - Task task = null; - [|await|] task; - } + Task task = null; + [|await|] task; } - """; + } + """; - var expected = - """ - using System.Threading.Tasks; + var expected = + """ + using System.Threading.Tasks; - class C + class C + { + async Task MAsync() { - async Task MAsync() - { - Task task = null; - await task; - } + Task task = null; + await task; } - """; - await TestInRegularAndScript1Async(initial, expected); - } + } + """; + await TestInRegularAndScript1Async(initial, expected); } } diff --git a/src/Analyzers/CSharp/Tests/MakeMethodSynchronous/MakeMethodSynchronousTests.cs b/src/Analyzers/CSharp/Tests/MakeMethodSynchronous/MakeMethodSynchronousTests.cs index 5b8e275be6ed9..a1ec1bf721a4f 100644 --- a/src/Analyzers/CSharp/Tests/MakeMethodSynchronous/MakeMethodSynchronousTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeMethodSynchronous/MakeMethodSynchronousTests.cs @@ -10,1098 +10,1097 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeMethodSynchronous -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpMakeMethodSynchronousCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeMethodSynchronous; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpMakeMethodSynchronousCodeFixProvider>; - public class MakeMethodSynchronousTests +public class MakeMethodSynchronousTests +{ + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestTaskReturnType() { - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestTaskReturnType() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() - { - } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestTaskOfTReturnType() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestTaskOfTReturnType() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() - { - return 1; - } + return 1; } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + int {|#0:Goo|}() { - int {|#0:Goo|}() - { - return 1; - } + return 1; } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestSecondModifier() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestSecondModifier() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + public async Task {|CS1998:Goo|}() { - public async Task {|CS1998:Goo|}() - { - } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void Goo() { - public void Goo() - { - } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestFirstModifier() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestFirstModifier() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async public Task {|CS1998:Goo|}() { - async public Task {|CS1998:Goo|}() - { - } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void Goo() { - public void Goo() - { - } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestTrailingTrivia() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestTrailingTrivia() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async // comment + Task {|CS1998:Goo|}() { - async // comment - Task {|CS1998:Goo|}() - { - } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestRenameMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestRenameMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:GooAsync|}() { - async Task {|CS1998:GooAsync|}() - { - } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestRenameMethod1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestRenameMethod1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:GooAsync|}() { - async Task {|CS1998:GooAsync|}() - { - } + } - void Bar() - { - GooAsync(); - } + void Bar() + { + GooAsync(); } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - } + } - void Bar() - { - Goo(); - } + void Bar() + { + Goo(); } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestParenthesizedLambda() - { - var source = - """ - using System; - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestParenthesizedLambda() + { + var source = + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = - async () {|CS1998:=>|} { }; - } + Func f = + async () {|CS1998:=>|} { }; } - """; - var expected = - """ - using System; - using System.Threading.Tasks; - - class C + } + """; + var expected = + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() - { - Func f = - () {|#0:=>|} { }; - } + Func f = + () {|#0:=>|} { }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedState = { - TestCode = source, - FixedState = + Sources = { expected }, + ExpectedDiagnostics = { - Sources = { expected }, - ExpectedDiagnostics = - { - // /0/Test0.cs(10,16): error CS1643: Not all code paths return a value in lambda expression of type 'Func' - DiagnosticResult.CompilerError("CS1643").WithLocation(0), - }, + // /0/Test0.cs(10,16): error CS1643: Not all code paths return a value in lambda expression of type 'Func' + DiagnosticResult.CompilerError("CS1643").WithLocation(0), }, - }.RunAsync(); - } + }, + }.RunAsync(); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestSimpleLambda() - { - var source = - """ - using System; - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestSimpleLambda() + { + var source = + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = - async a {|CS1998:=>|} { }; - } + Func f = + async a {|CS1998:=>|} { }; } - """; - var expected = - """ - using System; - using System.Threading.Tasks; - - class C + } + """; + var expected = + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() - { - Func f = - a {|#0:=>|} { }; - } + Func f = + a {|#0:=>|} { }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedState = { - TestCode = source, - FixedState = + Sources = { expected }, + ExpectedDiagnostics = { - Sources = { expected }, - ExpectedDiagnostics = - { - // /0/Test0.cs(10,15): error CS1643: Not all code paths return a value in lambda expression of type 'Func' - DiagnosticResult.CompilerError("CS1643").WithLocation(0), - }, + // /0/Test0.cs(10,15): error CS1643: Not all code paths return a value in lambda expression of type 'Func' + DiagnosticResult.CompilerError("CS1643").WithLocation(0), }, - }.RunAsync(); - } + }, + }.RunAsync(); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestLambdaWithExpressionBody() - { - var source = - """ - using System; - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestLambdaWithExpressionBody() + { + var source = + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = - async a {|CS1998:=>|} 1; - } + Func> f = + async a {|CS1998:=>|} 1; } - """; - var expected = - """ - using System; - using System.Threading.Tasks; - - class C + } + """; + var expected = + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() - { - Func> f = - a => {|#0:1|}; - } + Func> f = + a => {|#0:1|}; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedState = { - TestCode = source, - FixedState = + Sources = { expected }, + ExpectedDiagnostics = { - Sources = { expected }, - ExpectedDiagnostics = - { - // /0/Test0.cs(10,18): error CS0029: Cannot implicitly convert type 'int' to 'System.Threading.Tasks.Task' - DiagnosticResult.CompilerError("CS0029").WithLocation(0).WithArguments("int", "System.Threading.Tasks.Task"), - // /0/Test0.cs(10,18): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type - DiagnosticResult.CompilerError("CS1662").WithLocation(0), - }, + // /0/Test0.cs(10,18): error CS0029: Cannot implicitly convert type 'int' to 'System.Threading.Tasks.Task' + DiagnosticResult.CompilerError("CS0029").WithLocation(0).WithArguments("int", "System.Threading.Tasks.Task"), + // /0/Test0.cs(10,18): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type + DiagnosticResult.CompilerError("CS1662").WithLocation(0), }, - }.RunAsync(); - } + }, + }.RunAsync(); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestAnonymousMethod() - { - var source = - """ - using System; - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestAnonymousMethod() + { + var source = + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = - async {|CS1998:delegate|} { }; - } + Func f = + async {|CS1998:delegate|} { }; } - """; - var expected = - """ - using System; - using System.Threading.Tasks; - - class C + } + """; + var expected = + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() - { - Func f = - {|#0:delegate|} { }; - } + Func f = + {|#0:delegate|} { }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedState = { - TestCode = source, - FixedState = + Sources = { expected }, + ExpectedDiagnostics = { - Sources = { expected }, - ExpectedDiagnostics = - { - // /0/Test0.cs(10,13): error CS1643: Not all code paths return a value in anonymous method of type 'Func' - DiagnosticResult.CompilerError("CS1643").WithLocation(0), - }, + // /0/Test0.cs(10,13): error CS1643: Not all code paths return a value in anonymous method of type 'Func' + DiagnosticResult.CompilerError("CS1643").WithLocation(0), }, - }.RunAsync(); - } + }, + }.RunAsync(); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestFixAll() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestFixAll() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - public class Class1 + public class Class1 + { + async Task {|CS1998:GooAsync|}() { - async Task {|CS1998:GooAsync|}() - { - BarAsync(); - } + BarAsync(); + } - async Task {|#0:{|CS1998:BarAsync|}|}() - { - GooAsync(); - return 1; - } + async Task {|#0:{|CS1998:BarAsync|}|}() + { + GooAsync(); + return 1; } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - public class Class1 + public class Class1 + { + void Goo() { - void Goo() - { - Bar(); - } + Bar(); + } - int {|#0:Bar|}() - { - Goo(); - return 1; - } + int {|#0:Bar|}() + { + Goo(); + return 1; } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] - public async Task TestRemoveAwaitFromCaller1() - { - var source = - """ - using System.Threading.Tasks; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] + public async Task TestRemoveAwaitFromCaller1() + { + var source = + """ + using System.Threading.Tasks; - public class Class1 + public class Class1 + { + async Task {|CS1998:GooAsync|}() { - async Task {|CS1998:GooAsync|}() - { - } - - async void BarAsync() - { - await GooAsync(); - } } - """; - var expected = - """ - using System.Threading.Tasks; - public class Class1 + async void BarAsync() { - void Goo() - { - } - - async void {|CS1998:BarAsync|}() - { - Goo(); - } + await GooAsync(); } - """; + } + """; + var expected = + """ + using System.Threading.Tasks; - await new VerifyCS.Test + public class Class1 { - TestCode = source, - FixedState = + void Goo() { - Sources = { expected }, - MarkupHandling = MarkupMode.Allow, - }, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - }.RunAsync(); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] - public async Task TestRemoveAwaitFromCaller2() + async void {|CS1998:BarAsync|}() + { + Goo(); + } + } + """; + + await new VerifyCS.Test { - var source = - """ - using System.Threading.Tasks; + TestCode = source, + FixedState = + { + Sources = { expected }, + MarkupHandling = MarkupMode.Allow, + }, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + }.RunAsync(); + } - public class Class1 - { - async Task {|CS1998:GooAsync|}() - { - } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] + public async Task TestRemoveAwaitFromCaller2() + { + var source = + """ + using System.Threading.Tasks; - async void BarAsync() - { - await GooAsync().ConfigureAwait(false); - } + public class Class1 + { + async Task {|CS1998:GooAsync|}() + { } - """; - var expected = - """ - using System.Threading.Tasks; - public class Class1 + async void BarAsync() { - void Goo() - { - } - - async void {|CS1998:BarAsync|}() - { - Goo(); - } + await GooAsync().ConfigureAwait(false); } - """; + } + """; + var expected = + """ + using System.Threading.Tasks; - await new VerifyCS.Test + public class Class1 { - TestCode = source, - FixedState = + void Goo() { - Sources = { expected }, - MarkupHandling = MarkupMode.Allow, - }, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - }.RunAsync(); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] - public async Task TestRemoveAwaitFromCaller3() + async void {|CS1998:BarAsync|}() + { + Goo(); + } + } + """; + + await new VerifyCS.Test { - var source = - """ - using System.Threading.Tasks; + TestCode = source, + FixedState = + { + Sources = { expected }, + MarkupHandling = MarkupMode.Allow, + }, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + }.RunAsync(); + } - public class Class1 - { - async Task {|CS1998:GooAsync|}() - { - } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] + public async Task TestRemoveAwaitFromCaller3() + { + var source = + """ + using System.Threading.Tasks; - async void BarAsync() - { - await this.GooAsync(); - } + public class Class1 + { + async Task {|CS1998:GooAsync|}() + { } - """; - var expected = - """ - using System.Threading.Tasks; - public class Class1 + async void BarAsync() { - void Goo() - { - } - - async void {|CS1998:BarAsync|}() - { - this.Goo(); - } + await this.GooAsync(); } - """; + } + """; + var expected = + """ + using System.Threading.Tasks; - await new VerifyCS.Test + public class Class1 { - TestCode = source, - FixedState = + void Goo() { - Sources = { expected }, - MarkupHandling = MarkupMode.Allow, - }, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - }.RunAsync(); - } + } + + async void {|CS1998:BarAsync|}() + { + this.Goo(); + } + } + """; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] - public async Task TestRemoveAwaitFromCaller4() + await new VerifyCS.Test { - var source = - """ - using System.Threading.Tasks; + TestCode = source, + FixedState = + { + Sources = { expected }, + MarkupHandling = MarkupMode.Allow, + }, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + }.RunAsync(); + } - public class Class1 - { - async Task {|CS1998:GooAsync|}() - { - } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] + public async Task TestRemoveAwaitFromCaller4() + { + var source = + """ + using System.Threading.Tasks; - async void BarAsync() - { - await this.GooAsync().ConfigureAwait(false); - } + public class Class1 + { + async Task {|CS1998:GooAsync|}() + { } - """; - var expected = - """ - using System.Threading.Tasks; - public class Class1 + async void BarAsync() { - void Goo() - { - } - - async void {|CS1998:BarAsync|}() - { - this.Goo(); - } + await this.GooAsync().ConfigureAwait(false); } - """; + } + """; + var expected = + """ + using System.Threading.Tasks; - await new VerifyCS.Test + public class Class1 { - TestCode = source, - FixedState = + void Goo() { - Sources = { expected }, - MarkupHandling = MarkupMode.Allow, - }, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - }.RunAsync(); - } + } + + async void {|CS1998:BarAsync|}() + { + this.Goo(); + } + } + """; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] - public async Task TestRemoveAwaitFromCallerNested1() + await new VerifyCS.Test { - var source = - """ - using System.Threading.Tasks; + TestCode = source, + FixedState = + { + Sources = { expected }, + MarkupHandling = MarkupMode.Allow, + }, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + }.RunAsync(); + } - public class Class1 - { - async Task {|CS1998:GooAsync|}(int i) - { - return 1; - } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] + public async Task TestRemoveAwaitFromCallerNested1() + { + var source = + """ + using System.Threading.Tasks; - async void BarAsync() - { - await this.GooAsync(await this.GooAsync(0)); - } + public class Class1 + { + async Task {|CS1998:GooAsync|}(int i) + { + return 1; } - """; - var expected = - """ - using System.Threading.Tasks; - public class Class1 + async void BarAsync() { - int Goo(int i) - { - return 1; - } - - async void {|CS1998:BarAsync|}() - { - this.Goo(this.Goo(0)); - } + await this.GooAsync(await this.GooAsync(0)); } - """; + } + """; + var expected = + """ + using System.Threading.Tasks; - await new VerifyCS.Test + public class Class1 { - TestCode = source, - FixedState = + int Goo(int i) { - Sources = { expected }, - MarkupHandling = MarkupMode.Allow, - }, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - }.RunAsync(); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] - public async Task TestRemoveAwaitFromCallerNested() - { - var source = - """ - using System.Threading.Tasks; + return 1; + } - public class Class1 + async void {|CS1998:BarAsync|}() { - async Task {|CS1998:GooAsync|}(int i) - { - return 1; - } - - async void BarAsync() - { - await this.GooAsync(await this.GooAsync(0).ConfigureAwait(false)).ConfigureAwait(false); - } + this.Goo(this.Goo(0)); } - """; - var expected = - """ - using System.Threading.Tasks; + } + """; - public class Class1 - { - int Goo(int i) - { - return 1; - } + await new VerifyCS.Test + { + TestCode = source, + FixedState = + { + Sources = { expected }, + MarkupHandling = MarkupMode.Allow, + }, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + }.RunAsync(); + } - async void {|CS1998:BarAsync|}() - { - this.Goo(this.Goo(0)); - } - } - """; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/13961")] + public async Task TestRemoveAwaitFromCallerNested() + { + var source = + """ + using System.Threading.Tasks; - await new VerifyCS.Test + public class Class1 { - TestCode = source, - FixedState = + async Task {|CS1998:GooAsync|}(int i) { - Sources = { expected }, - MarkupHandling = MarkupMode.Allow, - }, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - }.RunAsync(); - } + return 1; + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/14133")] - public async Task RemoveAsyncInLocalFunction() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + async void BarAsync() + { + await this.GooAsync(await this.GooAsync(0).ConfigureAwait(false)).ConfigureAwait(false); + } + } + """; + var expected = + """ + using System.Threading.Tasks; - class C + public class Class1 + { + int Goo(int i) { - public void M1() - { - async Task {|CS1998:M2Async|}() - { - } - } + return 1; } - """, - """ - using System.Threading.Tasks; - class C + async void {|CS1998:BarAsync|}() { - public void M1() - { - void M2() - { - } - } + this.Goo(this.Goo(0)); } - """); - } - - [Theory] - [InlineData("Task", "C")] - [InlineData("Task", "int")] - [InlineData("Task", "void")] - [InlineData("void", "void")] - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] - public async Task RemoveAsyncInLocalFunctionKeepsTrivia(string asyncReturn, string expectedReturn) + } + """; + + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - $$""" - using System; - using System.Threading.Tasks; + TestCode = source, + FixedState = + { + Sources = { expected }, + MarkupHandling = MarkupMode.Allow, + }, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + }.RunAsync(); + } - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/14133")] + public async Task RemoveAsyncInLocalFunction() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; + + class C + { + public void M1() { - public void M1() + async Task {|CS1998:M2Async|}() { - // Leading trivia - /*1*/ async {{asyncReturn}} /*2*/ {|CS1998:M2Async|}/*3*/() /*4*/ - { - throw new NotImplementedException(); - } } } - """, - $$""" - using System; - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + void M2() { - // Leading trivia - /*1*/ - {{expectedReturn}} /*2*/ M2/*3*/() /*4*/ - { - throw new NotImplementedException(); - } } } - """); - } - - [Theory] - [InlineData("", "Task", "\r\n C")] - [InlineData("", "Task", "\r\n int")] - [InlineData("", "Task", "\r\n void")] - [InlineData("", "void", "\r\n void")] - [InlineData("public", "Task", " C")] - [InlineData("public", "Task", " int")] - [InlineData("public", "Task", " void")] - [InlineData("public", "void", " void")] - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] - [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] - public async Task RemoveAsyncKeepsTrivia(string modifiers, string asyncReturn, string expectedReturn) - { - await VerifyCS.VerifyCodeFixAsync( - $$""" - using System; - using System.Threading.Tasks; + } + """); + } - class C + [Theory] + [InlineData("Task", "C")] + [InlineData("Task", "int")] + [InlineData("Task", "void")] + [InlineData("void", "void")] + [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] + public async Task RemoveAsyncInLocalFunctionKeepsTrivia(string asyncReturn, string expectedReturn) + { + await VerifyCS.VerifyCodeFixAsync( + $$""" + using System; + using System.Threading.Tasks; + + class C + { + public void M1() { // Leading trivia - {{modifiers}}/*1*/ async {{asyncReturn}} /*2*/ {|CS1998:M2Async|}/*3*/() /*4*/ + /*1*/ async {{asyncReturn}} /*2*/ {|CS1998:M2Async|}/*3*/() /*4*/ { throw new NotImplementedException(); } } - """, - $$""" - using System; - using System.Threading.Tasks; + } + """, + $$""" + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { // Leading trivia - {{modifiers}}/*1*/{{expectedReturn}} /*2*/ M2/*3*/() /*4*/ + /*1*/ + {{expectedReturn}} /*2*/ M2/*3*/() /*4*/ { throw new NotImplementedException(); } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task MethodWithUsingAwait() - { - var source = - """ - class C + [Theory] + [InlineData("", "Task", "\r\n C")] + [InlineData("", "Task", "\r\n int")] + [InlineData("", "Task", "\r\n void")] + [InlineData("", "void", "\r\n void")] + [InlineData("public", "Task", " C")] + [InlineData("public", "Task", " int")] + [InlineData("public", "Task", " void")] + [InlineData("public", "void", " void")] + [Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodAsynchronous)] + [WorkItem("https://github.com/dotnet/roslyn/issues/18307")] + public async Task RemoveAsyncKeepsTrivia(string modifiers, string asyncReturn, string expectedReturn) + { + await VerifyCS.VerifyCodeFixAsync( + $$""" + using System; + using System.Threading.Tasks; + + class C + { + // Leading trivia + {{modifiers}}/*1*/ async {{asyncReturn}} /*2*/ {|CS1998:M2Async|}/*3*/() /*4*/ { - async System.Threading.Tasks.Task MAsync() - { - await using ({|#0:var x = new object()|}) - { - } - } + throw new NotImplementedException(); } - """; + } + """, + $$""" + using System; + using System.Threading.Tasks; - await new VerifyCS.Test + class C { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - ExpectedDiagnostics = + // Leading trivia + {{modifiers}}/*1*/{{expectedReturn}} /*2*/ M2/*3*/() /*4*/ { - // /0/Test0.cs(5,22): error CS8410: 'object': type used in an asynchronous using statement must be implicitly convertible to 'System.IAsyncDisposable' or implement a suitable 'DisposeAsync' method. - DiagnosticResult.CompilerError("CS8410").WithLocation(0).WithArguments("object"), - }, - FixedCode = source, - }.RunAsync(); - } + throw new NotImplementedException(); + } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task MethodWithUsingNoAwait() + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task MethodWithUsingAwait() + { + var source = + """ + class C + { + async System.Threading.Tasks.Task MAsync() + { + await using ({|#0:var x = new object()|}) + { + } + } + } + """; + + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + ExpectedDiagnostics = + { + // /0/Test0.cs(5,22): error CS8410: 'object': type used in an asynchronous using statement must be implicitly convertible to 'System.IAsyncDisposable' or implement a suitable 'DisposeAsync' method. + DiagnosticResult.CompilerError("CS8410").WithLocation(0).WithArguments("object"), + }, + FixedCode = source, + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task MethodWithUsingNoAwait() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + async System.Threading.Tasks.Task {|CS1998:MAsync|}() { - async System.Threading.Tasks.Task {|CS1998:MAsync|}() + using ({|#0:var x = new object()|}) { - using ({|#0:var x = new object()|}) - { - } } } - """, - // /0/Test0.cs(5,16): error CS1674: 'object': type used in a using statement must be implicitly convertible to 'System.IDisposable'. - DiagnosticResult.CompilerError("CS1674").WithLocation(0).WithArguments("object"), - """ - class C + } + """, + // /0/Test0.cs(5,16): error CS1674: 'object': type used in a using statement must be implicitly convertible to 'System.IDisposable'. + DiagnosticResult.CompilerError("CS1674").WithLocation(0).WithArguments("object"), + """ + class C + { + void M() { - void M() + using ({|#0:var x = new object()|}) { - using ({|#0:var x = new object()|}) - { - } } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task MethodWithAwaitForEach() - { - var source = - """ - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task MethodWithAwaitForEach() + { + var source = + """ + class C + { + async System.Threading.Tasks.Task MAsync() { - async System.Threading.Tasks.Task MAsync() + await foreach (var n in {|#0:new int[] { }|}) { - await foreach (var n in {|#0:new int[] { }|}) - { - } } } - """; - - await VerifyCS.VerifyCodeFixAsync( - source, - // /0/Test0.cs(5,33): error CS1061: 'bool' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) - DiagnosticResult.CompilerError("CS1061").WithLocation(0).WithArguments("bool", "GetAwaiter"), - source); - } + } + """; + + await VerifyCS.VerifyCodeFixAsync( + source, + // /0/Test0.cs(5,33): error CS1061: 'bool' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) + DiagnosticResult.CompilerError("CS1061").WithLocation(0).WithArguments("bool", "GetAwaiter"), + source); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task MethodWithForEachNoAwait() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task MethodWithForEachNoAwait() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + async System.Threading.Tasks.Task {|CS1998:MAsync|}() { - async System.Threading.Tasks.Task {|CS1998:MAsync|}() + foreach (var n in new int[] { }) { - foreach (var n in new int[] { }) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + foreach (var n in new int[] { }) { - foreach (var n in new int[] { }) - { - } } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task MethodWithForEachVariableAwait() - { - var source = - """ - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task MethodWithForEachVariableAwait() + { + var source = + """ + class C + { + async System.Threading.Tasks.Task MAsync() { - async System.Threading.Tasks.Task MAsync() + await foreach (var (a, b) in {|#0:new(int, int)[] { }|}) { - await foreach (var (a, b) in {|#0:new(int, int)[] { }|}) - { - } } } - """; - - await VerifyCS.VerifyCodeFixAsync( - source, - // /0/Test0.cs(5,38): error CS1061: 'bool' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) - DiagnosticResult.CompilerError("CS1061").WithLocation(0).WithArguments("bool", "GetAwaiter"), - source); - } + } + """; + + await VerifyCS.VerifyCodeFixAsync( + source, + // /0/Test0.cs(5,38): error CS1061: 'bool' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) + DiagnosticResult.CompilerError("CS1061").WithLocation(0).WithArguments("bool", "GetAwaiter"), + source); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task MethodWithForEachVariableNoAwait() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task MethodWithForEachVariableNoAwait() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + async System.Threading.Tasks.Task {|CS1998:MAsync|}() { - async System.Threading.Tasks.Task {|CS1998:MAsync|}() + foreach (var (a, b) in new(int, int)[] { }) { - foreach (var (a, b) in new(int, int)[] { }) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + foreach (var (a, b) in new (int, int)[] { }) { - foreach (var (a, b) in new (int, int)[] { }) - { - } } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestIAsyncEnumerableReturnType() - { - var source = - """ - using System.Threading.Tasks; - using System.Collections.Generic; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestIAsyncEnumerableReturnType() + { + var source = + """ + using System.Threading.Tasks; + using System.Collections.Generic; - class C + class C + { + async IAsyncEnumerable {|CS1998:MAsync|}() { - async IAsyncEnumerable {|CS1998:MAsync|}() - { - yield return 1; - } + yield return 1; } - """; - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - - class C + } + """; + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + + class C + { + IEnumerable M() { - IEnumerable M() - { - yield return 1; - } + yield return 1; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - FixedCode = expected, - }.RunAsync(); - } + } + """; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] - public async Task TestIAsyncEnumeratorReturnTypeOnLocalFunction() + await new VerifyCS.Test { - var source = - """ - using System.Threading.Tasks; - using System.Collections.Generic; + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + FixedCode = expected, + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeMethodSynchronous)] + public async Task TestIAsyncEnumeratorReturnTypeOnLocalFunction() + { + var source = + """ + using System.Threading.Tasks; + using System.Collections.Generic; - class C + class C + { + void Method() { - void Method() + async IAsyncEnumerator {|CS1998:MAsync|}() { - async IAsyncEnumerator {|CS1998:MAsync|}() - { - yield return 1; - } + yield return 1; } } - """; - var expected = - """ - using System.Threading.Tasks; - using System.Collections.Generic; - - class C + } + """; + var expected = + """ + using System.Threading.Tasks; + using System.Collections.Generic; + + class C + { + void Method() { - void Method() + IEnumerator M() { - IEnumerator M() - { - yield return 1; - } + yield return 1; } } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - FixedCode = expected, - }.RunAsync(); - } + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + FixedCode = expected, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/MakeRefStruct/MakeRefStructTests.cs b/src/Analyzers/CSharp/Tests/MakeRefStruct/MakeRefStructTests.cs index f4c774d0c0a4b..151a515c1e686 100644 --- a/src/Analyzers/CSharp/Tests/MakeRefStruct/MakeRefStructTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeRefStruct/MakeRefStructTests.cs @@ -16,246 +16,245 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeRefStruct +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeRefStruct; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeRefStruct)] +public class MakeRefStructTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeRefStruct)] - public class MakeRefStructTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + private static readonly CSharpParseOptions s_parseOptions = + CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3); + + public MakeRefStructTests(ITestOutputHelper logger) + : base(logger) { - private static readonly CSharpParseOptions s_parseOptions = - CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_3); + } - public MakeRefStructTests(ITestOutputHelper logger) - : base(logger) + private const string SpanDeclarationSourceText = """ + using System; + namespace System { - } - - private const string SpanDeclarationSourceText = """ - using System; - namespace System + public readonly ref struct Span { - public readonly ref struct Span - { - unsafe public Span(void* pointer, int length) { } - } + unsafe public Span(void* pointer, int length) { } } + } - """; + """; - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new MakeRefStructCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new MakeRefStructCodeFixProvider()); - [Fact] - public async Task FieldInNotRefStruct() - { - var text = CreateTestSource(""" - struct S - { - Span[||] m; - } - """); - var expected = CreateTestSource(""" - ref struct S - { - Span m; - } - """); - await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); - } + [Fact] + public async Task FieldInNotRefStruct() + { + var text = CreateTestSource(""" + struct S + { + Span[||] m; + } + """); + var expected = CreateTestSource(""" + ref struct S + { + Span m; + } + """); + await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); + } - [Fact] - public async Task FieldInRecordStruct() - { - var text = CreateTestSource(""" - record struct S + [Fact] + public async Task FieldInRecordStruct() + { + var text = CreateTestSource(""" + record struct S + { + Span[||] m; + } + """); + await TestMissingInRegularAndScriptAsync(text, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp12))); + } + + [Fact] + public async Task FieldInNestedClassInsideNotRefStruct() + { + var text = CreateTestSource(""" + struct S + { + class C { Span[||] m; } - """); - await TestMissingInRegularAndScriptAsync(text, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp12))); - } + } + """); + await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); + } - [Fact] - public async Task FieldInNestedClassInsideNotRefStruct() - { - var text = CreateTestSource(""" - struct S - { - class C - { - Span[||] m; - } - } - """); - await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); - } + [Fact] + public async Task FieldStaticInRefStruct() + { + // Note: does not compile + var text = CreateTestSource(""" + ref struct S + { + static Span[||] m; + } + """); + await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); + } - [Fact] - public async Task FieldStaticInRefStruct() - { - // Note: does not compile - var text = CreateTestSource(""" - ref struct S - { - static Span[||] m; - } - """); - await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); - } + [Fact] + public async Task FieldStaticInNotRefStruct() + { + var text = CreateTestSource(""" + struct S + { + static Span[||] m; + } + """); + // Note: still does not compile after fix + var expected = CreateTestSource(""" + ref struct S + { + static Span m; + } + """); + await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); + } - [Fact] - public async Task FieldStaticInNotRefStruct() - { - var text = CreateTestSource(""" - struct S - { - static Span[||] m; - } - """); - // Note: still does not compile after fix - var expected = CreateTestSource(""" - ref struct S - { - static Span m; - } - """); - await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); - } + [Fact] + public async Task PropInNotRefStruct() + { + var text = CreateTestSource(""" + struct S + { + Span[||] M { get; } + } + """); + var expected = CreateTestSource(""" + ref struct S + { + Span M { get; } + } + """); + await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); + } - [Fact] - public async Task PropInNotRefStruct() - { - var text = CreateTestSource(""" - struct S + [Fact] + public async Task PropInNestedClassInsideNotRefStruct() + { + // Note: does not compile + var text = CreateTestSource(""" + struct S + { + class C { Span[||] M { get; } } - """); - var expected = CreateTestSource(""" - ref struct S - { - Span M { get; } - } - """); - await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); - } - - [Fact] - public async Task PropInNestedClassInsideNotRefStruct() - { - // Note: does not compile - var text = CreateTestSource(""" - struct S - { - class C - { - Span[||] M { get; } - } - } - """); - await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); - } - - [Fact] - public async Task PropStaticInRefStruct() - { - // Note: does not compile - var text = CreateTestSource(""" - ref struct S - { - static Span[||] M { get; } - } - """); - await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); - } + } + """); + await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); + } - [Fact] - public async Task PropStaticInNotRefStruct() - { - var text = CreateTestSource(""" - struct S - { - static Span[||] M { get; } - } - """); - // Note: still does not compile after fix - var expected = CreateTestSource(""" - ref struct S - { - static Span M { get; } - } - """); - await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); - } + [Fact] + public async Task PropStaticInRefStruct() + { + // Note: does not compile + var text = CreateTestSource(""" + ref struct S + { + static Span[||] M { get; } + } + """); + await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); + } - [Fact] - public async Task PartialByRefStruct() - { - var text = CreateTestSource(""" - ref partial struct S - { - } + [Fact] + public async Task PropStaticInNotRefStruct() + { + var text = CreateTestSource(""" + struct S + { + static Span[||] M { get; } + } + """); + // Note: still does not compile after fix + var expected = CreateTestSource(""" + ref struct S + { + static Span M { get; } + } + """); + await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); + } - struct S - { - Span[||] M { get; } - } - """); - await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); - } + [Fact] + public async Task PartialByRefStruct() + { + var text = CreateTestSource(""" + ref partial struct S + { + } - [Fact] - public async Task PartialStruct() - { - var text = CreateTestSource(""" - partial struct S - { - } + struct S + { + Span[||] M { get; } + } + """); + await TestMissingInRegularAndScriptAsync(text, new TestParameters(s_parseOptions)); + } - partial struct S - { - Span[||] M { get; } - } - """); - var expected = CreateTestSource(""" - partial struct S - { - } + [Fact] + public async Task PartialStruct() + { + var text = CreateTestSource(""" + partial struct S + { + } - ref partial struct S - { - Span[||] M { get; } - } - """); - await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); - } + partial struct S + { + Span[||] M { get; } + } + """); + var expected = CreateTestSource(""" + partial struct S + { + } - [Fact] - public async Task ReadonlyPartialStruct() - { - var text = CreateTestSource(""" - partial struct S - { - } + ref partial struct S + { + Span[||] M { get; } + } + """); + await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); + } - readonly partial struct S - { - Span[||] M { get; } - } - """); - var expected = CreateTestSource(""" - partial struct S - { - } + [Fact] + public async Task ReadonlyPartialStruct() + { + var text = CreateTestSource(""" + partial struct S + { + } - readonly ref partial struct S - { - Span[||] M { get; } - } - """); - await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); - } + readonly partial struct S + { + Span[||] M { get; } + } + """); + var expected = CreateTestSource(""" + partial struct S + { + } - private static string CreateTestSource(string testSource) => SpanDeclarationSourceText + testSource; + readonly ref partial struct S + { + Span[||] M { get; } + } + """); + await TestInRegularAndScriptAsync(text, expected, parseOptions: s_parseOptions); } + + private static string CreateTestSource(string testSource) => SpanDeclarationSourceText + testSource; } diff --git a/src/Analyzers/CSharp/Tests/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixTests.cs b/src/Analyzers/CSharp/Tests/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixTests.cs index 3477494c0ad5d..d36dd3d254079 100644 --- a/src/Analyzers/CSharp/Tests/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixTests.cs @@ -9,249 +9,248 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.MakeStatementAsynchronous -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpMakeStatementAsynchronousCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.MakeStatementAsynchronous; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpMakeStatementAsynchronousCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeStatementAsynchronous)] - public class CSharpMakeStatementAsynchronousCodeFixTests +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeStatementAsynchronous)] +public class CSharpMakeStatementAsynchronousCodeFixTests +{ + [Fact] + public async Task FixAllForeach() { - [Fact] - public async Task FixAllForeach() + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable collection) { - void M(System.Collections.Generic.IAsyncEnumerable collection) - { - foreach (var i in {|CS8414:collection|}) { } - foreach (var j in {|CS8414:collection|}) { } - } + foreach (var i in {|CS8414:collection|}) { } + foreach (var j in {|CS8414:collection|}) { } } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable collection) { - void M(System.Collections.Generic.IAsyncEnumerable collection) - { - {|CS4033:await|} foreach (var i in collection) { } - {|CS4033:await|} foreach (var j in collection) { } - } + {|CS4033:await|} foreach (var i in collection) { } + {|CS4033:await|} foreach (var j in collection) { } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixAllForeachDeconstruction() + [Fact] + public async Task FixAllForeachDeconstruction() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) { - void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) - { - foreach (var ({|CS8130:i|}, {|CS8130:j|}) in {|CS8414:collection|}) { } - foreach (var ({|CS8130:k|}, {|CS8130:l|}) in {|CS8414:collection|}) { } - } + foreach (var ({|CS8130:i|}, {|CS8130:j|}) in {|CS8414:collection|}) { } + foreach (var ({|CS8130:k|}, {|CS8130:l|}) in {|CS8414:collection|}) { } } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) { - void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) - { - {|CS4033:await|} foreach (var (i, j) in collection) { } - {|CS4033:await|} foreach (var (k, l) in collection) { } - } + {|CS4033:await|} foreach (var (i, j) in collection) { } + {|CS4033:await|} foreach (var (k, l) in collection) { } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixAllUsingStatement() + [Fact] + public async Task FixAllUsingStatement() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) - { - using ({|CS8418:var i = disposable|}) { } - using ({|CS8418:var j = disposable|}) { } - } + using ({|CS8418:var i = disposable|}) { } + using ({|CS8418:var j = disposable|}) { } } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) - { - {|CS4033:await|} using (var i = disposable) { } - {|CS4033:await|} using (var j = disposable) { } - } + {|CS4033:await|} using (var i = disposable) { } + {|CS4033:await|} using (var j = disposable) { } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixAllUsingDeclaration() + [Fact] + public async Task FixAllUsingDeclaration() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) - { - {|CS8418:using var i = disposable;|} - {|CS8418:using var j = disposable;|} - } + {|CS8418:using var i = disposable;|} + {|CS8418:using var j = disposable;|} } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) - { - {|CS4033:await|} using var i = disposable; - {|CS4033:await|} using var j = disposable; - } + {|CS4033:await|} using var i = disposable; + {|CS4033:await|} using var j = disposable; } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixForeach() + [Fact] + public async Task FixForeach() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable collection) { - void M(System.Collections.Generic.IAsyncEnumerable collection) + foreach (var i in {|CS8414:collection|}) { - foreach (var i in {|CS8414:collection|}) - { - } } } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable collection) { - void M(System.Collections.Generic.IAsyncEnumerable collection) + {|CS4033:await|} foreach (var i in collection) { - {|CS4033:await|} foreach (var i in collection) - { - } } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixForeachDeconstruction() + [Fact] + public async Task FixForeachDeconstruction() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) { - void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) + foreach (var ({|CS8130:i|}, {|CS8130:j|}) in {|CS8414:collection|}) { - foreach (var ({|CS8130:i|}, {|CS8130:j|}) in {|CS8414:collection|}) - { - } } } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) { - void M(System.Collections.Generic.IAsyncEnumerable<(int, int)> collection) + {|CS4033:await|} foreach (var (i, j) in collection) { - {|CS4033:await|} foreach (var (i, j) in collection) - { - } } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixUsingStatement() + [Fact] + public async Task FixUsingStatement() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) + using ({|CS8418:var i = disposable|}) { - using ({|CS8418:var i = disposable|}) - { - } } } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) + {|CS4033:await|} using (var i = disposable) { - {|CS4033:await|} using (var i = disposable) - { - } } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact] - public async Task FixUsingDeclaration() + [Fact] + public async Task FixUsingDeclaration() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - class Program + TestCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) - { - {|CS8418:using var i = disposable;|} - } + {|CS8418:using var i = disposable;|} } - """, - FixedCode = """ - class Program + } + """, + FixedCode = """ + class Program + { + void M(System.IAsyncDisposable disposable) { - void M(System.IAsyncDisposable disposable) - { - {|CS4033:await|} using var i = disposable; - } + {|CS4033:await|} using var i = disposable; } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/MakeStructFieldsWritable/MakeStructFieldsWritableTests.cs b/src/Analyzers/CSharp/Tests/MakeStructFieldsWritable/MakeStructFieldsWritableTests.cs index 3e1c0be5e0806..09e04048a73bb 100644 --- a/src/Analyzers/CSharp/Tests/MakeStructFieldsWritable/MakeStructFieldsWritableTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeStructFieldsWritable/MakeStructFieldsWritableTests.cs @@ -9,729 +9,728 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeStructFieldsWritable +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeStructFieldsWritable; + +using VerifyCS = CSharpCodeFixVerifier; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeStructFieldsWritable)] +public class MakeStructFieldsWritable { - using VerifyCS = CSharpCodeFixVerifier; + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeStructFieldsWritable)] - public class MakeStructFieldsWritable + [Fact] + public async Task SingleReadonlyField_ThisAssignmentInMethod() { - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; - [Fact] - public async Task SingleReadonlyField_ThisAssignmentInMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + public MyStruct(int value) { - public readonly int Value; + Value = value; + } - public MyStruct(int value) - { - Value = value; - } + public void Test() + { + this = new MyStruct(5); + } + } + """, + """ + struct MyStruct + { + public int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; } - """, - """ - struct MyStruct + + public void Test() { - public int Value; + this = new MyStruct(5); + } + } + """); + } - public MyStruct(int value) - { - Value = value; - } + [Fact] + public async Task SingleReadonlyField_ThisAssignmentInMultipleMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; } - """); - } - [Fact] - public async Task SingleReadonlyField_ThisAssignmentInMultipleMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + public void Test() { - public readonly int Value; - - public MyStruct(int value) - { - Value = value; - } + this = new MyStruct(5); + } - public void Test() - { - this = new MyStruct(5); - } + public void Test2() + { + this = new MyStruct(10); + } + } + """, + """ + struct MyStruct + { + public int Value; - public void Test2() - { - this = new MyStruct(10); - } + public MyStruct(int value) + { + Value = value; } - """, - """ - struct MyStruct + + public void Test() { - public int Value; + this = new MyStruct(5); + } - public MyStruct(int value) - { - Value = value; - } + public void Test2() + { + this = new MyStruct(10); + } + } + """); + } - public void Test() - { - this = new MyStruct(5); - } + [Fact] + public async Task SingleNonReadonlyField_ThisAssignmentInMethod() + { + var code = """ + struct MyStruct + { + public int Value; - public void Test2() - { - this = new MyStruct(10); - } + public MyStruct(int value) + { + Value = value; } - """); - } - [Fact] - public async Task SingleNonReadonlyField_ThisAssignmentInMethod() - { - var code = """ - struct MyStruct + public void Test() { - public int Value; - - public MyStruct(int value) - { - Value = value; - } - - public void Test() - { - this = new MyStruct(5); - } + this = new MyStruct(5); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task MultipleMixedFields_ThisAssignmentInMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + [Fact] + public async Task MultipleMixedFields_ThisAssignmentInMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int First; + public readonly int Second; + public int Third; + + public MyStruct(int first, int second, int third) { - public readonly int First; - public readonly int Second; - public int Third; + First = first; + Second = second; + Third = third; + } - public MyStruct(int first, int second, int third) - { - First = first; - Second = second; - Third = third; - } + public void Test() + { + this = new MyStruct(5, 3, 1); + } + } + """, + """ + struct MyStruct + { + public int First; + public int Second; + public int Third; - public void Test() - { - this = new MyStruct(5, 3, 1); - } + public MyStruct(int first, int second, int third) + { + First = first; + Second = second; + Third = third; } - """, - """ - struct MyStruct + + public void Test() { - public int First; - public int Second; - public int Third; + this = new MyStruct(5, 3, 1); + } + } + """); + } - public MyStruct(int first, int second, int third) - { - First = first; - Second = second; - Third = third; - } + [Fact] + public async Task SingleReadonlyField_ThisAssignmentInCtor() + { + var code = """ + struct MyStruct + { + public readonly int Value; - public void Test() - { - this = new MyStruct(5, 3, 1); - } + public MyStruct(int value) + { + this = new MyStruct(value, 0); } - """); - } - [Fact] - public async Task SingleReadonlyField_ThisAssignmentInCtor() - { - var code = """ - struct MyStruct + public MyStruct(int first, int second) { - public readonly int Value; + Value = first; + } + } + """; - public MyStruct(int value) - { - this = new MyStruct(value, 0); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - public MyStruct(int first, int second) - { - Value = first; - } + [Fact] + public async Task SingleReadonlyField_NoThisAssignment() + { + var code = """ + struct MyStruct + { + public readonly int Value; + + public MyStruct(int value) + { + Value = value; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task SingleReadonlyField_NoThisAssignment() - { - var code = """ - struct MyStruct + [Fact] + public async Task SingleReadonlyField_ThisAssignmentInMethod_ReportDiagnostic() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; + + public MyStruct(int value) { - public readonly int Value; + Value = value; + } - public MyStruct(int value) - { - Value = value; - } + public void Test() + { + this = new MyStruct(5); } - """; + } + """, + """ + struct MyStruct + { + public int Value; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + public MyStruct(int value) + { + Value = value; + } - [Fact] - public async Task SingleReadonlyField_ThisAssignmentInMethod_ReportDiagnostic() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + public void Test() { - public readonly int Value; + this = new MyStruct(5); + } + } + """); + } - public MyStruct(int value) - { - Value = value; - } + [Fact] + public async Task SingleReadonlyField_InClass() + { + var code = """ + class MyClass + { + public readonly int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyClass(int value) + { + Value = value; } - """, - """ - struct MyStruct + + public void Test() { - public int Value; + // error CS1604: Cannot assign to 'this' because it is read-only + {|CS1604:this|} = new MyClass(5); + } + } + """; - public MyStruct(int value) - { - Value = value; - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - public void Test() - { - this = new MyStruct(5); - } + [Fact] + public async Task StructWithoutField() + { + var code = """ + struct MyStruct + { + public void Test() + { + this = new MyStruct(); } - """); - } + } + """; - [Fact] - public async Task SingleReadonlyField_InClass() - { - var code = """ - class MyClass - { - public readonly int Value; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - public MyClass(int value) - { - Value = value; - } + [Fact] + public async Task SingleProperty_ThisAssignmentInMethod() + { + var code = """ + struct MyStruct + { + public int Value { get; set; } - public void Test() - { - // error CS1604: Cannot assign to 'this' because it is read-only - {|CS1604:this|} = new MyClass(5); - } + public MyStruct(int value) + { + Value = value; } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - [Fact] - public async Task StructWithoutField() - { - var code = """ - struct MyStruct + public void Test() { - public void Test() - { - this = new MyStruct(); - } + this = new MyStruct(5); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task SingleProperty_ThisAssignmentInMethod() - { - var code = """ - struct MyStruct - { - public int Value { get; set; } + [Fact] + public async Task SingleGetterProperty_ThisAssignmentInMethod() + { + var code = """ + struct MyStruct + { + public int Value { get; } - public MyStruct(int value) - { - Value = value; - } + public MyStruct(int value) + { + Value = value; + } - public void Test() - { - this = new MyStruct(5); - } + public void Test() + { + this = new MyStruct(5); } - """; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MultipleStructDeclaration_SingleReadonlyField_ThisAssignmentInMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; - [Fact] - public async Task SingleGetterProperty_ThisAssignmentInMethod() - { - var code = """ - struct MyStruct + public MyStruct(int value) { - public int Value { get; } - - public MyStruct(int value) - { - Value = value; - } + Value = value; + } - public void Test() - { - this = new MyStruct(5); - } + public void Test() + { + this = new MyStruct(5); } - """; + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + struct [|MyStruct2|] + { + public readonly int Value; - [Fact] - public async Task MultipleStructDeclaration_SingleReadonlyField_ThisAssignmentInMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + public MyStruct2(int value) { - public readonly int Value; + Value = value; + } - public MyStruct(int value) - { - Value = value; - } + public void Test() + { + this = new MyStruct2(5); + } + } + """, + """ + struct MyStruct + { + public int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; } - struct [|MyStruct2|] + public void Test() { - public readonly int Value; + this = new MyStruct(5); + } + } - public MyStruct2(int value) - { - Value = value; - } + struct MyStruct2 + { + public int Value; - public void Test() - { - this = new MyStruct2(5); - } + public MyStruct2(int value) + { + Value = value; } - """, - """ - struct MyStruct + + public void Test() { - public int Value; + this = new MyStruct2(5); + } + } + """); + } - public MyStruct(int value) - { - Value = value; - } + [Fact] + public async Task MultipleStructDeclaration_SingleReadonlyField_ThisAssignmentInMethod_ShouldNotReportDiagnostic() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct MyStruct + { + public int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; } - struct MyStruct2 + public void Test() { - public int Value; + this = new MyStruct(5); + } + } - public MyStruct2(int value) - { - Value = value; - } + struct [|MyStruct2|] + { + public readonly int Value; - public void Test() - { - this = new MyStruct2(5); - } + public MyStruct2(int value) + { + Value = value; } - """); - } - [Fact] - public async Task MultipleStructDeclaration_SingleReadonlyField_ThisAssignmentInMethod_ShouldNotReportDiagnostic() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct MyStruct + public void Test() { - public int Value; - - public MyStruct(int value) - { - Value = value; - } + this = new MyStruct2(5); + } + } + """, + """ + struct MyStruct + { + public int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; } - struct [|MyStruct2|] + public void Test() { - public readonly int Value; + this = new MyStruct(5); + } + } - public MyStruct2(int value) - { - Value = value; - } + struct MyStruct2 + { + public int Value; - public void Test() - { - this = new MyStruct2(5); - } + public MyStruct2(int value) + { + Value = value; } - """, - """ - struct MyStruct + + public void Test() { - public int Value; + this = new MyStruct2(5); + } + } + """); + } - public MyStruct(int value) - { - Value = value; - } + [Fact] + public async Task NestedStructDeclaration_SingleNestedReadonlyField_ThisAssignmentInMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; } - struct MyStruct2 + public void Test() { - public int Value; - - public MyStruct2(int value) - { - Value = value; - } - - public void Test() - { - this = new MyStruct2(5); - } + this = new MyStruct(5); } - """); - } - [Fact] - public async Task NestedStructDeclaration_SingleNestedReadonlyField_ThisAssignmentInMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + struct [|NestedStruct|] { - public readonly int Value; + public readonly int NestedValue; - public MyStruct(int value) + public NestedStruct(int nestedValue) { - Value = value; + NestedValue = nestedValue; } public void Test() { - this = new MyStruct(5); + this = new NestedStruct(5); } + } + } + """, + """ + struct MyStruct + { + public int Value; - struct [|NestedStruct|] - { - public readonly int NestedValue; - - public NestedStruct(int nestedValue) - { - NestedValue = nestedValue; - } + public MyStruct(int value) + { + Value = value; + } - public void Test() - { - this = new NestedStruct(5); - } - } + public void Test() + { + this = new MyStruct(5); } - """, - """ - struct MyStruct + + struct NestedStruct { - public int Value; + public int NestedValue; - public MyStruct(int value) + public NestedStruct(int nestedValue) { - Value = value; + NestedValue = nestedValue; } public void Test() { - this = new MyStruct(5); + this = new NestedStruct(5); } + } + } + """); + } - struct NestedStruct - { - public int NestedValue; + [Fact] + public async Task NestedStructDeclaration_SingleReadonlyField_ThisAssignmentInMethod() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; - public NestedStruct(int nestedValue) - { - NestedValue = nestedValue; - } + public MyStruct(int value) + { + Value = value; + } - public void Test() - { - this = new NestedStruct(5); - } - } + public void Test() + { + this = new MyStruct(5); } - """); - } - [Fact] - public async Task NestedStructDeclaration_SingleReadonlyField_ThisAssignmentInMethod() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + struct [|NestedStruct|] { - public readonly int Value; + public readonly int NestedValue; - public MyStruct(int value) + public NestedStruct(int nestedValue) { - Value = value; + NestedValue = nestedValue; } public void Test() { - this = new MyStruct(5); + this = new NestedStruct(5); } + } + } + """, + """ + struct MyStruct + { + public int Value; - struct [|NestedStruct|] - { - public readonly int NestedValue; - - public NestedStruct(int nestedValue) - { - NestedValue = nestedValue; - } + public MyStruct(int value) + { + Value = value; + } - public void Test() - { - this = new NestedStruct(5); - } - } + public void Test() + { + this = new MyStruct(5); } - """, - """ - struct MyStruct + + struct NestedStruct { - public int Value; + public int NestedValue; - public MyStruct(int value) + public NestedStruct(int nestedValue) { - Value = value; + NestedValue = nestedValue; } public void Test() { - this = new MyStruct(5); + this = new NestedStruct(5); } + } + } + """); + } - struct NestedStruct - { - public int NestedValue; - - public NestedStruct(int nestedValue) - { - NestedValue = nestedValue; - } + [Fact] + public async Task StructDeclaration_MixedFields_MixedAssignmentsInMethods() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; + public int TestValue; - public void Test() - { - this = new NestedStruct(5); - } - } + public MyStruct(int value) + { + Value = value; + TestValue = 100; } - """); - } - [Fact] - public async Task StructDeclaration_MixedFields_MixedAssignmentsInMethods() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + public void Test() { - public readonly int Value; - public int TestValue; - - public MyStruct(int value) - { - Value = value; - TestValue = 100; - } - - public void Test() - { - this = new MyStruct(5); - } - - public void Test2() - { - TestValue = 0; - } + this = new MyStruct(5); } - """, - """ - struct MyStruct - { - public int Value; - public int TestValue; - public MyStruct(int value) - { - Value = value; - TestValue = 100; - } + public void Test2() + { + TestValue = 0; + } + } + """, + """ + struct MyStruct + { + public int Value; + public int TestValue; - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; + TestValue = 100; + } - public void Test2() - { - TestValue = 0; - } + public void Test() + { + this = new MyStruct(5); } - """); - } - [Fact] - public async Task StructDeclaration_ChangedOrderOfConstructorDeclaration() - { - await VerifyCS.VerifyCodeFixAsync( - """ - struct [|MyStruct|] + public void Test2() { - public readonly int Value; + TestValue = 0; + } + } + """); + } - public void Test() - { - this = new MyStruct(5); - } + [Fact] + public async Task StructDeclaration_ChangedOrderOfConstructorDeclaration() + { + await VerifyCS.VerifyCodeFixAsync( + """ + struct [|MyStruct|] + { + public readonly int Value; - public MyStruct(int value) - { - Value = value; - } - } - """, - """ - struct MyStruct + public void Test() { - public int Value; + this = new MyStruct(5); + } - public void Test() - { - this = new MyStruct(5); - } + public MyStruct(int value) + { + Value = value; + } + } + """, + """ + struct MyStruct + { + public int Value; - public MyStruct(int value) - { - Value = value; - } + public void Test() + { + this = new MyStruct(5); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57920")] - public async Task ReadonlyStaticField() - { - var test = """ - struct Repro + public MyStruct(int value) { - public static readonly Repro DefaultValue = new Repro(); + Value = value; + } + } + """); + } - public int IrrelevantValue; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57920")] + public async Task ReadonlyStaticField() + { + var test = """ + struct Repro + { + public static readonly Repro DefaultValue = new Repro(); - public void Overwrite(Repro other) => this = other; - } - """; - await VerifyCS.VerifyCodeFixAsync(test, test); - } + public int IrrelevantValue; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57920")] - public async Task ConstField() - { - var test = """ - struct Repro - { - public const int X = 0; + public void Overwrite(Repro other) => this = other; + } + """; + await VerifyCS.VerifyCodeFixAsync(test, test); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57920")] + public async Task ConstField() + { + var test = """ + struct Repro + { + public const int X = 0; - public int IrrelevantValue; + public int IrrelevantValue; - public void Overwrite(Repro other) => this = other; - } - """; - await VerifyCS.VerifyCodeFixAsync(test, test); - } + public void Overwrite(Repro other) => this = other; + } + """; + await VerifyCS.VerifyCodeFixAsync(test, test); } } diff --git a/src/Analyzers/CSharp/Tests/MakeTypeAbstract/MakeTypeAbstractTests.cs b/src/Analyzers/CSharp/Tests/MakeTypeAbstract/MakeTypeAbstractTests.cs index e13da926c701c..4b6b868c9648e 100644 --- a/src/Analyzers/CSharp/Tests/MakeTypeAbstract/MakeTypeAbstractTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeTypeAbstract/MakeTypeAbstractTests.cs @@ -12,370 +12,369 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeTypeAbstract +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeTypeAbstract; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeTypeAbstract)] +public class MakeTypeAbstractTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeTypeAbstract)] - public class MakeTypeAbstractTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public MakeTypeAbstractTests(ITestOutputHelper logger) + : base(logger) { - public MakeTypeAbstractTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpMakeTypeAbstractCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpMakeTypeAbstractCodeFixProvider()); - [Fact] - public async Task TestMethod() - { - await TestInRegularAndScript1Async( - """ - public class Goo - { - public abstract void [|M|](); - } - """, - """ - public abstract class Goo - { - public abstract void M(); - } - """); - } + [Fact] + public async Task TestMethod() + { + await TestInRegularAndScript1Async( + """ + public class Goo + { + public abstract void [|M|](); + } + """, + """ + public abstract class Goo + { + public abstract void M(); + } + """); + } - [Fact] - public async Task TestMethodEnclosingClassWithoutAccessibility() - { - await TestInRegularAndScript1Async( - """ - class Goo - { - public abstract void [|M|](); - } - """, - """ - abstract class Goo - { - public abstract void M(); - } - """); - } + [Fact] + public async Task TestMethodEnclosingClassWithoutAccessibility() + { + await TestInRegularAndScript1Async( + """ + class Goo + { + public abstract void [|M|](); + } + """, + """ + abstract class Goo + { + public abstract void M(); + } + """); + } - [Fact] - public async Task TestMethodEnclosingClassDocumentationComment() - { - await TestInRegularAndScript1Async( - """ - /// - /// Some class comment. - /// - public class Goo - { - public abstract void [|M|](); - } - """, - """ - /// - /// Some class comment. - /// - public abstract class Goo - { - public abstract void M(); - } - """); - } + [Fact] + public async Task TestMethodEnclosingClassDocumentationComment() + { + await TestInRegularAndScript1Async( + """ + /// + /// Some class comment. + /// + public class Goo + { + public abstract void [|M|](); + } + """, + """ + /// + /// Some class comment. + /// + public abstract class Goo + { + public abstract void M(); + } + """); + } - [Fact] - public async Task TestPropertyGetter() - { - await TestInRegularAndScript1Async( - """ - public class Goo - { - public abstract object P { [|get|]; } - } - """, - """ - public abstract class Goo - { - public abstract object P { get; } - } - """); - } + [Fact] + public async Task TestPropertyGetter() + { + await TestInRegularAndScript1Async( + """ + public class Goo + { + public abstract object P { [|get|]; } + } + """, + """ + public abstract class Goo + { + public abstract object P { get; } + } + """); + } - [Fact] - public async Task TestPropertySetter() - { - await TestInRegularAndScript1Async( - """ - public class Goo - { - public abstract object P { [|set|]; } - } - """, - """ - public abstract class Goo - { - public abstract object P { set; } - } - """); - } + [Fact] + public async Task TestPropertySetter() + { + await TestInRegularAndScript1Async( + """ + public class Goo + { + public abstract object P { [|set|]; } + } + """, + """ + public abstract class Goo + { + public abstract object P { set; } + } + """); + } - [Fact] - public async Task TestIndexerGetter() - { - await TestInRegularAndScript1Async( - """ - public class Goo - { - public abstract object this[object o] { [|get|]; } - } - """, - """ - public abstract class Goo - { - public abstract object this[object o] { get; } - } - """); - } + [Fact] + public async Task TestIndexerGetter() + { + await TestInRegularAndScript1Async( + """ + public class Goo + { + public abstract object this[object o] { [|get|]; } + } + """, + """ + public abstract class Goo + { + public abstract object this[object o] { get; } + } + """); + } - [Fact] - public async Task TestIndexerSetter() - { - await TestInRegularAndScript1Async( - """ - public class Goo - { - public abstract object this[object o] { [|set|]; } - } - """, - """ - public abstract class Goo - { - public abstract object this[object o] { set; } - } - """); - } + [Fact] + public async Task TestIndexerSetter() + { + await TestInRegularAndScript1Async( + """ + public class Goo + { + public abstract object this[object o] { [|set|]; } + } + """, + """ + public abstract class Goo + { + public abstract object this[object o] { set; } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54218")] - public async Task TestPartialClass() - { - await TestInRegularAndScript1Async( - """ - public partial class Goo - { - public abstract void [|M|](); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/54218")] + public async Task TestPartialClass() + { + await TestInRegularAndScript1Async( + """ + public partial class Goo + { + public abstract void [|M|](); + } - public partial class Goo - { - } - """, - """ - public abstract partial class Goo - { - public abstract void M(); - } + public partial class Goo + { + } + """, + """ + public abstract partial class Goo + { + public abstract void M(); + } - public partial class Goo - { - } - """); - } + public partial class Goo + { + } + """); + } - [Fact] - public async Task TestEventAdd() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Goo - { - public abstract event System.EventHandler E { [|add|]; } - } - """); - } + [Fact] + public async Task TestEventAdd() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Goo + { + public abstract event System.EventHandler E { [|add|]; } + } + """); + } - [Fact] - public async Task TestEventRemove() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Goo - { - public abstract event System.EventHandler E { [|remove|]; } - } - """); - } + [Fact] + public async Task TestEventRemove() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Goo + { + public abstract event System.EventHandler E { [|remove|]; } + } + """); + } - [Fact] - public async Task TestMethodWithBody() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Goo - { - public abstract int [|M|]() => 3; - } - """); - } + [Fact] + public async Task TestMethodWithBody() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Goo + { + public abstract int [|M|]() => 3; + } + """); + } - [Fact] - public async Task TestPropertyGetterWithArrowBody() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Goo - { - public abstract int [|P|] => 3; - } - """); - } + [Fact] + public async Task TestPropertyGetterWithArrowBody() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Goo + { + public abstract int [|P|] => 3; + } + """); + } - [Fact] - public async Task TestPropertyGetterWithBody() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Goo + [Fact] + public async Task TestPropertyGetterWithBody() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Goo + { + public abstract int P { - public abstract int P - { - [|get|] { return 1; } - } + [|get|] { return 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestStructNestedInClass() - { - await TestMissingInRegularAndScriptAsync( - """ - public class C + [Fact] + public async Task TestStructNestedInClass() + { + await TestMissingInRegularAndScriptAsync( + """ + public class C + { + public struct S { - public struct S - { - public abstract void [|Goo|](); - } + public abstract void [|Goo|](); } - """); - } + } + """); + } - [Fact] - public async Task TestMethodEnclosingClassStatic() - { - await TestMissingInRegularAndScriptAsync( - """ - public static class Goo - { - public abstract void [|M|](); - } - """); - } + [Fact] + public async Task TestMethodEnclosingClassStatic() + { + await TestMissingInRegularAndScriptAsync( + """ + public static class Goo + { + public abstract void [|M|](); + } + """); + } - [Fact] - public async Task TestRecord() - { - await TestInRegularAndScript1Async( - """ - public record Goo + [Fact] + public async Task TestRecord() + { + await TestInRegularAndScript1Async( + """ + public record Goo + { + public abstract void [|M|](); + } + """, + """ + public abstract record Goo + { + public abstract void M(); + } + """); + } + + [Fact] + public async Task TestRecordClass() + { + await TestInRegularAndScript1Async( + """ + public record class Goo + { + public abstract void [|M|](); + } + """, + """ + public abstract record class Goo + { + public abstract void M(); + } + """); + } + + [Fact] + public async Task TestRecordStruct() + { + await TestMissingInRegularAndScriptAsync(""" + public record struct Goo + { + public abstract void [|M|](); + } + """); + } + + [Fact] + public async Task FixAll() + { + await TestInRegularAndScript1Async( + """ + namespace NS + { + using System; + + public class C1 { - public abstract void [|M|](); + public abstract void {|FixAllInDocument:|}M(); + public abstract object P { get; set; } + public abstract object this[object o] { get; set; } } - """, - """ - public abstract record Goo + + public class C2 { public abstract void M(); } - """); - } - [Fact] - public async Task TestRecordClass() - { - await TestInRegularAndScript1Async( - """ - public record class Goo + public class C3 { - public abstract void [|M|](); + public class InnerClass + { + public abstract void M(); + } } - """, - """ - public abstract record class Goo + } + """, + """ + namespace NS + { + using System; + + public abstract class C1 { public abstract void M(); + public abstract object P { get; set; } + public abstract object this[object o] { get; set; } } - """); - } - [Fact] - public async Task TestRecordStruct() - { - await TestMissingInRegularAndScriptAsync(""" - public record struct Goo + public abstract class C2 { - public abstract void [|M|](); + public abstract void M(); } - """); - } - - [Fact] - public async Task FixAll() - { - await TestInRegularAndScript1Async( - """ - namespace NS - { - using System; - - public class C1 - { - public abstract void {|FixAllInDocument:|}M(); - public abstract object P { get; set; } - public abstract object this[object o] { get; set; } - } - public class C2 - { - public abstract void M(); - } - - public class C3 - { - public class InnerClass - { - public abstract void M(); - } - } - } - """, - """ - namespace NS + public class C3 { - using System; - - public abstract class C1 + public abstract class InnerClass { public abstract void M(); - public abstract object P { get; set; } - public abstract object this[object o] { get; set; } - } - - public abstract class C2 - { - public abstract void M(); - } - - public class C3 - { - public abstract class InnerClass - { - public abstract void M(); - } } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/MakeTypePartial/MakeTypePartialTests.cs b/src/Analyzers/CSharp/Tests/MakeTypePartial/MakeTypePartialTests.cs index 58630d202ae2e..377704d006a21 100644 --- a/src/Analyzers/CSharp/Tests/MakeTypePartial/MakeTypePartialTests.cs +++ b/src/Analyzers/CSharp/Tests/MakeTypePartial/MakeTypePartialTests.cs @@ -10,375 +10,374 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.CSharp.UnitTests.MakeTypePartial +namespace Microsoft.CodeAnalysis.CSharp.CSharp.UnitTests.MakeTypePartial; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpMakeTypePartialCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsMakeTypePartial)] +public sealed class MakeTypePartialTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpMakeTypePartialCodeFixProvider>; + public static IEnumerable AllValidDeclarationTypes() + { + yield return new[] { "class" }; + yield return new[] { "struct" }; + yield return new[] { "interface" }; + yield return new[] { "record" }; + yield return new[] { "record class" }; + yield return new[] { "record struct" }; + } - [Trait(Traits.Feature, Traits.Features.CodeActionsMakeTypePartial)] - public sealed class MakeTypePartialTests + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task OutsideNamespace(string declarationType) { - public static IEnumerable AllValidDeclarationTypes() + await new VerifyCS.Test { - yield return new[] { "class" }; - yield return new[] { "struct" }; - yield return new[] { "interface" }; - yield return new[] { "record" }; - yield return new[] { "record class" }; - yield return new[] { "record struct" }; - } + TestCode = $$""" + partial {{declarationType}} Declaration + { + } + + {{declarationType}} {|CS0260:Declaration|} + { + } + """, + FixedCode = $$""" + partial {{declarationType}} Declaration + { + } + + partial {{declarationType}} Declaration + { + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task OutsideNamespace(string declarationType) + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task InsideOneFileScopedNamespace(string declarationType) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" + TestCode = $$""" + namespace TestNamespace; + + partial {{declarationType}} Declaration + { + } + + {{declarationType}} {|CS0260:Declaration|} + { + } + """, + FixedCode = $$""" + namespace TestNamespace; + + partial {{declarationType}} Declaration + { + } + + partial {{declarationType}} Declaration + { + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task InsideOneBlockScopedNamespace(string declarationType) + { + await new VerifyCS.Test + { + TestCode = $$""" + namespace TestNamespace + { partial {{declarationType}} Declaration { } - + {{declarationType}} {|CS0260:Declaration|} { } - """, - FixedCode = $$""" + } + """, + FixedCode = $$""" + namespace TestNamespace + { partial {{declarationType}} Declaration { } - + partial {{declarationType}} Declaration { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task InsideOneFileScopedNamespace(string declarationType) + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task InsideTwoEqualBlockScopedNamespaces(string declarationType) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - namespace TestNamespace; - + TestCode = $$""" + namespace TestNamespace + { partial {{declarationType}} Declaration { } - + } + + namespace TestNamespace + { {{declarationType}} {|CS0260:Declaration|} { } - """, - FixedCode = $$""" - namespace TestNamespace; - + } + """, + FixedCode = $$""" + namespace TestNamespace + { partial {{declarationType}} Declaration { } - + } + + namespace TestNamespace + { partial {{declarationType}} Declaration { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task InsideOneBlockScopedNamespace(string declarationType) - { - await new VerifyCS.Test + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task InDifferentDocuments(string declarationType) + { + var document1 = $$""" + partial {{declarationType}} Declaration { - TestCode = $$""" - namespace TestNamespace - { - partial {{declarationType}} Declaration - { - } - - {{declarationType}} {|CS0260:Declaration|} - { - } - } - """, - FixedCode = $$""" - namespace TestNamespace - { - partial {{declarationType}} Declaration - { - } - - partial {{declarationType}} Declaration - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + } + """; - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task InsideTwoEqualBlockScopedNamespaces(string declarationType) + var document2 = $$""" + {{declarationType}} {|CS0260:Declaration|} + { + } + """; + + var fixedDocument2 = $$""" + partial {{declarationType}} Declaration + { + } + """; + + await new VerifyCS.Test { - await new VerifyCS.Test + TestState = { - TestCode = $$""" - namespace TestNamespace - { - partial {{declarationType}} Declaration - { - } - } - - namespace TestNamespace - { - {{declarationType}} {|CS0260:Declaration|} - { - } - } - """, - FixedCode = $$""" - namespace TestNamespace - { - partial {{declarationType}} Declaration - { - } - } - - namespace TestNamespace - { - partial {{declarationType}} Declaration - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + Sources = { document1, document2 } + }, + FixedState = + { + Sources = { document1, fixedDocument2 } + }, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task InDifferentDocuments(string declarationType) + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task WithOtherModifiers(string declarationType) + { + await new VerifyCS.Test { - var document1 = $$""" - partial {{declarationType}} Declaration + TestCode = $$""" + public partial {{declarationType}} Declaration { } - """; - - var document2 = $$""" - {{declarationType}} {|CS0260:Declaration|} + + public {{declarationType}} {|CS0260:Declaration|} { } - """; - - var fixedDocument2 = $$""" - partial {{declarationType}} Declaration + """, + FixedCode = $$""" + public partial {{declarationType}} Declaration { } - """; - - await new VerifyCS.Test - { - TestState = + + public partial {{declarationType}} Declaration { - Sources = { document1, document2 } - }, - FixedState = - { - Sources = { document1, fixedDocument2 } - }, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task WithOtherModifiers(string declarationType) + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task NestedType1(string declarationType) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" + TestCode = $$""" + class Test + { public partial {{declarationType}} Declaration { } - + public {{declarationType}} {|CS0260:Declaration|} { } - """, - FixedCode = $$""" + } + """, + FixedCode = $$""" + class Test + { public partial {{declarationType}} Declaration { } - + public partial {{declarationType}} Declaration { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task NestedType1(string declarationType) - { - await new VerifyCS.Test - { - TestCode = $$""" - class Test - { - public partial {{declarationType}} Declaration - { - } - - public {{declarationType}} {|CS0260:Declaration|} - { - } - } - """, - FixedCode = $$""" - class Test - { - public partial {{declarationType}} Declaration - { - } - - public partial {{declarationType}} Declaration - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } - - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task NestedType2(string declarationType) - { - await new VerifyCS.Test - { - TestCode = $$""" - partial {{declarationType}} Test - { - } - - {{declarationType}} {|CS0260:Test|} - { - public partial {{declarationType}} Declaration - { - } - - public {{declarationType}} {|CS0260:Declaration|} - { - } - } - """, - FixedCode = $$""" - partial {{declarationType}} Test - { - } - - partial {{declarationType}} Test - { - public partial {{declarationType}} Declaration - { - } - - public partial {{declarationType}} Declaration - { - } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task FixOne(string declarationType) + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task NestedType2(string declarationType) + { + await new VerifyCS.Test { - var testCode = $$""" + TestCode = $$""" partial {{declarationType}} Test { } - - {{declarationType}} {|CS0260:Test|} - { - } - + {{declarationType}} {|CS0260:Test|} { + public partial {{declarationType}} Declaration + { + } + + public {{declarationType}} {|CS0260:Declaration|} + { + } } - """; - var fixedCode = $$""" - partial {{declarationType}} Test - { - } - + """, + FixedCode = $$""" partial {{declarationType}} Test { } - + partial {{declarationType}} Test { + public partial {{declarationType}} Declaration + { + } + + public partial {{declarationType}} Declaration + { + } } - """; + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - await new VerifyCS.Test + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task FixOne(string declarationType) + { + var testCode = $$""" + partial {{declarationType}} Test { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp10, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - DiagnosticSelector = d => d[0] - }.RunAsync(); - - await new VerifyCS.Test + } + + {{declarationType}} {|CS0260:Test|} { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp10, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - DiagnosticSelector = d => d[1] - }.RunAsync(); - } + } + + {{declarationType}} {|CS0260:Test|} + { + } + """; + var fixedCode = $$""" + partial {{declarationType}} Test + { + } + + partial {{declarationType}} Test + { + } + + partial {{declarationType}} Test + { + } + """; + + await new VerifyCS.Test + { + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp10, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + DiagnosticSelector = d => d[0] + }.RunAsync(); - [Theory] - [MemberData(nameof(AllValidDeclarationTypes))] - public async Task NotInDifferentNamespaces(string declarationType) + await new VerifyCS.Test { - var markup = $$""" - namespace TestNamespace1 + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp10, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + DiagnosticSelector = d => d[1] + }.RunAsync(); + } + + [Theory] + [MemberData(nameof(AllValidDeclarationTypes))] + public async Task NotInDifferentNamespaces(string declarationType) + { + var markup = $$""" + namespace TestNamespace1 + { + partial {{declarationType}} Declaration { - partial {{declarationType}} Declaration - { - } } - - namespace TestNamespace2 + } + + namespace TestNamespace2 + { + {{declarationType}} Declaration { - {{declarationType}} Declaration - { - } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = markup, - FixedCode = markup, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = markup, + FixedCode = markup, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/MatchFolderAndNamespace/CSharpMatchFolderAndNamespaceTests.cs b/src/Analyzers/CSharp/Tests/MatchFolderAndNamespace/CSharpMatchFolderAndNamespaceTests.cs index 4391df445cab6..cbea904eed4c3 100644 --- a/src/Analyzers/CSharp/Tests/MatchFolderAndNamespace/CSharpMatchFolderAndNamespaceTests.cs +++ b/src/Analyzers/CSharp/Tests/MatchFolderAndNamespace/CSharpMatchFolderAndNamespaceTests.cs @@ -13,156 +13,156 @@ Microsoft.CodeAnalysis.CSharp.Analyzers.MatchFolderAndNamespace.CSharpMatchFolderAndNamespaceDiagnosticAnalyzer, Microsoft.CodeAnalysis.CSharp.CodeFixes.MatchFolderAndNamespace.CSharpChangeNamespaceToMatchFolderCodeFixProvider>; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.MatchFolderAndNamespace +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.MatchFolderAndNamespace; + +public class CSharpMatchFolderAndNamespaceTests { - public class CSharpMatchFolderAndNamespaceTests - { - private static readonly string Directory = "/0/"; + private static readonly string Directory = "/0/"; - // DefaultNamespace gets exposed as RootNamespace in the build properties - private const string DefaultNamespace = "Test.Root.Namespace"; + // DefaultNamespace gets exposed as RootNamespace in the build properties + private const string DefaultNamespace = "Test.Root.Namespace"; - private static readonly string EditorConfig = @$" + private static readonly string EditorConfig = @$" is_global=true build_property.ProjectDir = {Directory} build_property.RootNamespace = {DefaultNamespace} "; - private static string CreateFolderPath(params string[] folders) - => Path.Combine(Directory, Path.Combine(folders)); + private static string CreateFolderPath(params string[] folders) + => Path.Combine(Directory, Path.Combine(folders)); - private static Task RunTestAsync(string fileName, string fileContents, string? directory = null, string? editorConfig = null, string? fixedCode = null, string? defaultNamespace = null) - { - var filePath = Path.Combine(directory ?? Directory, fileName); - fixedCode ??= fileContents; - - return RunTestAsync( - new[] { (filePath, fileContents) }, - new[] { (filePath, fixedCode) }, - editorConfig, - defaultNamespace); - } + private static Task RunTestAsync(string fileName, string fileContents, string? directory = null, string? editorConfig = null, string? fixedCode = null, string? defaultNamespace = null) + { + var filePath = Path.Combine(directory ?? Directory, fileName); + fixedCode ??= fileContents; + + return RunTestAsync( + new[] { (filePath, fileContents) }, + new[] { (filePath, fixedCode) }, + editorConfig, + defaultNamespace); + } - private static Task RunTestAsync(IEnumerable<(string, string)> originalSources, IEnumerable<(string, string)>? fixedSources = null, string? editorconfig = null, string? defaultNamespace = null) - { - // When a namespace isn't provided we will fallback on our default - defaultNamespace ??= DefaultNamespace; + private static Task RunTestAsync(IEnumerable<(string, string)> originalSources, IEnumerable<(string, string)>? fixedSources = null, string? editorconfig = null, string? defaultNamespace = null) + { + // When a namespace isn't provided we will fallback on our default + defaultNamespace ??= DefaultNamespace; - var testState = new VerifyCS.Test - { - EditorConfig = editorconfig ?? EditorConfig, - CodeFixTestBehaviors = CodeAnalysis.Testing.CodeFixTestBehaviors.SkipFixAllInDocumentCheck, - LanguageVersion = LanguageVersion.CSharp10, - }; + var testState = new VerifyCS.Test + { + EditorConfig = editorconfig ?? EditorConfig, + CodeFixTestBehaviors = CodeAnalysis.Testing.CodeFixTestBehaviors.SkipFixAllInDocumentCheck, + LanguageVersion = LanguageVersion.CSharp10, + }; - foreach (var (fileName, content) in originalSources) - testState.TestState.Sources.Add((fileName, content)); + foreach (var (fileName, content) in originalSources) + testState.TestState.Sources.Add((fileName, content)); - fixedSources ??= []; - foreach (var (fileName, content) in fixedSources) - testState.FixedState.Sources.Add((fileName, content)); + fixedSources ??= []; + foreach (var (fileName, content) in fixedSources) + testState.FixedState.Sources.Add((fileName, content)); - // If empty string was provided as the namespace, then we will not set a default - if (defaultNamespace.Length > 0) + // If empty string was provided as the namespace, then we will not set a default + if (defaultNamespace.Length > 0) + { + testState.SolutionTransforms.Add((solution, projectId) => { - testState.SolutionTransforms.Add((solution, projectId) => - { - var project = solution.GetRequiredProject(projectId); - return project.WithDefaultNamespace(defaultNamespace).Solution; - }); - } - - return testState.RunAsync(); + var project = solution.GetRequiredProject(projectId); + return project.WithDefaultNamespace(defaultNamespace).Solution; + }); } - [Fact] - public Task InvalidFolderName1_NoDiagnostic() - { - // No change namespace action because the folder name is not valid identifier - var folder = CreateFolderPath(["3B", "C"]); - var code = - """ - namespace A.B + return testState.RunAsync(); + } + + [Fact] + public Task InvalidFolderName1_NoDiagnostic() + { + // No change namespace action because the folder name is not valid identifier + var folder = CreateFolderPath(["3B", "C"]); + var code = + """ + namespace A.B + { + class Class1 { - class Class1 - { - } } - """; + } + """; - return RunTestAsync( - "File1.cs", - code, - directory: folder); - } + return RunTestAsync( + "File1.cs", + code, + directory: folder); + } - [Fact] - public Task InvalidFolderName1_NoDiagnostic_FileScopedNamespace() - { - // No change namespace action because the folder name is not valid identifier - var folder = CreateFolderPath(["3B", "C"]); - var code = - """ - namespace A.B; + [Fact] + public Task InvalidFolderName1_NoDiagnostic_FileScopedNamespace() + { + // No change namespace action because the folder name is not valid identifier + var folder = CreateFolderPath(["3B", "C"]); + var code = + """ + namespace A.B; - class Class1 - { - } - """; + class Class1 + { + } + """; - return RunTestAsync( - "File1.cs", - code, - directory: folder); - } + return RunTestAsync( + "File1.cs", + code, + directory: folder); + } - [Fact] - public Task InvalidFolderName2_NoDiagnostic() - { - // No change namespace action because the folder name is not valid identifier - var folder = CreateFolderPath(["B.3C", "D"]); - var code = - """ - namespace A.B + [Fact] + public Task InvalidFolderName2_NoDiagnostic() + { + // No change namespace action because the folder name is not valid identifier + var folder = CreateFolderPath(["B.3C", "D"]); + var code = + """ + namespace A.B + { + class Class1 { - class Class1 - { - } } - """; + } + """; - return RunTestAsync( - "File1.cs", - code, - directory: folder); - } + return RunTestAsync( + "File1.cs", + code, + directory: folder); + } - [Fact] - public Task InvalidFolderName3_NoDiagnostic() - { - // No change namespace action because the folder name is not valid identifier - var folder = CreateFolderPath([".folder", "..subfolder", "name"]); - var code = - """ - namespace A.B + [Fact] + public Task InvalidFolderName3_NoDiagnostic() + { + // No change namespace action because the folder name is not valid identifier + var folder = CreateFolderPath([".folder", "..subfolder", "name"]); + var code = + """ + namespace A.B + { + class Class1 { - class Class1 - { - } } - """; + } + """; - return RunTestAsync( - "File1.cs", - code, - directory: folder); - } + return RunTestAsync( + "File1.cs", + code, + directory: folder); + } - [Fact] - public Task CaseInsensitiveMatch_NoDiagnostic() - { - var folder = CreateFolderPath(["A", "B"]); - var code = + [Fact] + public Task CaseInsensitiveMatch_NoDiagnostic() + { + var folder = CreateFolderPath(["A", "B"]); + var code = @$" namespace {DefaultNamespace}.a.b {{ @@ -171,167 +171,167 @@ class Class1 }} }}"; - return RunTestAsync( - "File1.cs", - code, - directory: folder); - } + return RunTestAsync( + "File1.cs", + code, + directory: folder); + } - [Fact] - public async Task CodeStyleOptionIsFalse() - { - var folder = CreateFolderPath("B", "C"); - var code = - """ - namespace A.B + [Fact] + public async Task CodeStyleOptionIsFalse() + { + var folder = CreateFolderPath("B", "C"); + var code = + """ + namespace A.B + { + class Class1 { - class Class1 - { - } } - """; - - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder, - editorConfig: EditorConfig + """ - dotnet_style_namespace_match_folder = false - """ + } + """; + + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder, + editorConfig: EditorConfig + """ + dotnet_style_namespace_match_folder = false + """ ); - } + } - [Fact] - public async Task SingleDocumentNoReference() - { - var folder = CreateFolderPath("B", "C"); - var code = - """ - namespace [|A.B|] + [Fact] + public async Task SingleDocumentNoReference() + { + var folder = CreateFolderPath("B", "C"); + var code = + """ + namespace [|A.B|] + { + class Class1 { - class Class1 - { - } } - """; + } + """; - var fixedCode = + var fixedCode = @$"namespace {DefaultNamespace}.B.C {{ class Class1 {{ }} }}"; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder, - fixedCode: fixedCode); - } + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder, + fixedCode: fixedCode); + } - [Fact] - public async Task SingleDocumentNoReference_FileScopedNamespace() - { - var folder = CreateFolderPath("B", "C"); - var code = - """ - namespace [|A.B|]; + [Fact] + public async Task SingleDocumentNoReference_FileScopedNamespace() + { + var folder = CreateFolderPath("B", "C"); + var code = + """ + namespace [|A.B|]; - class Class1 - { - } - """; + class Class1 + { + } + """; - var fixedCode = + var fixedCode = @$"namespace {DefaultNamespace}.B.C; class Class1 {{ }}"; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder, - fixedCode: fixedCode); - } + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder, + fixedCode: fixedCode); + } - [Fact] - public async Task SingleDocumentNoReference_NoDefaultNamespace() - { - var editorConfig = @$" + [Fact] + public async Task SingleDocumentNoReference_NoDefaultNamespace() + { + var editorConfig = @$" is_global=true build_property.ProjectDir = {Directory} "; - var folder = CreateFolderPath("B", "C"); - var code = - """ - namespace [|A.B|] + var folder = CreateFolderPath("B", "C"); + var code = + """ + namespace [|A.B|] + { + class Class1 { - class Class1 - { - } } - """; + } + """; - var fixedCode = + var fixedCode = @$"namespace B.C {{ class Class1 {{ }} }}"; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder, - fixedCode: fixedCode, - editorConfig: editorConfig, - // passing empty string means that a default namespace isn't set on the test Project - defaultNamespace: string.Empty); - } + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder, + fixedCode: fixedCode, + editorConfig: editorConfig, + // passing empty string means that a default namespace isn't set on the test Project + defaultNamespace: string.Empty); + } - [Fact] - public async Task SingleDocumentNoReference_NoDefaultNamespace_FileScopedNamespace() - { - var editorConfig = @$" + [Fact] + public async Task SingleDocumentNoReference_NoDefaultNamespace_FileScopedNamespace() + { + var editorConfig = @$" is_global=true build_property.ProjectDir = {Directory} "; - var folder = CreateFolderPath("B", "C"); - var code = - """ - namespace [|A.B|]; + var folder = CreateFolderPath("B", "C"); + var code = + """ + namespace [|A.B|]; - class Class1 - { - } - """; + class Class1 + { + } + """; - var fixedCode = - """ - namespace B.C; + var fixedCode = + """ + namespace B.C; - class Class1 - { - } - """; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder, - fixedCode: fixedCode, - editorConfig: editorConfig, - // passing empty string means that a default namespace isn't set on the test Project - defaultNamespace: string.Empty); - } + class Class1 + { + } + """; + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder, + fixedCode: fixedCode, + editorConfig: editorConfig, + // passing empty string means that a default namespace isn't set on the test Project + defaultNamespace: string.Empty); + } - [Fact] - public async Task NamespaceWithSpaces_NoDiagnostic() - { - var folder = CreateFolderPath("A", "B"); - var code = + [Fact] + public async Task NamespaceWithSpaces_NoDiagnostic() + { + var folder = CreateFolderPath("A", "B"); + var code = @$"namespace {DefaultNamespace}.A . B {{ class Class1 @@ -339,89 +339,89 @@ class Class1 }} }}"; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder); - } + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder); + } - [Fact] - public async Task NestedNamespaces_NoDiagnostic() - { - // The code fix doesn't currently support nested namespaces for sync, so - // diagnostic does not report. + [Fact] + public async Task NestedNamespaces_NoDiagnostic() + { + // The code fix doesn't currently support nested namespaces for sync, so + // diagnostic does not report. - var folder = CreateFolderPath("B", "C"); - var code = - """ - namespace A.B + var folder = CreateFolderPath("B", "C"); + var code = + """ + namespace A.B + { + namespace C.D { - namespace C.D + class CDClass { - class CDClass - { - } } + } - class ABClass - { - } + class ABClass + { } - """; + } + """; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder); - } + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder); + } - [Fact] - public async Task PartialTypeWithMultipleDeclarations_NoDiagnostic() - { - // The code fix doesn't currently support nested namespaces for sync, so - // diagnostic does not report. + [Fact] + public async Task PartialTypeWithMultipleDeclarations_NoDiagnostic() + { + // The code fix doesn't currently support nested namespaces for sync, so + // diagnostic does not report. - var folder = CreateFolderPath("B", "C"); - var code1 = - """ - namespace A.B + var folder = CreateFolderPath("B", "C"); + var code1 = + """ + namespace A.B + { + partial class ABClass { - partial class ABClass - { - void M1() {} - } + void M1() {} } - """; + } + """; - var code2 = - """ - namespace A.B + var code2 = + """ + namespace A.B + { + partial class ABClass { - partial class ABClass - { - void M2() {} - } + void M2() {} } - """; + } + """; - var sources = new[] - { - (Path.Combine(folder, "ABClass1.cs"), code1), - (Path.Combine(folder, "ABClass2.cs"), code2), - }; + var sources = new[] + { + (Path.Combine(folder, "ABClass1.cs"), code1), + (Path.Combine(folder, "ABClass2.cs"), code2), + }; - await RunTestAsync(sources); - } + await RunTestAsync(sources); + } - [Fact] - public async Task FileNotInProjectFolder_NoDiagnostic() - { - // Default directory is Test\Directory for the project, - // putting the file outside the directory should have no - // diagnostic shown. + [Fact] + public async Task FileNotInProjectFolder_NoDiagnostic() + { + // Default directory is Test\Directory for the project, + // putting the file outside the directory should have no + // diagnostic shown. - var folder = Path.Combine("B", "C"); - var code = + var folder = Path.Combine("B", "C"); + var code = $@"namespace A.B {{ class ABClass @@ -429,19 +429,19 @@ class ABClass }} }}"; - await RunTestAsync( - fileName: "Class1.cs", - fileContents: code, - directory: folder); - } + await RunTestAsync( + fileName: "Class1.cs", + fileContents: code, + directory: folder); + } - [Fact] - public async Task SingleDocumentLocalReference() - { - var @namespace = "Bar.Baz"; + [Fact] + public async Task SingleDocumentLocalReference() + { + var @namespace = "Bar.Baz"; - var folder = CreateFolderPath("A", "B", "C"); - var code = + var folder = CreateFolderPath("A", "B", "C"); + var code = $@" namespace [|{@namespace}|] {{ @@ -460,7 +460,7 @@ class Class2 : {@namespace}.Class1 }} }}"; - var expected = + var expected = @$"namespace {DefaultNamespace}.A.B.C {{ delegate void D1(); @@ -478,20 +478,20 @@ void Class1.M1() {{ }} }} }}"; - await RunTestAsync( - "Class1.cs", - code, - folder, - fixedCode: expected); - } + await RunTestAsync( + "Class1.cs", + code, + folder, + fixedCode: expected); + } - [Fact] - public async Task ChangeUsingsInMultipleContainers() - { - var declaredNamespace = "Bar.Baz"; + [Fact] + public async Task ChangeUsingsInMultipleContainers() + { + var declaredNamespace = "Bar.Baz"; - var folder = CreateFolderPath("A", "B", "C"); - var code1 = + var folder = CreateFolderPath("A", "B", "C"); + var code1 = $@"namespace [|{declaredNamespace}|] {{ class Class1 @@ -499,7 +499,7 @@ class Class1 }} }}"; - var code2 = + var code2 = $@"namespace NS1 {{ using {declaredNamespace}; @@ -520,7 +520,7 @@ class Class2 }} }}"; - var fixed1 = + var fixed1 = @$"namespace {DefaultNamespace}.A.B.C {{ class Class1 @@ -528,7 +528,7 @@ class Class1 }} }}"; - var fixed2 = + var fixed2 = @$"namespace NS1 {{ using {DefaultNamespace}.A.B.C; @@ -547,69 +547,69 @@ class Class2 }} }}"; - var originalSources = new[] - { - (Path.Combine(folder, "Class1.cs"), code1), - ("Class2.cs", code2) - }; + var originalSources = new[] + { + (Path.Combine(folder, "Class1.cs"), code1), + ("Class2.cs", code2) + }; - var fixedSources = new[] - { - (Path.Combine(folder, "Class1.cs"), fixed1), - ("Class2.cs", fixed2) - }; + var fixedSources = new[] + { + (Path.Combine(folder, "Class1.cs"), fixed1), + ("Class2.cs", fixed2) + }; - await RunTestAsync(originalSources, fixedSources); - } + await RunTestAsync(originalSources, fixedSources); + } - [Fact] - public async Task DocumentAtRoot_NoDiagnostic() - { - var folder = CreateFolderPath(); + [Fact] + public async Task DocumentAtRoot_NoDiagnostic() + { + var folder = CreateFolderPath(); - var code = $@" + var code = $@" namespace {DefaultNamespace} {{ class C {{ }} }}"; - await RunTestAsync( - "File1.cs", - code, - folder); - } + await RunTestAsync( + "File1.cs", + code, + folder); + } - [Fact] - public async Task DocumentAtRoot_ChangeNamespace() - { - var folder = CreateFolderPath(); + [Fact] + public async Task DocumentAtRoot_ChangeNamespace() + { + var folder = CreateFolderPath(); - var code = + var code = $@"namespace [|{DefaultNamespace}.Test|] {{ class C {{ }} }}"; - var fixedCode = + var fixedCode = $@"namespace {DefaultNamespace} {{ class C {{ }} }}"; - await RunTestAsync( - "File1.cs", - code, - folder, - fixedCode: fixedCode); - } + await RunTestAsync( + "File1.cs", + code, + folder, + fixedCode: fixedCode); + } - [Fact] - public async Task ChangeNamespace_WithAliasReferencesInOtherDocument() - { - var declaredNamespace = $"Bar.Baz"; + [Fact] + public async Task ChangeNamespace_WithAliasReferencesInOtherDocument() + { + var declaredNamespace = $"Bar.Baz"; - var folder = CreateFolderPath("A", "B", "C"); - var code1 = + var folder = CreateFolderPath("A", "B", "C"); + var code1 = $@"namespace [|{declaredNamespace}|] {{ class Class1 @@ -617,7 +617,7 @@ class Class1 }} }}"; - var code2 = $@" + var code2 = $@" using System; using {declaredNamespace}; using Class1Alias = {declaredNamespace}.Class1; @@ -630,7 +630,7 @@ class RefClass }} }}"; - var fixed1 = + var fixed1 = @$"namespace {DefaultNamespace}.A.B.C {{ class Class1 @@ -638,7 +638,7 @@ class Class1 }} }}"; - var fixed2 = + var fixed2 = @$" using System; using Class1Alias = {DefaultNamespace}.A.B.C.Class1; @@ -651,36 +651,36 @@ class RefClass }} }}"; - var originalSources = new[] - { - (Path.Combine(folder, "Class1.cs"), code1), - ("Class2.cs", code2) - }; + var originalSources = new[] + { + (Path.Combine(folder, "Class1.cs"), code1), + ("Class2.cs", code2) + }; - var fixedSources = new[] - { - (Path.Combine(folder, "Class1.cs"), fixed1), - ("Class2.cs", fixed2) - }; + var fixedSources = new[] + { + (Path.Combine(folder, "Class1.cs"), fixed1), + ("Class2.cs", fixed2) + }; - await RunTestAsync(originalSources, fixedSources); - } + await RunTestAsync(originalSources, fixedSources); + } - [Fact] - public async Task FixAll() - { - var declaredNamespace = "Bar.Baz"; + [Fact] + public async Task FixAll() + { + var declaredNamespace = "Bar.Baz"; - var folder1 = CreateFolderPath("A", "B", "C"); - var fixedNamespace1 = $"{DefaultNamespace}.A.B.C"; + var folder1 = CreateFolderPath("A", "B", "C"); + var fixedNamespace1 = $"{DefaultNamespace}.A.B.C"; - var folder2 = CreateFolderPath("Second", "Folder", "Path"); - var fixedNamespace2 = $"{DefaultNamespace}.Second.Folder.Path"; + var folder2 = CreateFolderPath("Second", "Folder", "Path"); + var fixedNamespace2 = $"{DefaultNamespace}.Second.Folder.Path"; - var folder3 = CreateFolderPath("Third", "Folder", "Path"); - var fixedNamespace3 = $"{DefaultNamespace}.Third.Folder.Path"; + var folder3 = CreateFolderPath("Third", "Folder", "Path"); + var fixedNamespace3 = $"{DefaultNamespace}.Third.Folder.Path"; - var code1 = + var code1 = $@"namespace [|{declaredNamespace}|] {{ class Class1 @@ -690,7 +690,7 @@ class Class1 }} }}"; - var fixed1 = + var fixed1 = $@"using {fixedNamespace2}; using {fixedNamespace3}; @@ -703,7 +703,7 @@ class Class1 }} }}"; - var code2 = + var code2 = $@"namespace [|{declaredNamespace}|] {{ class Class2 @@ -713,7 +713,7 @@ class Class2 }} }}"; - var fixed2 = + var fixed2 = $@"using {fixedNamespace1}; using {fixedNamespace3}; @@ -726,7 +726,7 @@ class Class2 }} }}"; - var code3 = + var code3 = $@"namespace [|{declaredNamespace}|] {{ class Class3 @@ -736,7 +736,7 @@ class Class3 }} }}"; - var fixed3 = + var fixed3 = $@"using {fixedNamespace1}; using {fixedNamespace2}; @@ -749,38 +749,38 @@ class Class3 }} }}"; - var sources = new[] - { - (Path.Combine(folder1, "Class1.cs"), code1), - (Path.Combine(folder2, "Class2.cs"), code2), - (Path.Combine(folder3, "Class3.cs"), code3), - }; + var sources = new[] + { + (Path.Combine(folder1, "Class1.cs"), code1), + (Path.Combine(folder2, "Class2.cs"), code2), + (Path.Combine(folder3, "Class3.cs"), code3), + }; - var fixedSources = new[] - { - (Path.Combine(folder1, "Class1.cs"), fixed1), - (Path.Combine(folder2, "Class2.cs"), fixed2), - (Path.Combine(folder3, "Class3.cs"), fixed3), - }; + var fixedSources = new[] + { + (Path.Combine(folder1, "Class1.cs"), fixed1), + (Path.Combine(folder2, "Class2.cs"), fixed2), + (Path.Combine(folder3, "Class3.cs"), fixed3), + }; - await RunTestAsync(sources, fixedSources); - } + await RunTestAsync(sources, fixedSources); + } - [Fact] - public async Task FixAll_MultipleProjects() - { - var declaredNamespace = "Bar.Baz"; + [Fact] + public async Task FixAll_MultipleProjects() + { + var declaredNamespace = "Bar.Baz"; - var folder1 = CreateFolderPath("A", "B", "C"); - var fixedNamespace1 = $"{DefaultNamespace}.A.B.C"; + var folder1 = CreateFolderPath("A", "B", "C"); + var fixedNamespace1 = $"{DefaultNamespace}.A.B.C"; - var folder2 = CreateFolderPath("Second", "Folder", "Path"); - var fixedNamespace2 = $"{DefaultNamespace}.Second.Folder.Path"; + var folder2 = CreateFolderPath("Second", "Folder", "Path"); + var fixedNamespace2 = $"{DefaultNamespace}.Second.Folder.Path"; - var folder3 = CreateFolderPath("Third", "Folder", "Path"); - var fixedNamespace3 = $"{DefaultNamespace}.Third.Folder.Path"; + var folder3 = CreateFolderPath("Third", "Folder", "Path"); + var fixedNamespace3 = $"{DefaultNamespace}.Third.Folder.Path"; - var code1 = + var code1 = $@"namespace [|{declaredNamespace}|] {{ public class Class1 @@ -790,7 +790,7 @@ public class Class1 }} }}"; - var fixed1 = + var fixed1 = $@"using {fixedNamespace2}; using {fixedNamespace3}; @@ -803,7 +803,7 @@ public class Class1 }} }}"; - var code2 = + var code2 = $@"namespace [|{declaredNamespace}|] {{ class Class2 @@ -813,7 +813,7 @@ class Class2 }} }}"; - var fixed2 = + var fixed2 = $@"using {fixedNamespace1}; using {fixedNamespace3}; @@ -826,7 +826,7 @@ class Class2 }} }}"; - var code3 = + var code3 = $@"namespace [|{declaredNamespace}|] {{ class Class3 @@ -836,7 +836,7 @@ class Class3 }} }}"; - var fixed3 = + var fixed3 = $@"using {fixedNamespace1}; using {fixedNamespace2}; @@ -849,15 +849,15 @@ class Class3 }} }}"; - var project2Directory = "/Project2/"; - var project2folder = Path.Combine(project2Directory, "A", "B", "C"); - var project2EditorConfig = @$" + var project2Directory = "/Project2/"; + var project2folder = Path.Combine(project2Directory, "A", "B", "C"); + var project2EditorConfig = @$" is_global=true build_property.ProjectDir = {project2Directory} build_property.RootNamespace = {DefaultNamespace} "; - var project2Source = + var project2Source = @$"using {declaredNamespace}; namespace [|Project2.Test|] @@ -868,7 +868,7 @@ class P }} }}"; - var project2FixedSource = + var project2FixedSource = $@"namespace {fixedNamespace1} {{ class P @@ -877,85 +877,85 @@ class P }} }}"; - var testState = new VerifyCS.Test + var testState = new VerifyCS.Test + { + EditorConfig = EditorConfig, + CodeFixTestBehaviors = CodeAnalysis.Testing.CodeFixTestBehaviors.SkipFixAllInDocumentCheck | CodeAnalysis.Testing.CodeFixTestBehaviors.SkipFixAllInProjectCheck, + LanguageVersion = LanguageVersion.CSharp10, + TestState = { - EditorConfig = EditorConfig, - CodeFixTestBehaviors = CodeAnalysis.Testing.CodeFixTestBehaviors.SkipFixAllInDocumentCheck | CodeAnalysis.Testing.CodeFixTestBehaviors.SkipFixAllInProjectCheck, - LanguageVersion = LanguageVersion.CSharp10, - TestState = + Sources = { - Sources = - { - (Path.Combine(folder1, "Class1.cs"), code1), - (Path.Combine(folder2, "Class2.cs"), code2), - (Path.Combine(folder3, "Class3.cs"), code3), - }, - AdditionalProjects = - { - ["Project2"] = - { - AdditionalProjectReferences = { "TestProject" }, - Sources = { (Path.Combine(project2folder, "P.cs"), project2Source) }, - AnalyzerConfigFiles = { (Path.Combine(project2Directory, ".editorconfig"), project2EditorConfig) }, - }, - }, + (Path.Combine(folder1, "Class1.cs"), code1), + (Path.Combine(folder2, "Class2.cs"), code2), + (Path.Combine(folder3, "Class3.cs"), code3), }, - FixedState = + AdditionalProjects = { - Sources = + ["Project2"] = { - (Path.Combine(folder1, "Class1.cs"), fixed1), - (Path.Combine(folder2, "Class2.cs"), fixed2), - (Path.Combine(folder3, "Class3.cs"), fixed3), + AdditionalProjectReferences = { "TestProject" }, + Sources = { (Path.Combine(project2folder, "P.cs"), project2Source) }, + AnalyzerConfigFiles = { (Path.Combine(project2Directory, ".editorconfig"), project2EditorConfig) }, }, - AdditionalProjects = + }, + }, + FixedState = + { + Sources = + { + (Path.Combine(folder1, "Class1.cs"), fixed1), + (Path.Combine(folder2, "Class2.cs"), fixed2), + (Path.Combine(folder3, "Class3.cs"), fixed3), + }, + AdditionalProjects = + { + ["Project2"] = { - ["Project2"] = - { - AdditionalProjectReferences = { "TestProject" }, - Sources = { (Path.Combine(project2folder, "P.cs"), project2FixedSource) }, - AnalyzerConfigFiles = { (Path.Combine(project2Directory, ".editorconfig"), project2EditorConfig) }, - } + AdditionalProjectReferences = { "TestProject" }, + Sources = { (Path.Combine(project2folder, "P.cs"), project2FixedSource) }, + AnalyzerConfigFiles = { (Path.Combine(project2Directory, ".editorconfig"), project2EditorConfig) }, } } - }; + } + }; - testState.SolutionTransforms.Add((solution, projectId) => + testState.SolutionTransforms.Add((solution, projectId) => + { + foreach (var id in solution.ProjectIds) { - foreach (var id in solution.ProjectIds) - { - var project = solution.GetRequiredProject(id); - solution = project.WithDefaultNamespace(DefaultNamespace).Solution; - } - return solution; - }); + var project = solution.GetRequiredProject(id); + solution = project.WithDefaultNamespace(DefaultNamespace).Solution; + } + return solution; + }); - await testState.RunAsync(); - } + await testState.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58372")] - public async Task InvalidProjectName_ChangeNamespace() - { - var defaultNamespace = "Invalid-Namespace"; - var editorConfig = @$" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58372")] + public async Task InvalidProjectName_ChangeNamespace() + { + var defaultNamespace = "Invalid-Namespace"; + var editorConfig = @$" is_global=true build_property.ProjectDir = {Directory} build_property.RootNamespace = {defaultNamespace} "; - var folder = CreateFolderPath(["B", "C"]); - var code = - """ - namespace [|A.B|] + var folder = CreateFolderPath(["B", "C"]); + var code = + """ + namespace [|A.B|] + { + class Class1 { - class Class1 - { - } } - """; + } + """; - // The project name is invalid so the default namespace is not prepended - var fixedCode = + // The project name is invalid so the default namespace is not prepended + var fixedCode = @$"namespace B.C {{ class Class1 @@ -963,64 +963,63 @@ class Class1 }} }}"; - await RunTestAsync( - "Class1.cs", - fileContents: code, - fixedCode: fixedCode, - directory: folder, - editorConfig: editorConfig, - defaultNamespace: defaultNamespace); - } + await RunTestAsync( + "Class1.cs", + fileContents: code, + fixedCode: fixedCode, + directory: folder, + editorConfig: editorConfig, + defaultNamespace: defaultNamespace); + } - [Fact] - public async Task InvalidProjectName_DocumentAtRoot_ChangeNamespace() - { - var defaultNamespace = "Invalid-Namespace"; - var editorConfig = @$" + [Fact] + public async Task InvalidProjectName_DocumentAtRoot_ChangeNamespace() + { + var defaultNamespace = "Invalid-Namespace"; + var editorConfig = @$" is_global=true build_property.ProjectDir = {Directory} build_property.RootNamespace = {defaultNamespace} "; - var folder = CreateFolderPath(); + var folder = CreateFolderPath(); - var code = + var code = $@"namespace Test.Code {{ class C {{ }} }}"; - await RunTestAsync( - "Class1.cs", - fileContents: code, - directory: folder, - editorConfig: editorConfig, - defaultNamespace: defaultNamespace); - } + await RunTestAsync( + "Class1.cs", + fileContents: code, + directory: folder, + editorConfig: editorConfig, + defaultNamespace: defaultNamespace); + } - [Fact] - public async Task InvalidRootNamespace_DocumentAtRoot_ChangeNamespace() - { - var editorConfig = @$" + [Fact] + public async Task InvalidRootNamespace_DocumentAtRoot_ChangeNamespace() + { + var editorConfig = @$" is_global=true build_property.ProjectDir = {Directory} build_property.RootNamespace = Test.Code # not an editorconfig comment even though it looks like one "; - var folder = CreateFolderPath(); + var folder = CreateFolderPath(); - var code = + var code = $@"namespace Test.Code {{ class C {{ }} }}"; - await RunTestAsync( - "Class1.cs", - fileContents: code, - directory: folder, - editorConfig: editorConfig, - defaultNamespace: "Invalid-Namespace"); - } + await RunTestAsync( + "Class1.cs", + fileContents: code, + directory: folder, + editorConfig: editorConfig, + defaultNamespace: "Invalid-Namespace"); } } diff --git a/src/Analyzers/CSharp/Tests/MisplacedUsingDirectives/MisplacedUsingDirectivesTests.cs b/src/Analyzers/CSharp/Tests/MisplacedUsingDirectives/MisplacedUsingDirectivesTests.cs index e7c3ad44d4326..2150b21ae5ebd 100644 --- a/src/Analyzers/CSharp/Tests/MisplacedUsingDirectives/MisplacedUsingDirectivesTests.cs +++ b/src/Analyzers/CSharp/Tests/MisplacedUsingDirectives/MisplacedUsingDirectivesTests.cs @@ -17,1135 +17,1134 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MisplacedUsingDirectives +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MisplacedUsingDirectives; + +public class MisplacedUsingDirectivesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - public class MisplacedUsingDirectivesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public MisplacedUsingDirectivesTests(ITestOutputHelper logger) + : base(logger) { - public MisplacedUsingDirectivesTests(ITestOutputHelper logger) - : base(logger) + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new MisplacedUsingDirectivesDiagnosticAnalyzer(), new MisplacedUsingDirectivesCodeFixProvider()); + + internal static readonly CodeStyleOption2 OutsidePreferPreservationOption = + new(AddImportPlacement.OutsideNamespace, NotificationOption2.None); + + internal static readonly CodeStyleOption2 InsidePreferPreservationOption = + new(AddImportPlacement.InsideNamespace, NotificationOption2.None); + + internal static readonly CodeStyleOption2 InsideNamespaceOption = + new(AddImportPlacement.InsideNamespace, NotificationOption2.Error); + + internal static readonly CodeStyleOption2 OutsideNamespaceOption = + new(AddImportPlacement.OutsideNamespace, NotificationOption2.Error); + + protected const string ClassDefinition = """ + public class TestClass { } + """; - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new MisplacedUsingDirectivesDiagnosticAnalyzer(), new MisplacedUsingDirectivesCodeFixProvider()); + protected const string StructDefinition = """ + public struct TestStruct + { + } + """; - internal static readonly CodeStyleOption2 OutsidePreferPreservationOption = - new(AddImportPlacement.OutsideNamespace, NotificationOption2.None); + protected const string InterfaceDefinition = """ + public interface TestInterface + { + } + """; - internal static readonly CodeStyleOption2 InsidePreferPreservationOption = - new(AddImportPlacement.InsideNamespace, NotificationOption2.None); + protected const string EnumDefinition = """ + public enum TestEnum + { + TestValue + } + """; - internal static readonly CodeStyleOption2 InsideNamespaceOption = - new(AddImportPlacement.InsideNamespace, NotificationOption2.Error); + protected const string DelegateDefinition = @"public delegate void TestDelegate();"; - internal static readonly CodeStyleOption2 OutsideNamespaceOption = - new(AddImportPlacement.OutsideNamespace, NotificationOption2.Error); + private TestParameters GetTestParameters(CodeStyleOption2 preferredPlacementOption) + => new(options: new OptionsCollection(GetLanguage()) { { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredPlacementOption } }); - protected const string ClassDefinition = """ - public class TestClass - { - } - """; + private protected Task TestDiagnosticMissingAsync(string initialMarkup, CodeStyleOption2 preferredPlacementOption) + => TestDiagnosticMissingAsync(initialMarkup, GetTestParameters(preferredPlacementOption)); + + private protected Task TestMissingAsync(string initialMarkup, CodeStyleOption2 preferredPlacementOption) + => TestMissingAsync(initialMarkup, GetTestParameters(preferredPlacementOption)); + + private protected Task TestInRegularAndScriptAsync(string initialMarkup, string expectedMarkup, CodeStyleOption2 preferredPlacementOption, bool placeSystemNamespaceFirst) + { + var options = new OptionsCollection(GetLanguage()) + { + { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredPlacementOption }, + { GenerationOptions.PlaceSystemNamespaceFirst, placeSystemNamespaceFirst }, + }; + return TestInRegularAndScriptAsync( + initialMarkup, expectedMarkup, options: options, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10)); + } - protected const string StructDefinition = """ - public struct TestStruct + #region Test Preserve + + /// + /// Verifies that valid using statements in a namespace does not produce any diagnostics. + /// + [Fact] + public Task WhenPreserve_UsingsInNamespace_ValidUsingStatements() + { + var testCode = """ + namespace TestNamespace { + [|using System; + using System.Threading;|] } """; - protected const string InterfaceDefinition = """ - public interface TestInterface - { - } + return TestDiagnosticMissingAsync(testCode, OutsidePreferPreservationOption); + } + + [Fact] + public Task WhenPreserve_UsingsInNamespace_ValidUsingStatements_FileScopedNamespace() + { + var testCode = """ + namespace TestNamespace; + + [|using System; + using System.Threading;|] """; - protected const string EnumDefinition = """ - public enum TestEnum + return TestDiagnosticMissingAsync(testCode, OutsidePreferPreservationOption); + } + + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics, nor will + /// having using statements inside a namespace. + /// + [Fact] + public Task WhenPreserve_UsingsInCompilationUnitAndNamespace_ValidUsingStatements() + { + var testCode = """ + using System; + + namespace TestNamespace { - TestValue + [|using System.Threading;|] } """; - protected const string DelegateDefinition = @"public delegate void TestDelegate();"; + return TestDiagnosticMissingAsync(testCode, OutsidePreferPreservationOption); + } - private TestParameters GetTestParameters(CodeStyleOption2 preferredPlacementOption) - => new(options: new OptionsCollection(GetLanguage()) { { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredPlacementOption } }); + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are type definition present. + /// + /// The type definition to test. + [Theory] + [InlineData(ClassDefinition)] + [InlineData(StructDefinition)] + [InlineData(InterfaceDefinition)] + [InlineData(EnumDefinition)] + [InlineData(DelegateDefinition)] + public Task WhenPreserve_UsingsInCompilationUnitWithTypeDefinition_ValidUsingStatements(string typeDefinition) + { + var testCode = $""" + [|using System;|] - private protected Task TestDiagnosticMissingAsync(string initialMarkup, CodeStyleOption2 preferredPlacementOption) - => TestDiagnosticMissingAsync(initialMarkup, GetTestParameters(preferredPlacementOption)); + {typeDefinition} + """; - private protected Task TestMissingAsync(string initialMarkup, CodeStyleOption2 preferredPlacementOption) - => TestMissingAsync(initialMarkup, GetTestParameters(preferredPlacementOption)); + return TestDiagnosticMissingAsync(testCode, InsidePreferPreservationOption); + } - private protected Task TestInRegularAndScriptAsync(string initialMarkup, string expectedMarkup, CodeStyleOption2 preferredPlacementOption, bool placeSystemNamespaceFirst) - { - var options = new OptionsCollection(GetLanguage()) - { - { CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredPlacementOption }, - { GenerationOptions.PlaceSystemNamespaceFirst, placeSystemNamespaceFirst }, - }; - return TestInRegularAndScriptAsync( - initialMarkup, expectedMarkup, options: options, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10)); - } + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are attributes present. + /// + [Fact] + public Task WhenPreserve_UsingsInCompilationUnitWithAttributes_ValidUsingStatements() + { + var testCode = """ + [|using System.Reflection;|] - #region Test Preserve + [assembly: AssemblyVersion("1.0.0.0")] - /// - /// Verifies that valid using statements in a namespace does not produce any diagnostics. - /// - [Fact] - public Task WhenPreserve_UsingsInNamespace_ValidUsingStatements() - { - var testCode = """ - namespace TestNamespace - { - [|using System; - using System.Threading;|] - } - """; + namespace TestNamespace + { + using System; + using System.Threading; + } + """; - return TestDiagnosticMissingAsync(testCode, OutsidePreferPreservationOption); - } + return TestDiagnosticMissingAsync(testCode, InsidePreferPreservationOption); + } - [Fact] - public Task WhenPreserve_UsingsInNamespace_ValidUsingStatements_FileScopedNamespace() - { - var testCode = """ - namespace TestNamespace; + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics, even if they could be + /// moved inside a namespace. + /// + [Fact] + public Task WhenPreserve_UsingsInCompilationUnit_ValidUsingStatements() + { + var testCode = """ + [|using System; + using System.Threading;|] - [|using System; - using System.Threading;|] - """; + namespace TestNamespace + { + } + """; - return TestDiagnosticMissingAsync(testCode, OutsidePreferPreservationOption); - } + return TestDiagnosticMissingAsync(testCode, InsidePreferPreservationOption); + } - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics, nor will - /// having using statements inside a namespace. - /// - [Fact] - public Task WhenPreserve_UsingsInCompilationUnitAndNamespace_ValidUsingStatements() - { - var testCode = """ - using System; + #endregion - namespace TestNamespace - { - [|using System.Threading;|] - } - """; + #region Test OutsideNamespace - return TestDiagnosticMissingAsync(testCode, OutsidePreferPreservationOption); - } + /// + /// Verifies that valid using statements in the compilation unit does not produce any diagnostics. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInCompilationUnit_ValidUsingStatements() + { + var testCode = """ + [|using System; + using System.Threading;|] - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are type definition present. - /// - /// The type definition to test. - [Theory] - [InlineData(ClassDefinition)] - [InlineData(StructDefinition)] - [InlineData(InterfaceDefinition)] - [InlineData(EnumDefinition)] - [InlineData(DelegateDefinition)] - public Task WhenPreserve_UsingsInCompilationUnitWithTypeDefinition_ValidUsingStatements(string typeDefinition) - { - var testCode = $""" - [|using System;|] + namespace TestNamespace + { + } + """; - {typeDefinition} - """; + return TestDiagnosticMissingAsync(testCode, OutsideNamespaceOption); + } - return TestDiagnosticMissingAsync(testCode, InsidePreferPreservationOption); - } + [Fact] + public Task WhenOutsidePreferred_UsingsInCompilationUnit_ValidUsingStatements_FileScopedNamespace() + { + var testCode = """ + [|using System; + using System.Threading;|] - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are attributes present. - /// - [Fact] - public Task WhenPreserve_UsingsInCompilationUnitWithAttributes_ValidUsingStatements() - { - var testCode = """ - [|using System.Reflection;|] + namespace TestNamespace; + """; - [assembly: AssemblyVersion("1.0.0.0")] + return TestDiagnosticMissingAsync(testCode, OutsideNamespaceOption); + } - namespace TestNamespace - { - using System; - using System.Threading; - } - """; + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are type definition present. + /// + /// The type definition to test. + [Theory] + [InlineData(ClassDefinition)] + [InlineData(StructDefinition)] + [InlineData(InterfaceDefinition)] + [InlineData(EnumDefinition)] + [InlineData(DelegateDefinition)] + public Task WhenOutsidePreferred_UsingsInCompilationUnitWithMember_ValidUsingStatements(string typeDefinition) + { + var testCode = $""" + [|using System;|] - return TestDiagnosticMissingAsync(testCode, InsidePreferPreservationOption); - } + {typeDefinition} + """; - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics, even if they could be - /// moved inside a namespace. - /// - [Fact] - public Task WhenPreserve_UsingsInCompilationUnit_ValidUsingStatements() - { - var testCode = """ + return TestDiagnosticMissingAsync(testCode, OutsideNamespaceOption); + } + + /// + /// Verifies that using statements in a namespace produces the expected diagnostics. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMoved() + { + var testCode = """ + namespace TestNamespace + { [|using System; using System.Threading;|] + } + """; + var fixedTestCode = """ + {|Warning:using System;|} + {|Warning:using System.Threading;|} - namespace TestNamespace - { - } - """; + namespace TestNamespace + { + } + """; - return TestDiagnosticMissingAsync(testCode, InsidePreferPreservationOption); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - #endregion + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMoved_FileScopedNamespace() + { + var testCode = """ + namespace TestNamespace; - #region Test OutsideNamespace + [|using System; + using System.Threading;|] + """; + var fixedTestCode = """ - /// - /// Verifies that valid using statements in the compilation unit does not produce any diagnostics. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInCompilationUnit_ValidUsingStatements() - { - var testCode = """ - [|using System; - using System.Threading;|] + {|Warning:using System;|} + {|Warning:using System.Threading;|} + namespace TestNamespace; - namespace TestNamespace - { - } - """; + """; - return TestDiagnosticMissingAsync(testCode, OutsideNamespaceOption); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - [Fact] - public Task WhenOutsidePreferred_UsingsInCompilationUnit_ValidUsingStatements_FileScopedNamespace() - { - var testCode = """ + /// + /// Verifies that simplified using statements in a namespace are expanded during the code fix operation. + /// + [Fact] + public Task WhenOutsidePreferred_SimplifiedUsingInNamespace_UsingsMovedAndExpanded() + { + var testCode = """ + namespace System + { [|using System; - using System.Threading;|] + using System.Threading; + using Reflection;|] + } + """; + var fixedTestCode = """ + {|Warning:using System;|} + {|Warning:using System.Threading;|} + {|Warning:using System.Reflection;|} - namespace TestNamespace; - """; + namespace System + { + } + """; - return TestDiagnosticMissingAsync(testCode, OutsideNamespaceOption); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are type definition present. - /// - /// The type definition to test. - [Theory] - [InlineData(ClassDefinition)] - [InlineData(StructDefinition)] - [InlineData(InterfaceDefinition)] - [InlineData(EnumDefinition)] - [InlineData(DelegateDefinition)] - public Task WhenOutsidePreferred_UsingsInCompilationUnitWithMember_ValidUsingStatements(string typeDefinition) - { - var testCode = $""" + /// + /// Verifies that the code fix will move the using directives when they are present in both the compilation unit and namespace. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInBoth_UsingsMoved() + { + var testCode = """ + using Microsoft.CodeAnalysis; + + namespace TestNamespace + { [|using System;|] + } + """; - {typeDefinition} - """; + var fixedTestCode = """ + using Microsoft.CodeAnalysis; + {|Warning:using System;|} - return TestDiagnosticMissingAsync(testCode, OutsideNamespaceOption); - } + namespace TestNamespace + { + } + """; - /// - /// Verifies that using statements in a namespace produces the expected diagnostics. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMoved() - { - var testCode = """ - namespace TestNamespace - { - [|using System; - using System.Threading;|] - } - """; - var fixedTestCode = """ - {|Warning:using System;|} - {|Warning:using System.Threading;|} + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - namespace TestNamespace - { - } - """; + /// + /// Verifies that simplified using statements in a namespace are expanded during the code fix operation. + /// + [Fact] + public Task WhenOutsidePreferred_SimplifiedUsingAliasInNamespace_UsingsMovedAndExpanded() + { + var testCode = """ + namespace System.MyExtension + { + [|using System.Threading; + using Reflection; + using Assembly = Reflection.Assembly; + using List = Collections.Generic.IList;|] + } + """; + var fixedTestCode = """ + {|Warning:using System.Threading;|} + {|Warning:using System.Reflection;|} + {|Warning:using Assembly = System.Reflection.Assembly;|} + {|Warning:using List = System.Collections.Generic.IList;|} - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace System.MyExtension + { + } + """; - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMoved_FileScopedNamespace() - { - var testCode = """ - namespace TestNamespace; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } + + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are attributes present. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespaceAndCompilationUnitWithAttributes_UsingsMoved() + { + var testCode = """ + using System.Reflection; + + [assembly: AssemblyVersion("1.0.0.0")] + namespace TestNamespace + { [|using System; using System.Threading;|] - """; - var fixedTestCode = """ + } + """; + var fixedTestCode = """ + using System.Reflection; + {|Warning:using System;|} + {|Warning:using System.Threading;|} - {|Warning:using System;|} - {|Warning:using System.Threading;|} - namespace TestNamespace; + [assembly: AssemblyVersion("1.0.0.0")] - """; + namespace TestNamespace + { + } + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - /// - /// Verifies that simplified using statements in a namespace are expanded during the code fix operation. - /// - [Fact] - public Task WhenOutsidePreferred_SimplifiedUsingInNamespace_UsingsMovedAndExpanded() - { - var testCode = """ - namespace System - { - [|using System; - using System.Threading; - using Reflection;|] - } - """; - var fixedTestCode = """ - {|Warning:using System;|} - {|Warning:using System.Threading;|} - {|Warning:using System.Reflection;|} + /// + /// Verifies that the file header of a file is properly preserved when moving using statements out of a namespace. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespaceAndCompilationUnitHasFileHeader_UsingsMovedAndHeaderPreserved() + { + var testCode = """ + // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. + // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. - namespace System - { - } - """; + namespace TestNamespace + { + [|using System;|] + } + """; + var fixedTestCode = """ + // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. + // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + {|Warning:using System;|} - /// - /// Verifies that the code fix will move the using directives when they are present in both the compilation unit and namespace. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInBoth_UsingsMoved() - { - var testCode = """ - using Microsoft.CodeAnalysis; + namespace TestNamespace + { + } + """; - namespace TestNamespace - { - [|using System;|] - } - """; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - var fixedTestCode = """ - using Microsoft.CodeAnalysis; - {|Warning:using System;|} + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespaceWithCommentsAndCompilationUnitHasFileHeader_UsingsMovedWithCommentsAndHeaderPreserved() + { + var testCode = """ + // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. + // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. - namespace TestNamespace - { - } - """; + namespace TestNamespace + { + // Separated Comment - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + [|using System.Collections; + // Comment + using System;|] + } + """; + var fixedTestCode = """ + // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. + // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. - /// - /// Verifies that simplified using statements in a namespace are expanded during the code fix operation. - /// - [Fact] - public Task WhenOutsidePreferred_SimplifiedUsingAliasInNamespace_UsingsMovedAndExpanded() - { - var testCode = """ - namespace System.MyExtension - { - [|using System.Threading; - using Reflection; - using Assembly = Reflection.Assembly; - using List = Collections.Generic.IList;|] - } - """; - var fixedTestCode = """ - {|Warning:using System.Threading;|} - {|Warning:using System.Reflection;|} - {|Warning:using Assembly = System.Reflection.Assembly;|} - {|Warning:using List = System.Collections.Generic.IList;|} + // Separated Comment - namespace System.MyExtension - { - } - """; + {|Warning:using System.Collections;|} + // Comment + {|Warning:using System;|} - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace TestNamespace + { + } + """; - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are attributes present. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespaceAndCompilationUnitWithAttributes_UsingsMoved() - { - var testCode = """ - using System.Reflection; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - [assembly: AssemblyVersion("1.0.0.0")] + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMovedAndSystemPlacedFirstIgnored() + { + var testCode = """ + namespace Foo + { + [|using Microsoft.CodeAnalysis; + using SystemAction = System.Action; + using static System.Math; + using System; - namespace TestNamespace - { - [|using System; - using System.Threading;|] - } - """; - var fixedTestCode = """ - using System.Reflection; - {|Warning:using System;|} - {|Warning:using System.Threading;|} + using static System.String; + using MyFunc = System.Func; - [assembly: AssemblyVersion("1.0.0.0")] + using System.Collections.Generic; + using System.Collections;|] - namespace TestNamespace + public class Bar { } - """; + } + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + var fixedTestCode = """ + {|Warning:using Microsoft.CodeAnalysis;|} + {|Warning:using SystemAction = System.Action;|} + {|Warning:using static System.Math;|} + {|Warning:using System;|} - /// - /// Verifies that the file header of a file is properly preserved when moving using statements out of a namespace. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespaceAndCompilationUnitHasFileHeader_UsingsMovedAndHeaderPreserved() - { - var testCode = """ - // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. - // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + {|Warning:using static System.String;|} + {|Warning:using MyFunc = System.Func;|} - namespace TestNamespace + {|Warning:using System.Collections.Generic;|} + {|Warning:using System.Collections;|} + + namespace Foo + { + public class Bar { - [|using System;|] } - """; - var fixedTestCode = """ - // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. - // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + } + """; - {|Warning:using System;|} + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - namespace TestNamespace - { - } - """; + [Fact] + public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMovedAndAlphaSortIgnored() + { + var testCode = """ + namespace Foo + { + [|using Microsoft.CodeAnalysis; + using SystemAction = System.Action; + using static System.Math; + using System; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + using static System.String; + using MyFunc = System.Func; - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespaceWithCommentsAndCompilationUnitHasFileHeader_UsingsMovedWithCommentsAndHeaderPreserved() - { - var testCode = """ - // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. - // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + using System.Collections.Generic; + using System.Collections;|] - namespace TestNamespace + public class Bar { - // Separated Comment - - [|using System.Collections; - // Comment - using System;|] } - """; - var fixedTestCode = """ - // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. - // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. + } + """; - // Separated Comment + var fixedTestCode = """ + {|Warning:using Microsoft.CodeAnalysis;|} + {|Warning:using SystemAction = System.Action;|} + {|Warning:using static System.Math;|} + {|Warning:using System;|} - {|Warning:using System.Collections;|} - // Comment - {|Warning:using System;|} + {|Warning:using static System.String;|} + {|Warning:using MyFunc = System.Func;|} + + {|Warning:using System.Collections.Generic;|} + {|Warning:using System.Collections;|} - namespace TestNamespace + namespace Foo + { + public class Bar { } - """; + } + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: false); + } - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMovedAndSystemPlacedFirstIgnored() - { - var testCode = """ - namespace Foo - { - [|using Microsoft.CodeAnalysis; - using SystemAction = System.Action; - using static System.Math; - using System; - - using static System.String; - using MyFunc = System.Func; - - using System.Collections.Generic; - using System.Collections;|] - - public class Bar - { - } - } - """; - - var fixedTestCode = """ - {|Warning:using Microsoft.CodeAnalysis;|} - {|Warning:using SystemAction = System.Action;|} - {|Warning:using static System.Math;|} - {|Warning:using System;|} - - {|Warning:using static System.String;|} - {|Warning:using MyFunc = System.Func;|} - - {|Warning:using System.Collections.Generic;|} - {|Warning:using System.Collections;|} - - namespace Foo - { - public class Bar - { - } - } - """; + /// + /// Verifies that simplified using statements in nested namespace are expanded during the code fix operation. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInNestedNamespaces_UsingsMovedAndExpanded() + { + var testCode = """ + using System; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace System.Namespace + { + // Outer Comment + [|using Threading; - [Fact] - public Task WhenOutsidePreferred_UsingsInNamespace_UsingsMovedAndAlphaSortIgnored() - { - var testCode = """ - namespace Foo + namespace OtherNamespace { - [|using Microsoft.CodeAnalysis; - using SystemAction = System.Action; - using static System.Math; - using System; - - using static System.String; - using MyFunc = System.Func; - - using System.Collections.Generic; - using System.Collections;|] - - public class Bar - { - } + // Inner Comment + using Reflection;|] } - """; - - var fixedTestCode = """ - {|Warning:using Microsoft.CodeAnalysis;|} - {|Warning:using SystemAction = System.Action;|} - {|Warning:using static System.Math;|} - {|Warning:using System;|} - - {|Warning:using static System.String;|} - {|Warning:using MyFunc = System.Func;|} - - {|Warning:using System.Collections.Generic;|} - {|Warning:using System.Collections;|} - - namespace Foo + } + """; + var fixedTestCode = """ + using System; + // Outer Comment + {|Warning:using System.Threading;|} + // Inner Comment + {|Warning:using System.Reflection;|} + + namespace System.Namespace + { + namespace OtherNamespace { - public class Bar - { - } } - """; + } + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: false); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - /// - /// Verifies that simplified using statements in nested namespace are expanded during the code fix operation. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInNestedNamespaces_UsingsMovedAndExpanded() - { - var testCode = """ - using System; + /// + /// Verifies that simplified using statements in multiple namespaces are expanded during the code fix operation. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInMultipleNamespaces_UsingsMovedAndExpanded() + { + var testCode = """ + using System; - namespace System.Namespace - { - // Outer Comment - [|using Threading; - - namespace OtherNamespace - { - // Inner Comment - using Reflection;|] - } - } - """; - var fixedTestCode = """ - using System; - // Outer Comment - {|Warning:using System.Threading;|} - // Inner Comment - {|Warning:using System.Reflection;|} + namespace System.Namespace + { + // A Comment + [|using Threading; + } - namespace System.Namespace - { - namespace OtherNamespace - { - } - } - """; + namespace System.OtherNamespace + { + // Another Comment + using Reflection;|] + } + """; + var fixedTestCode = """ + using System; + // A Comment + {|Warning:using System.Threading;|} + // Another Comment + {|Warning:using System.Reflection;|} + + namespace System.Namespace + { + } - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace System.OtherNamespace + { + } + """; - /// - /// Verifies that simplified using statements in multiple namespaces are expanded during the code fix operation. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInMultipleNamespaces_UsingsMovedAndExpanded() - { - var testCode = """ - using System; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - namespace System.Namespace - { - // A Comment - [|using Threading; - } + /// + /// Verifies that simplified using statements in multiple namespaces are deduplicated during the code fix operation. + /// + [Fact] + public Task WhenOutsidePreferred_UsingsInMultipleNamespaces_UsingsMovedAndDeduplicated() + { + var testCode = """ + using System; - namespace System.OtherNamespace - { - // Another Comment - using Reflection;|] - } - """; - var fixedTestCode = """ - using System; + namespace System.Namespace + { + // Orphaned Comment 1 + [|using System; // A Comment - {|Warning:using System.Threading;|} - // Another Comment - {|Warning:using System.Reflection;|} - - namespace System.Namespace - { - } + using Threading; + } - namespace System.OtherNamespace - { - } - """; + namespace B + { + // Orphaned Comment 2 + using System.Threading;|] + } + """; + var fixedTestCode = """ + using System; + // Orphaned Comment 1 + // A Comment + {|Warning:using System.Threading;|} + // Orphaned Comment 2 + + namespace System.Namespace + { + } - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace B + { + } + """; - /// - /// Verifies that simplified using statements in multiple namespaces are deduplicated during the code fix operation. - /// - [Fact] - public Task WhenOutsidePreferred_UsingsInMultipleNamespaces_UsingsMovedAndDeduplicated() - { - var testCode = """ - using System; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - namespace System.Namespace - { - // Orphaned Comment 1 - [|using System; - // A Comment - using Threading; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61773")] + public Task WhenOutsidePreferred_MoveGlobalUsing1() + { + var testCode = """ + namespace N1 + { + [|global using System;|] + } + """; + var fixedTestCode = + """ + {|Warning:global using System;|} - namespace B - { - // Orphaned Comment 2 - using System.Threading;|] - } - """; - var fixedTestCode = """ - using System; - // Orphaned Comment 1 - // A Comment - {|Warning:using System.Threading;|} - // Orphaned Comment 2 + namespace N1 + { + } + """; - namespace System.Namespace - { - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); + } - namespace B - { - } - """; + #endregion - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + #region Test InsideNamespace - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61773")] - public Task WhenOutsidePreferred_MoveGlobalUsing1() - { - var testCode = """ - namespace N1 - { - [|global using System;|] - } - """; - var fixedTestCode = - """ - {|Warning:global using System;|} + /// + /// Verifies that valid using statements in a namespace does not produce any diagnostics. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInNamespace_ValidUsingStatements() + { + var testCode = """ + namespace TestNamespace + { + [|using System; + using System.Threading;|] + } + """; - namespace N1 - { - } - """; + return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); + } - return TestInRegularAndScriptAsync(testCode, fixedTestCode, OutsideNamespaceOption, placeSystemNamespaceFirst: true); - } + [Fact] + public Task WhenInsidePreferred_UsingsInNamespace_ValidUsingStatements_FileScopedNamespace() + { + var testCode = """ + namespace TestNamespace; - #endregion + [|using System; + using System.Threading;|] + """; - #region Test InsideNamespace + return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); + } - /// - /// Verifies that valid using statements in a namespace does not produce any diagnostics. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInNamespace_ValidUsingStatements() - { - var testCode = """ - namespace TestNamespace - { - [|using System; - using System.Threading;|] - } - """; + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are type definition present. + /// + /// The type definition to test. + [Theory] + [InlineData(ClassDefinition)] + [InlineData(StructDefinition)] + [InlineData(InterfaceDefinition)] + [InlineData(EnumDefinition)] + [InlineData(DelegateDefinition)] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithTypeDefinition_ValidUsingStatements(string typeDefinition) + { + var testCode = $""" + [|using System;|] - return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); - } + {typeDefinition} + """; - [Fact] - public Task WhenInsidePreferred_UsingsInNamespace_ValidUsingStatements_FileScopedNamespace() - { - var testCode = """ - namespace TestNamespace; + return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); + } - [|using System; - using System.Threading;|] - """; + /// + /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are attributes present. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithAttributes_ValidUsingStatements() + { + var testCode = """ + [|using System.Reflection;|] - return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); - } + [assembly: AssemblyVersion("1.0.0.0")] - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are type definition present. - /// - /// The type definition to test. - [Theory] - [InlineData(ClassDefinition)] - [InlineData(StructDefinition)] - [InlineData(InterfaceDefinition)] - [InlineData(EnumDefinition)] - [InlineData(DelegateDefinition)] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithTypeDefinition_ValidUsingStatements(string typeDefinition) - { - var testCode = $""" - [|using System;|] + namespace TestNamespace + { + using System; + using System.Threading; + } + """; - {typeDefinition} - """; + return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); + } - return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); - } + /// + /// Verifies that the code fix will move the using directives and not place System directives first. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnit_UsingsMovedAndSystemPlacedFirstIgnored() + { + var testCode = """ + [|using Microsoft.CodeAnalysis; + using SystemAction = System.Action; + using static System.Math; + using System; - /// - /// Verifies that having using statements in the compilation unit will not produce any diagnostics when there are attributes present. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithAttributes_ValidUsingStatements() - { - var testCode = """ - [|using System.Reflection;|] + using static System.String; + using MyFunc = System.Func; - [assembly: AssemblyVersion("1.0.0.0")] + using System.Collections.Generic; + using System.Collections;|] - namespace TestNamespace + namespace Foo + { + public class Bar { - using System; - using System.Threading; } - """; - - return TestDiagnosticMissingAsync(testCode, InsideNamespaceOption); - } + } + """; - /// - /// Verifies that the code fix will move the using directives and not place System directives first. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnit_UsingsMovedAndSystemPlacedFirstIgnored() - { - var testCode = """ - [|using Microsoft.CodeAnalysis; - using SystemAction = System.Action; - using static System.Math; - using System; + var fixedTestCode = """ + namespace Foo + { + {|Warning:using Microsoft.CodeAnalysis;|} + {|Warning:using SystemAction = System.Action;|} + {|Warning:using static System.Math;|} + {|Warning:using System;|} - using static System.String; - using MyFunc = System.Func; + {|Warning:using static System.String;|} + {|Warning:using MyFunc = System.Func;|} - using System.Collections.Generic; - using System.Collections;|] + {|Warning:using System.Collections.Generic;|} + {|Warning:using System.Collections;|} - namespace Foo + public class Bar { - public class Bar - { - } } - """; + } + """; - var fixedTestCode = """ - namespace Foo - { - {|Warning:using Microsoft.CodeAnalysis;|} - {|Warning:using SystemAction = System.Action;|} - {|Warning:using static System.Math;|} - {|Warning:using System;|} + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - {|Warning:using static System.String;|} - {|Warning:using MyFunc = System.Func;|} + /// + /// Verifies that the code fix will move the using directives and not sort them alphabetically. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnit_UsingsAndWithAlphaSortIgnored() + { + var testCode = """ + [|using Microsoft.CodeAnalysis; + using SystemAction = System.Action; + using static System.Math; + using System; - {|Warning:using System.Collections.Generic;|} - {|Warning:using System.Collections;|} + using static System.String; + using MyFunc = System.Func; - public class Bar - { - } - } - """; + using System.Collections.Generic; + using System.Collections;|] - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace NamespaceName + { + public class Bar + { + } + } + """; - /// - /// Verifies that the code fix will move the using directives and not sort them alphabetically. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnit_UsingsAndWithAlphaSortIgnored() - { - var testCode = """ - [|using Microsoft.CodeAnalysis; - using SystemAction = System.Action; - using static System.Math; - using System; + var fixedTestCode = """ + namespace NamespaceName + { + {|Warning:using Microsoft.CodeAnalysis;|} + {|Warning:using SystemAction = System.Action;|} + {|Warning:using static System.Math;|} + {|Warning:using System;|} - using static System.String; - using MyFunc = System.Func; + {|Warning:using static System.String;|} + {|Warning:using MyFunc = System.Func;|} - using System.Collections.Generic; - using System.Collections;|] + {|Warning:using System.Collections.Generic;|} + {|Warning:using System.Collections;|} - namespace NamespaceName + public class Bar { - public class Bar - { - } } - """; + } + """; - var fixedTestCode = """ - namespace NamespaceName - { - {|Warning:using Microsoft.CodeAnalysis;|} - {|Warning:using SystemAction = System.Action;|} - {|Warning:using static System.Math;|} - {|Warning:using System;|} + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: false); + } - {|Warning:using static System.String;|} - {|Warning:using MyFunc = System.Func;|} + /// + /// Verifies that the code fix will move the using directives, but will not move a file header comment separated by an new line. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithFileHeader_UsingsMovedNotHeader() + { + var testCode = """ + // This is a file header. + [|using Microsoft.CodeAnalysis; + using System;|] - {|Warning:using System.Collections.Generic;|} - {|Warning:using System.Collections;|} + namespace TestNamespace + { + } + """; - public class Bar - { - } - } - """; + var fixedTestCode = """ + // This is a file header. + namespace TestNamespace + { + {|Warning:using Microsoft.CodeAnalysis;|} + {|Warning:using System;|} + } + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: false); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - /// - /// Verifies that the code fix will move the using directives, but will not move a file header comment separated by an new line. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithFileHeader_UsingsMovedNotHeader() - { - var testCode = """ - // This is a file header. - [|using Microsoft.CodeAnalysis; - using System;|] + /// + /// Verifies that the code fix will move the using directives when they are present in both the compilation unit and namespace. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInBoth_UsingsMoved() + { + var testCode = """ + [|using Microsoft.CodeAnalysis;|] - namespace TestNamespace - { - } - """; + namespace TestNamespace + { + using System; + } + """; - var fixedTestCode = """ - // This is a file header. - namespace TestNamespace - { - {|Warning:using Microsoft.CodeAnalysis;|} - {|Warning:using System;|} - } - """; + var fixedTestCode = """ + namespace TestNamespace + { + {|Warning:using Microsoft.CodeAnalysis;|} + using System; + } + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - /// - /// Verifies that the code fix will move the using directives when they are present in both the compilation unit and namespace. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInBoth_UsingsMoved() - { - var testCode = """ - [|using Microsoft.CodeAnalysis;|] + [Fact] + public Task WhenInsidePreferred_UsingsInBoth_UsingsMoved_FileScopedNamespaec() + { + var testCode = """ + [|using Microsoft.CodeAnalysis;|] - namespace TestNamespace - { - using System; - } - """; + namespace TestNamespace; - var fixedTestCode = """ - namespace TestNamespace - { - {|Warning:using Microsoft.CodeAnalysis;|} - using System; - } - """; + using System; + """; - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + var fixedTestCode = """ + namespace TestNamespace; + {|Warning:using Microsoft.CodeAnalysis;|} - [Fact] - public Task WhenInsidePreferred_UsingsInBoth_UsingsMoved_FileScopedNamespaec() - { - var testCode = """ - [|using Microsoft.CodeAnalysis;|] + using System; + """; - namespace TestNamespace; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - using System; - """; + /// + /// Verifies that the code fix will properly move separated trivia, but will not move a file header comment. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithFileHeaderAndTrivia_UsingsAndTriviaMovedNotHeader() + { + var testCode = """ + // File Header - var fixedTestCode = """ - namespace TestNamespace; - {|Warning:using Microsoft.CodeAnalysis;|} + // Leading Comment - using System; - """; + [|using Microsoft.CodeAnalysis; + using System;|] - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace TestNamespace + { + } + """; - /// - /// Verifies that the code fix will properly move separated trivia, but will not move a file header comment. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithFileHeaderAndTrivia_UsingsAndTriviaMovedNotHeader() - { - var testCode = """ - // File Header + var fixedTestCode = """ + // File Header + namespace TestNamespace + { // Leading Comment - [|using Microsoft.CodeAnalysis; - using System;|] + {|Warning:using Microsoft.CodeAnalysis;|} + {|Warning:using System;|} + } + """; - namespace TestNamespace - { - } - """; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - var fixedTestCode = """ - // File Header + /// + /// Verifies that a code fix will not be offered for MisplacedUsing diagnostics when multiple namespaces are present. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithMultipleNamespaces_NoCodeFixOffered() + { + var testCode = """ + [|using System;|] - namespace TestNamespace + namespace TestNamespace1 + { + public class TestClass1 { - // Leading Comment - - {|Warning:using Microsoft.CodeAnalysis;|} - {|Warning:using System;|} } - """; - - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + } - /// - /// Verifies that a code fix will not be offered for MisplacedUsing diagnostics when multiple namespaces are present. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithMultipleNamespaces_NoCodeFixOffered() - { - var testCode = """ - [|using System;|] + namespace TestNamespace2 + { + } + """; - namespace TestNamespace1 - { - public class TestClass1 - { - } - } + return TestMissingAsync(testCode, InsideNamespaceOption); + } - namespace TestNamespace2 - { - } - """; + /// + /// Verifies that the code fix will properly move pragmas. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithPragma_PragmaMoved() + { + var testCode = """ + #pragma warning disable 1573 // Comment + [|using System; + using System.Threading;|] - return TestMissingAsync(testCode, InsideNamespaceOption); - } + namespace TestNamespace + { + } + """; - /// - /// Verifies that the code fix will properly move pragmas. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithPragma_PragmaMoved() - { - var testCode = """ - #pragma warning disable 1573 // Comment - [|using System; - using System.Threading;|] + var fixedTestCode = """ + namespace TestNamespace + { + #pragma warning disable 1573 // Comment + {|Warning:using System;|} + {|Warning:using System.Threading;|} + } + """; - namespace TestNamespace - { - } - """; + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - var fixedTestCode = """ - namespace TestNamespace - { - #pragma warning disable 1573 // Comment - {|Warning:using System;|} - {|Warning:using System.Threading;|} - } - """; + /// + /// Verifies that the code fix will properly move regions. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithRegion_RegionMoved() + { + var testCode = """ + #region Comment + #endregion Comment + [|using System; + using System.Threading;|] - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace TestNamespace + { + } + """; - /// - /// Verifies that the code fix will properly move regions. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithRegion_RegionMoved() - { - var testCode = """ + var fixedTestCode = """ + namespace TestNamespace + { #region Comment #endregion Comment - [|using System; - using System.Threading;|] - - namespace TestNamespace - { - } - """; - - var fixedTestCode = """ - namespace TestNamespace - { - #region Comment - #endregion Comment - {|Warning:using System;|} - {|Warning:using System.Threading;|} - } - """; - - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + {|Warning:using System;|} + {|Warning:using System.Threading;|} + } + """; - /// - /// Verifies that the code fix will properly move comment trivia. - /// - [Fact] - public Task WhenInsidePreferred_UsingsInCompilationUnitWithCommentTrivia_TriviaMoved() - { - var testCode = """ + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - // Some comment - [|using System; - using System.Threading;|] + /// + /// Verifies that the code fix will properly move comment trivia. + /// + [Fact] + public Task WhenInsidePreferred_UsingsInCompilationUnitWithCommentTrivia_TriviaMoved() + { + var testCode = """ - namespace TestNamespace - { - } - """; + // Some comment + [|using System; + using System.Threading;|] - var fixedTestCode = """ - namespace TestNamespace - { + namespace TestNamespace + { + } + """; - // Some comment - {|Warning:using System;|} - {|Warning:using System.Threading;|} - } - """; + var fixedTestCode = """ + namespace TestNamespace + { - return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + // Some comment + {|Warning:using System;|} + {|Warning:using System.Threading;|} + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61773")] - public Task WhenInsidePreferred_DoNotMoveGlobalUsings1() - { - var testCode = """ - [|global using System;|] + return TestInRegularAndScriptAsync(testCode, fixedTestCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); + } - namespace TestNamespace - { - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61773")] + public Task WhenInsidePreferred_DoNotMoveGlobalUsings1() + { + var testCode = """ + [|global using System;|] - return TestMissingAsync(testCode, InsideNamespaceOption); - } + namespace TestNamespace + { + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61773")] - public Task WhenInsidePreferred_DoNotMoveGlobalUsings2() - { - var testCode = """ - [|global using System; - using System.Threading;|] + return TestMissingAsync(testCode, InsideNamespaceOption); + } - namespace TestNamespace - { - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61773")] + public Task WhenInsidePreferred_DoNotMoveGlobalUsings2() + { + var testCode = """ + [|global using System; + using System.Threading;|] - var fixedCode = """ - global using System; + namespace TestNamespace + { + } + """; - namespace TestNamespace - { - {|Warning:using System.Threading;|} - } - """; + var fixedCode = """ + global using System; - return TestInRegularAndScriptAsync(testCode, fixedCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); - } + namespace TestNamespace + { + {|Warning:using System.Threading;|} + } + """; - #endregion + return TestInRegularAndScriptAsync(testCode, fixedCode, InsideNamespaceOption, placeSystemNamespaceFirst: true); } + + #endregion } diff --git a/src/Analyzers/CSharp/Tests/NamingStyles/NamingStylesTests.cs b/src/Analyzers/CSharp/Tests/NamingStyles/NamingStylesTests.cs index 86ed09ff64280..ee726f9e1485d 100644 --- a/src/Analyzers/CSharp/Tests/NamingStyles/NamingStylesTests.cs +++ b/src/Analyzers/CSharp/Tests/NamingStyles/NamingStylesTests.cs @@ -18,1594 +18,1593 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.NamingStyles +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.NamingStyles; + +[Trait(Traits.Feature, Traits.Features.NamingStyle)] +public class NamingStylesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.NamingStyle)] - public class NamingStylesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor - { - public NamingStylesTests(ITestOutputHelper logger) - : base(logger) - { - } - - private static readonly NamingStylesTestOptionSets s_options = new NamingStylesTestOptionSets(LanguageNames.CSharp); - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpNamingStyleDiagnosticAnalyzer(), new NamingStyleCodeFixProvider()); - - protected override TestComposition GetComposition() - => base.GetComposition().AddParts(typeof(TestSymbolRenamedCodeActionOperationFactoryWorkspaceService)); - - [Fact] - public async Task TestPascalCaseClass_CorrectName() - { - await TestMissingInRegularAndScriptAsync( - """ - class [|C|] - { - } - """, new TestParameters(options: s_options.ClassNamesArePascalCase)); - } - - [Fact] - public async Task TestPascalCaseClass_NameGetsCapitalized() - { - await TestInRegularAndScriptAsync( - """ - class [|c|] - { - } - """, - """ - class C - { - } - """, - options: s_options.ClassNamesArePascalCase); - } - - [Theory] - [InlineData("M_bar", "bar")] - [InlineData("S_bar", "bar")] - [InlineData("T_bar", "bar")] - [InlineData("_Bar", "bar")] - [InlineData("__Bar", "bar")] - [InlineData("M_s__t_Bar", "bar")] - [InlineData("m_bar", "bar")] - [InlineData("s_bar", "bar")] - [InlineData("t_bar", "bar")] - [InlineData("_bar", "bar")] - [InlineData("__bar", "bar")] - [InlineData("m_s__t_Bar", "bar")] - // Special cases to ensure empty identifiers are not produced - [InlineData("M_", "m_")] - [InlineData("M__", "_")] - [InlineData("S_", "s_")] - [InlineData("T_", "t_")] - [InlineData("M_S__T_", "t_")] - public async Task TestCamelCaseField_PrefixGetsStripped(string fieldName, string correctedName) - { - await TestInRegularAndScriptAsync( - $$""" - class C - { - int [|{{fieldName}}|]; - } - """, - $$""" - class C - { - int [|{{correctedName}}|]; - } - """, - options: s_options.FieldNamesAreCamelCase); - } - - [Theory] - [InlineData("M_bar", "_bar")] - [InlineData("S_bar", "_bar")] - [InlineData("T_bar", "_bar")] - [InlineData("_Bar", "_bar")] - [InlineData("__Bar", "_bar")] - [InlineData("M_s__t_Bar", "_bar")] - [InlineData("m_bar", "_bar")] - [InlineData("s_bar", "_bar")] - [InlineData("t_bar", "_bar")] - [InlineData("bar", "_bar")] - [InlineData("__bar", "_bar")] - [InlineData("__s_bar", "_bar")] - [InlineData("m_s__t_Bar", "_bar")] - // Special cases to ensure empty identifiers are not produced - [InlineData("M_", "_m_")] - [InlineData("M__", "_")] - [InlineData("S_", "_s_")] - [InlineData("T_", "_t_")] - [InlineData("M_S__T_", "_t_")] - public async Task TestCamelCaseField_PrefixGetsStrippedBeforeAddition(string fieldName, string correctedName) - { - await TestInRegularAndScriptAsync( - $$""" - class C - { - int [|{{fieldName}}|]; - } - """, - $$""" - class C - { - int [|{{correctedName}}|]; - } - """, - options: s_options.FieldNamesAreCamelCaseWithUnderscorePrefix); - } - - [Fact] - public async Task TestPascalCaseMethod_CorrectName() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void [|M|]() - { - } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } - - [Theory] - [InlineData("")] - [InlineData("public")] - [InlineData("protected")] - [InlineData("internal")] - [InlineData("protected internal")] - [InlineData("private")] - [InlineData("protected private")] - [WorkItem("https://github.com/dotnet/roslyn/issues/20907")] - public async Task TestPascalCaseMethod_NoneAndDefaultAccessibilities(string accessibility) - { - await TestMissingInRegularAndScriptAsync( - $$""" - class C - { - {{accessibility}} void [|m|]() - { - } - } - """, new TestParameters(options: s_options.MethodNamesWithAccessibilityArePascalCase([]))); + public NamingStylesTests(ITestOutputHelper logger) + : base(logger) + { + } - await TestInRegularAndScriptAsync( - $$""" - class C - { - {{accessibility}} void [|m|]() - { - } - } - """, - $$""" - class C - { - {{accessibility}} void M() - { - } - } - """, options: s_options.MethodNamesWithAccessibilityArePascalCase(accessibilities: default)); - } - - [Theory] - [InlineData("} namespace [|c2|] {", "} namespace C2 {")] - [InlineData("class [|c2|] { }", "class C2 { }")] - [InlineData("struct [|c2|] { }", "struct C2 { }")] - [InlineData("interface [|c2|] { }", "interface C2 { }")] - [InlineData("delegate void [|c2|]();", "delegate void C2();")] - [InlineData("enum [|c2|] { }", "enum C2 { }")] - [InlineData("class M<[|t|]> {}", "class M {}")] - [InlineData("void M<[|t|]>() {}", "void M() {}")] - [InlineData("int [|m|] { get; }", "int M { get; }")] - [InlineData("void [|m|]() {}", "void M() {}")] - [InlineData("void Outer() { void [|m|]() {} }", "void Outer() { void M() {} }")] - [InlineData("int [|m|];", "int M;")] - [InlineData("event System.EventHandler [|m|];", "event System.EventHandler M;")] - [InlineData("void Outer(int [|m|]) {}", "void Outer(int M) {}")] - [InlineData("void Outer() { int [|m|]; }", "void Outer() { int M; }")] - [WorkItem("https://github.com/dotnet/roslyn/issues/20907")] - public async Task TestPascalCaseSymbol_NoneAndDefaultSymbolKinds(string camelCaseSymbol, string pascalCaseSymbol) - { - await TestMissingInRegularAndScriptAsync( - $$""" - class C - { - {{camelCaseSymbol}} - } - """, new TestParameters(options: s_options.SymbolKindsArePascalCaseEmpty())); - - await TestInRegularAndScriptAsync( - $$""" - class C - { - {{camelCaseSymbol}} - } - """, - $$""" - class C - { - {{pascalCaseSymbol}} - } - """, options: s_options.SymbolKindsArePascalCase(symbolKinds: default)); - } - - [Theory] - [InlineData("} namespace [|c2|] {", "} namespace C2 {", SymbolKind.Namespace, Accessibility.Public)] - [InlineData("class [|c2|] { }", "class C2 { }", TypeKind.Class, Accessibility.Private)] - [InlineData("struct [|c2|] { }", "struct C2 { }", TypeKind.Struct, Accessibility.Private)] - [InlineData("interface [|c2|] { }", "interface C2 { }", TypeKind.Interface, Accessibility.Private)] - [InlineData("delegate void [|c2|]();", "delegate void C2();", TypeKind.Delegate, Accessibility.Private)] - [InlineData("enum [|c2|] { }", "enum C2 { }", TypeKind.Enum, Accessibility.Private)] - [InlineData("class M<[|t|]> {}", "class M {}", SymbolKind.TypeParameter, Accessibility.Private)] - [InlineData("void M<[|t|]>() {}", "void M() {}", SymbolKind.TypeParameter, Accessibility.Private)] - [InlineData("int [|m|] { get; }", "int M { get; }", SymbolKind.Property, Accessibility.Private)] - [InlineData("void [|m|]() {}", "void M() {}", MethodKind.Ordinary, Accessibility.Private)] - [InlineData("void Outer() { void [|m|]() {} }", "void Outer() { void M() {} }", MethodKind.LocalFunction, Accessibility.NotApplicable)] - [InlineData("int [|m|];", "int M;", SymbolKind.Field, Accessibility.Private)] - [InlineData("event System.EventHandler [|m|];", "event System.EventHandler M;", SymbolKind.Event, Accessibility.Private)] - [InlineData("void Outer(int [|m|]) {}", "void Outer(int M) {}", SymbolKind.Parameter, Accessibility.Private)] - [InlineData("void Outer() { void Inner(int [|m|]) {} }", "void Outer() { void Inner(int M) {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] - [InlineData("void Outer() { System.Action action = [|m|] => {} }", "void Outer() { System.Action action = M => {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] - [InlineData("void Outer() { System.Action action = ([|m|]) => {} }", "void Outer() { System.Action action = (M) => {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] - [InlineData("void Outer() { System.Action action = (int [|m|]) => {} }", "void Outer() { System.Action action = (int M) => {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] - [InlineData("void Outer() { System.Action action = delegate (int [|m|]) {} }", "void Outer() { System.Action action = delegate (int M) {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] - [InlineData("void Outer() { int [|m|]; }", "void Outer() { int M; }", SymbolKind.Local, Accessibility.NotApplicable)] - [WorkItem("https://github.com/dotnet/roslyn/issues/20907")] - public async Task TestPascalCaseSymbol_ExpectedSymbolAndAccessibility(string camelCaseSymbol, string pascalCaseSymbol, object symbolKind, Accessibility accessibility) - { - var alternateSymbolKind = TypeKind.Class.Equals(symbolKind) ? TypeKind.Interface : TypeKind.Class; - var alternateAccessibility = accessibility == Accessibility.Public ? Accessibility.Protected : Accessibility.Public; - - // Verify that no diagnostic is reported if the symbol kind is wrong - await TestMissingInRegularAndScriptAsync( - $$""" - class C - { - {{camelCaseSymbol}} - } - """, new TestParameters(options: s_options.SymbolKindsArePascalCase(alternateSymbolKind))); - - // Verify that no diagnostic is reported if the accessibility is wrong - await TestMissingInRegularAndScriptAsync( - $$""" - class C - { - {{camelCaseSymbol}} - } - """, new TestParameters(options: s_options.AccessibilitiesArePascalCase(ImmutableArray.Create(alternateAccessibility)))); - - await TestInRegularAndScriptAsync( - $$""" - class C - { - {{camelCaseSymbol}} - } - """, - $$""" - class C - { - {{pascalCaseSymbol}} - } - """, options: s_options.AccessibilitiesArePascalCase(ImmutableArray.Create(accessibility))); - } - - [Fact] - public async Task TestPascalCaseMethod_NameGetsCapitalized() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void [|m|]() - { - } - } - """, - """ - class C - { - void M() - { - } - } - """, - options: s_options.MethodNamesArePascalCase); - } + private static readonly NamingStylesTestOptionSets s_options = new NamingStylesTestOptionSets(LanguageNames.CSharp); - [Fact] - public async Task TestPascalCaseMethod_ConstructorsAreIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class c - { - public [|c|]() - { - } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpNamingStyleDiagnosticAnalyzer(), new NamingStyleCodeFixProvider()); - [Fact] - public async Task TestPascalCaseMethod_PropertyAccessorsAreIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - public int P { [|get|]; set; } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + protected override TestComposition GetComposition() + => base.GetComposition().AddParts(typeof(TestSymbolRenamedCodeActionOperationFactoryWorkspaceService)); + + [Fact] + public async Task TestPascalCaseClass_CorrectName() + { + await TestMissingInRegularAndScriptAsync( + """ + class [|C|] + { + } + """, new TestParameters(options: s_options.ClassNamesArePascalCase)); + } - [Fact] - public async Task TestPascalCaseMethod_IndexerNameIsIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestPascalCaseClass_NameGetsCapitalized() + { + await TestInRegularAndScriptAsync( + """ + class [|c|] + { + } + """, + """ + class C + { + } + """, + options: s_options.ClassNamesArePascalCase); + } + + [Theory] + [InlineData("M_bar", "bar")] + [InlineData("S_bar", "bar")] + [InlineData("T_bar", "bar")] + [InlineData("_Bar", "bar")] + [InlineData("__Bar", "bar")] + [InlineData("M_s__t_Bar", "bar")] + [InlineData("m_bar", "bar")] + [InlineData("s_bar", "bar")] + [InlineData("t_bar", "bar")] + [InlineData("_bar", "bar")] + [InlineData("__bar", "bar")] + [InlineData("m_s__t_Bar", "bar")] + // Special cases to ensure empty identifiers are not produced + [InlineData("M_", "m_")] + [InlineData("M__", "_")] + [InlineData("S_", "s_")] + [InlineData("T_", "t_")] + [InlineData("M_S__T_", "t_")] + public async Task TestCamelCaseField_PrefixGetsStripped(string fieldName, string correctedName) + { + await TestInRegularAndScriptAsync( + $$""" + class C + { + int [|{{fieldName}}|]; + } + """, + $$""" + class C + { + int [|{{correctedName}}|]; + } + """, + options: s_options.FieldNamesAreCamelCase); + } + + [Theory] + [InlineData("M_bar", "_bar")] + [InlineData("S_bar", "_bar")] + [InlineData("T_bar", "_bar")] + [InlineData("_Bar", "_bar")] + [InlineData("__Bar", "_bar")] + [InlineData("M_s__t_Bar", "_bar")] + [InlineData("m_bar", "_bar")] + [InlineData("s_bar", "_bar")] + [InlineData("t_bar", "_bar")] + [InlineData("bar", "_bar")] + [InlineData("__bar", "_bar")] + [InlineData("__s_bar", "_bar")] + [InlineData("m_s__t_Bar", "_bar")] + // Special cases to ensure empty identifiers are not produced + [InlineData("M_", "_m_")] + [InlineData("M__", "_")] + [InlineData("S_", "_s_")] + [InlineData("T_", "_t_")] + [InlineData("M_S__T_", "_t_")] + public async Task TestCamelCaseField_PrefixGetsStrippedBeforeAddition(string fieldName, string correctedName) + { + await TestInRegularAndScriptAsync( + $$""" + class C + { + int [|{{fieldName}}|]; + } + """, + $$""" + class C + { + int [|{{correctedName}}|]; + } + """, + options: s_options.FieldNamesAreCamelCaseWithUnderscorePrefix); + } + + [Fact] + public async Task TestPascalCaseMethod_CorrectName() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void [|M|]() { - public int [|this|][int index] - { - get - { - return 1; - } - } } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - [Fact] - public async Task TestPascalCaseMethod_LocalFunctionIsIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData("")] + [InlineData("public")] + [InlineData("protected")] + [InlineData("internal")] + [InlineData("protected internal")] + [InlineData("private")] + [InlineData("protected private")] + [WorkItem("https://github.com/dotnet/roslyn/issues/20907")] + public async Task TestPascalCaseMethod_NoneAndDefaultAccessibilities(string accessibility) + { + await TestMissingInRegularAndScriptAsync( + $$""" + class C + { + {{accessibility}} void [|m|]() { - void M() - { - void [|f|]() - { - } - } } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + } + """, new TestParameters(options: s_options.MethodNamesWithAccessibilityArePascalCase([]))); - [Fact] - public async Task TestCamelCaseParameters() - { - await TestInRegularAndScriptAsync( - """ - class C + await TestInRegularAndScriptAsync( + $$""" + class C + { + {{accessibility}} void [|m|]() { - public void M(int [|X|]) - { - } } - """, - """ - class C + } + """, + $$""" + class C + { + {{accessibility}} void M() { - public void M(int x) - { - } } - """, - options: s_options.ParameterNamesAreCamelCase); - } + } + """, options: s_options.MethodNamesWithAccessibilityArePascalCase(accessibilities: default)); + } + + [Theory] + [InlineData("} namespace [|c2|] {", "} namespace C2 {")] + [InlineData("class [|c2|] { }", "class C2 { }")] + [InlineData("struct [|c2|] { }", "struct C2 { }")] + [InlineData("interface [|c2|] { }", "interface C2 { }")] + [InlineData("delegate void [|c2|]();", "delegate void C2();")] + [InlineData("enum [|c2|] { }", "enum C2 { }")] + [InlineData("class M<[|t|]> {}", "class M {}")] + [InlineData("void M<[|t|]>() {}", "void M() {}")] + [InlineData("int [|m|] { get; }", "int M { get; }")] + [InlineData("void [|m|]() {}", "void M() {}")] + [InlineData("void Outer() { void [|m|]() {} }", "void Outer() { void M() {} }")] + [InlineData("int [|m|];", "int M;")] + [InlineData("event System.EventHandler [|m|];", "event System.EventHandler M;")] + [InlineData("void Outer(int [|m|]) {}", "void Outer(int M) {}")] + [InlineData("void Outer() { int [|m|]; }", "void Outer() { int M; }")] + [WorkItem("https://github.com/dotnet/roslyn/issues/20907")] + public async Task TestPascalCaseSymbol_NoneAndDefaultSymbolKinds(string camelCaseSymbol, string pascalCaseSymbol) + { + await TestMissingInRegularAndScriptAsync( + $$""" + class C + { + {{camelCaseSymbol}} + } + """, new TestParameters(options: s_options.SymbolKindsArePascalCaseEmpty())); + + await TestInRegularAndScriptAsync( + $$""" + class C + { + {{camelCaseSymbol}} + } + """, + $$""" + class C + { + {{pascalCaseSymbol}} + } + """, options: s_options.SymbolKindsArePascalCase(symbolKinds: default)); + } - [Fact] - public async Task TestCamelCaseLocals_LocalDeclaration1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData("} namespace [|c2|] {", "} namespace C2 {", SymbolKind.Namespace, Accessibility.Public)] + [InlineData("class [|c2|] { }", "class C2 { }", TypeKind.Class, Accessibility.Private)] + [InlineData("struct [|c2|] { }", "struct C2 { }", TypeKind.Struct, Accessibility.Private)] + [InlineData("interface [|c2|] { }", "interface C2 { }", TypeKind.Interface, Accessibility.Private)] + [InlineData("delegate void [|c2|]();", "delegate void C2();", TypeKind.Delegate, Accessibility.Private)] + [InlineData("enum [|c2|] { }", "enum C2 { }", TypeKind.Enum, Accessibility.Private)] + [InlineData("class M<[|t|]> {}", "class M {}", SymbolKind.TypeParameter, Accessibility.Private)] + [InlineData("void M<[|t|]>() {}", "void M() {}", SymbolKind.TypeParameter, Accessibility.Private)] + [InlineData("int [|m|] { get; }", "int M { get; }", SymbolKind.Property, Accessibility.Private)] + [InlineData("void [|m|]() {}", "void M() {}", MethodKind.Ordinary, Accessibility.Private)] + [InlineData("void Outer() { void [|m|]() {} }", "void Outer() { void M() {} }", MethodKind.LocalFunction, Accessibility.NotApplicable)] + [InlineData("int [|m|];", "int M;", SymbolKind.Field, Accessibility.Private)] + [InlineData("event System.EventHandler [|m|];", "event System.EventHandler M;", SymbolKind.Event, Accessibility.Private)] + [InlineData("void Outer(int [|m|]) {}", "void Outer(int M) {}", SymbolKind.Parameter, Accessibility.Private)] + [InlineData("void Outer() { void Inner(int [|m|]) {} }", "void Outer() { void Inner(int M) {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] + [InlineData("void Outer() { System.Action action = [|m|] => {} }", "void Outer() { System.Action action = M => {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] + [InlineData("void Outer() { System.Action action = ([|m|]) => {} }", "void Outer() { System.Action action = (M) => {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] + [InlineData("void Outer() { System.Action action = (int [|m|]) => {} }", "void Outer() { System.Action action = (int M) => {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] + [InlineData("void Outer() { System.Action action = delegate (int [|m|]) {} }", "void Outer() { System.Action action = delegate (int M) {} }", SymbolKind.Parameter, Accessibility.NotApplicable)] + [InlineData("void Outer() { int [|m|]; }", "void Outer() { int M; }", SymbolKind.Local, Accessibility.NotApplicable)] + [WorkItem("https://github.com/dotnet/roslyn/issues/20907")] + public async Task TestPascalCaseSymbol_ExpectedSymbolAndAccessibility(string camelCaseSymbol, string pascalCaseSymbol, object symbolKind, Accessibility accessibility) + { + var alternateSymbolKind = TypeKind.Class.Equals(symbolKind) ? TypeKind.Interface : TypeKind.Class; + var alternateAccessibility = accessibility == Accessibility.Public ? Accessibility.Protected : Accessibility.Public; + + // Verify that no diagnostic is reported if the symbol kind is wrong + await TestMissingInRegularAndScriptAsync( + $$""" + class C + { + {{camelCaseSymbol}} + } + """, new TestParameters(options: s_options.SymbolKindsArePascalCase(alternateSymbolKind))); + + // Verify that no diagnostic is reported if the accessibility is wrong + await TestMissingInRegularAndScriptAsync( + $$""" + class C + { + {{camelCaseSymbol}} + } + """, new TestParameters(options: s_options.AccessibilitiesArePascalCase(ImmutableArray.Create(alternateAccessibility)))); + + await TestInRegularAndScriptAsync( + $$""" + class C + { + {{camelCaseSymbol}} + } + """, + $$""" + class C + { + {{pascalCaseSymbol}} + } + """, options: s_options.AccessibilitiesArePascalCase(ImmutableArray.Create(accessibility))); + } + + [Fact] + public async Task TestPascalCaseMethod_NameGetsCapitalized() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void [|m|]() { - void M() - { - int [|X|]; - } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x; - } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.MethodNamesArePascalCase); + } - [Fact] - public async Task TestCamelCaseLocals_LocalDeclaration2() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int X, [|Y|] = 0; - } - } - """, - """ - class C + [Fact] + public async Task TestPascalCaseMethod_ConstructorsAreIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class c + { + public [|c|]() { - void M() - { - int X, y = 0; - } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } + + [Fact] + public async Task TestPascalCaseMethod_PropertyAccessorsAreIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int P { [|get|]; set; } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - [Fact] - public async Task TestCamelCaseLocals_UsingVariable1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestPascalCaseMethod_IndexerNameIsIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int [|this|][int index] { - void M() + get { - using (object [|A|] = null) - { - } + return 1; } } - """, - """ - class C + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } + + [Fact] + public async Task TestPascalCaseMethod_LocalFunctionIsIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + void [|f|]() { - using (object a = null) - { - } } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - [Fact] - public async Task TestCamelCaseLocals_UsingVariable2() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseParameters() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public void M(int [|X|]) { - void M() - { - using (object A = null, [|B|] = null) - { - } - } } - """, - """ - class C + } + """, + """ + class C + { + public void M(int x) { - void M() - { - using (object A = null, b = null) - { - } - } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.ParameterNamesAreCamelCase); + } + + [Fact] + public async Task TestCamelCaseLocals_LocalDeclaration1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int [|X|]; + } + } + """, + """ + class C + { + void M() + { + int x; + } + } + """, + options: s_options.LocalNamesAreCamelCase); + } + + [Fact] + public async Task TestCamelCaseLocals_LocalDeclaration2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int X, [|Y|] = 0; + } + } + """, + """ + class C + { + void M() + { + int X, y = 0; + } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_ForVariable1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_UsingVariable1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + using (object [|A|] = null) { - for (int [|I|] = 0, J = 0; I < J; ++I) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + using (object a = null) { - for (int i = 0, J = 0; i < J; ++i) - { - } } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_ForVariable2() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_UsingVariable2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + using (object A = null, [|B|] = null) { - for (int I = 0, [|J|] = 0; I < J; ++J) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + using (object A = null, b = null) { - for (int I = 0, j = 0; I < j; ++j) - { - } } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_ForEachVariable() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_ForVariable1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + for (int [|I|] = 0, J = 0; I < J; ++I) { - foreach (var [|X|] in new string[] { }) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + for (int i = 0, J = 0; i < J; ++i) { - foreach (var x in new string[] { }) - { - } } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_CatchVariable() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact] + public async Task TestCamelCaseLocals_ForVariable2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + for (int I = 0, [|J|] = 0; I < J; ++J) { - try - { - } - catch (Exception [|Exception|]) - { - } } } - """, - """ - using System; - class C + } + """, + """ + class C + { + void M() { - void M() + for (int I = 0, j = 0; I < j; ++j) { - try - { - } - catch (Exception exception) - { - } } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_CatchWithoutVariableIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - class C + [Fact] + public async Task TestCamelCaseLocals_ForEachVariable() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + foreach (var [|X|] in new string[] { }) { - try - { - } - catch ([|Exception|]) - { - } } } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } - - [Fact] - public async Task TestCamelCaseLocals_CatchWithoutDeclarationIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - class C + } + """, + """ + class C + { + void M() { - void M() + foreach (var x in new string[] { }) { - try - { - } - [|catch|] - { - } } } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_Deconstruction1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_CatchVariable() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + void M() { - void M() + try { - (int A, (string [|B|], var C)) = (0, (string.Empty, string.Empty)); - System.Console.WriteLine(A + B + C); } - } - """, - """ - class C - { - void M() + catch (Exception [|Exception|]) { - (int A, (string b, var C)) = (0, (string.Empty, string.Empty)); - System.Console.WriteLine(A + b + C); } } - """, - options: s_options.LocalNamesAreCamelCase); - } - - [Fact] - public async Task TestCamelCaseLocals_Deconstruction2() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """, + """ + using System; + class C + { + void M() { - void M() + try { - var (A, (B, [|C|])) = (0, (string.Empty, string.Empty)); - System.Console.WriteLine(A + B + C); } - } - """, - """ - class C - { - void M() + catch (Exception exception) { - var (A, (B, [|c|])) = (0, (string.Empty, string.Empty)); - System.Console.WriteLine(A + B + c); } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_ForEachDeconstruction1() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_CatchWithoutVariableIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + class C + { + void M() { - void M() + try { - foreach ((int A, (string [|B|], var C)) in new[] { (0, (string.Empty, string.Empty)) }) - System.Console.WriteLine(A + B + C); } - } - """, - """ - class C - { - void M() + catch ([|Exception|]) { - foreach ((int A, (string b, var C)) in new[] { (0, (string.Empty, string.Empty)) }) - System.Console.WriteLine(A + b + C); } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact] - public async Task TestCamelCaseLocals_ForEachDeconstruction2() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_CatchWithoutDeclarationIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + class C + { + void M() { - void M() + try { - foreach (var (A, (B, [|C|])) in new[] { (0, (string.Empty, string.Empty)) }) - System.Console.WriteLine(A + B + C); } - } - """, - """ - class C - { - void M() + [|catch|] { - foreach (var (A, (B, c)) in new[] { (0, (string.Empty, string.Empty)) }) - System.Console.WriteLine(A + B + c); } } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } + + [Fact] + public async Task TestCamelCaseLocals_Deconstruction1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + (int A, (string [|B|], var C)) = (0, (string.Empty, string.Empty)); + System.Console.WriteLine(A + B + C); + } + } + """, + """ + class C + { + void M() + { + (int A, (string b, var C)) = (0, (string.Empty, string.Empty)); + System.Console.WriteLine(A + b + C); + } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_OutVariable() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_Deconstruction2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + var (A, (B, [|C|])) = (0, (string.Empty, string.Empty)); + System.Console.WriteLine(A + B + C); + } + } + """, + """ + class C + { + void M() + { + var (A, (B, [|c|])) = (0, (string.Empty, string.Empty)); + System.Console.WriteLine(A + B + c); + } + } + """, + options: s_options.LocalNamesAreCamelCase); + } + + [Fact] + public async Task TestCamelCaseLocals_ForEachDeconstruction1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - if (int.TryParse(string.Empty, out var [|Value|])) - System.Console.WriteLine(Value); - } + foreach ((int A, (string [|B|], var C)) in new[] { (0, (string.Empty, string.Empty)) }) + System.Console.WriteLine(A + B + C); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - if (int.TryParse(string.Empty, out var value)) - System.Console.WriteLine(value); - } + foreach ((int A, (string b, var C)) in new[] { (0, (string.Empty, string.Empty)) }) + System.Console.WriteLine(A + b + C); } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_PatternVariable() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_ForEachDeconstruction2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - if (new object() is int [|Value|]) - System.Console.WriteLine(Value); - } + foreach (var (A, (B, [|C|])) in new[] { (0, (string.Empty, string.Empty)) }) + System.Console.WriteLine(A + B + C); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - if (new object() is int value) - System.Console.WriteLine(value); - } + foreach (var (A, (B, c)) in new[] { (0, (string.Empty, string.Empty)) }) + System.Console.WriteLine(A + B + c); } - """, - options: s_options.LocalNamesAreCamelCase); - } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_QueryFromClauseIgnored() - { - // This is an IRangeVariableSymbol, not ILocalSymbol - await TestMissingInRegularAndScriptAsync( - """ - using System.Linq; + [Fact] + public async Task TestCamelCaseLocals_OutVariable() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + if (int.TryParse(string.Empty, out var [|Value|])) + System.Console.WriteLine(Value); + } + } + """, + """ + class C + { + void M() + { + if (int.TryParse(string.Empty, out var value)) + System.Console.WriteLine(value); + } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - class C - { - void M() - { - var squares = - from [|STRING|] in new string[] { } - let Number = int.Parse(STRING) - select Number * Number; - } - } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + [Fact] + public async Task TestCamelCaseLocals_PatternVariable() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + if (new object() is int [|Value|]) + System.Console.WriteLine(Value); + } + } + """, + """ + class C + { + void M() + { + if (new object() is int value) + System.Console.WriteLine(value); + } + } + """, + options: s_options.LocalNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocals_QueryLetClauseIgnored() - { - // This is an IRangeVariableSymbol, not ILocalSymbol - await TestMissingInRegularAndScriptAsync( - """ - using System.Linq; + [Fact] + public async Task TestCamelCaseLocals_QueryFromClauseIgnored() + { + // This is an IRangeVariableSymbol, not ILocalSymbol + await TestMissingInRegularAndScriptAsync( + """ + using System.Linq; + + class C + { + void M() + { + var squares = + from [|STRING|] in new string[] { } + let Number = int.Parse(STRING) + select Number * Number; + } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - class C - { - void M() - { - var squares = - from STRING in new string[] { } - let [|Number|] = int.Parse(STRING) - select Number * Number; - } - } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + [Fact] + public async Task TestCamelCaseLocals_QueryLetClauseIgnored() + { + // This is an IRangeVariableSymbol, not ILocalSymbol + await TestMissingInRegularAndScriptAsync( + """ + using System.Linq; + + class C + { + void M() + { + var squares = + from STRING in new string[] { } + let [|Number|] = int.Parse(STRING) + select Number * Number; + } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact] - public async Task TestCamelCaseLocals_ParameterIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_ParameterIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(int [|X|]) { - void M(int [|X|]) - { - } } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact] - public async Task TestCamelCaseLocals_TupleTypeElementNameIgnored1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_TupleTypeElementNameIgnored1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - (int [|A|], string B) tuple; - } + (int [|A|], string B) tuple; } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact] - public async Task TestCamelCaseLocals_TupleTypeElementNameIgnored2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_TupleTypeElementNameIgnored2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - (int A, (string [|B|], string C)) tuple = (0, (string.Empty, string.Empty)); - } + (int A, (string [|B|], string C)) tuple = (0, (string.Empty, string.Empty)); } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact] - public async Task TestCamelCaseLocals_TupleExpressionElementNameIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocals_TupleExpressionElementNameIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - var tuple = ([|A|]: 0, B: 0); - } + var tuple = ([|A|]: 0, B: 0); } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact] - public async Task TestUpperCaseConstants_ConstField() - { - await TestInRegularAndScriptAsync( - """ - class C - { - const int [|field|] = 0; - } - """, - """ - class C - { - const int FIELD = 0; - } - """, - options: s_options.ConstantsAreUpperCase); - } + [Fact] + public async Task TestUpperCaseConstants_ConstField() + { + await TestInRegularAndScriptAsync( + """ + class C + { + const int [|field|] = 0; + } + """, + """ + class C + { + const int FIELD = 0; + } + """, + options: s_options.ConstantsAreUpperCase); + } - [Fact] - public async Task TestUpperCaseConstants_ConstLocal() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - const int local1 = 0, [|local2|] = 0; - } - } - """, - """ - class C - { - void M() - { - const int local1 = 0, LOCAL2 = 0; - } - } - """, - options: s_options.ConstantsAreUpperCase); - } + [Fact] + public async Task TestUpperCaseConstants_ConstLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + const int local1 = 0, [|local2|] = 0; + } + } + """, + """ + class C + { + void M() + { + const int local1 = 0, LOCAL2 = 0; + } + } + """, + options: s_options.ConstantsAreUpperCase); + } - [Fact] - public async Task TestUpperCaseConstants_NonConstFieldIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - readonly int [|field|] = 0; - } - """, new TestParameters(options: s_options.ConstantsAreUpperCase)); - } + [Fact] + public async Task TestUpperCaseConstants_NonConstFieldIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + readonly int [|field|] = 0; + } + """, new TestParameters(options: s_options.ConstantsAreUpperCase)); + } - [Fact] - public async Task TestUpperCaseConstants_NonConstLocalIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestUpperCaseConstants_NonConstLocalIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - int local1 = 0, [|local2|] = 0; - } + int local1 = 0, [|local2|] = 0; } - """, new TestParameters(options: s_options.ConstantsAreUpperCase)); - } + } + """, new TestParameters(options: s_options.ConstantsAreUpperCase)); + } - [Fact] - public async Task TestCamelCaseLocalsUpperCaseConstants_ConstLocal() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - const int [|PascalCase|] = 0; - } - } - """, - """ - class C - { - void M() - { - const int PASCALCASE = 0; - } - } - """, - options: s_options.LocalsAreCamelCaseConstantsAreUpperCase); - } + [Fact] + public async Task TestCamelCaseLocalsUpperCaseConstants_ConstLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + const int [|PascalCase|] = 0; + } + } + """, + """ + class C + { + void M() + { + const int PASCALCASE = 0; + } + } + """, + options: s_options.LocalsAreCamelCaseConstantsAreUpperCase); + } - [Fact] - public async Task TestCamelCaseLocalsUpperCaseConstants_NonConstLocal() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int [|PascalCase|] = 0; - } - } - """, - """ - class C - { - void M() - { - int pascalCase = 0; - } - } - """, - options: s_options.LocalsAreCamelCaseConstantsAreUpperCase); - } + [Fact] + public async Task TestCamelCaseLocalsUpperCaseConstants_NonConstLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int [|PascalCase|] = 0; + } + } + """, + """ + class C + { + void M() + { + int pascalCase = 0; + } + } + """, + options: s_options.LocalsAreCamelCaseConstantsAreUpperCase); + } - [Fact] - public async Task TestCamelCaseLocalFunctions() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocalFunctions() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + void [|F|]() { - void [|F|]() - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + void f() { - void f() - { - } } } - """, - options: s_options.LocalFunctionNamesAreCamelCase); - } + } + """, + options: s_options.LocalFunctionNamesAreCamelCase); + } - [Fact] - public async Task TestCamelCaseLocalFunctions_MethodIsIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestCamelCaseLocalFunctions_MethodIsIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void [|M|]() { - void [|M|]() - { - } } - """, new TestParameters(options: s_options.LocalFunctionNamesAreCamelCase)); - } + } + """, new TestParameters(options: s_options.LocalFunctionNamesAreCamelCase)); + } - [Fact] - public async Task TestAsyncFunctions_AsyncMethod() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestAsyncFunctions_AsyncMethod() + { + await TestInRegularAndScriptAsync( + """ + class C + { + async void [|M|]() { - async void [|M|]() - { - } } - """, - """ - class C + } + """, + """ + class C + { + async void MAsync() { - async void MAsync() - { - } } - """, - options: s_options.AsyncFunctionNamesEndWithAsync); - } + } + """, + options: s_options.AsyncFunctionNamesEndWithAsync); + } - [Fact] - public async Task TestAsyncFunctions_AsyncLocalFunction() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestAsyncFunctions_AsyncLocalFunction() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + async void [|F|]() { - async void [|F|]() - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + async void FAsync() { - async void FAsync() - { - } } } - """, - options: s_options.AsyncFunctionNamesEndWithAsync); - } + } + """, + options: s_options.AsyncFunctionNamesEndWithAsync); + } - [Fact] - public async Task TestAsyncFunctions_NonAsyncMethodIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestAsyncFunctions_NonAsyncMethodIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void [|M|]() { - void [|M|]() + async void F() { - async void F() - { - } } } - """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); - } + } + """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); + } - [Fact] - public async Task TestAsyncFunctions_NonAsyncLocalFunctionIgnored() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestAsyncFunctions_NonAsyncLocalFunctionIgnored() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + async void M() { - async void M() + void [|F|]() { - void [|F|]() - { - } } } - """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); - } - - [Fact] - public async Task TestPascalCaseMethod_InInterfaceWithImplicitImplementation() - { - await TestInRegularAndScriptAsync( - """ - interface I - { - void [|m|](); - } - - class C : I - { - public void m() { } - } - """, - """ - interface I - { - void M(); - } - - class C : I - { - public void M() { } - } - """, - options: s_options.MethodNamesArePascalCase); - } - - [Fact] - public async Task TestPascalCaseMethod_InInterfaceWithExplicitImplementation() - { - await TestInRegularAndScriptAsync( - """ - interface I - { - void [|m|](); - } - - class C : I - { - void I.m() { } - } - """, - """ - interface I - { - void M(); - } - - class C : I - { - void I.M() { } - } - """, - options: s_options.MethodNamesArePascalCase); - } - - [Fact] - public async Task TestPascalCaseMethod_NotInImplicitInterfaceImplementation() - { - await TestMissingInRegularAndScriptAsync( - """ - interface I - { - void m(); - } - - class C : I - { - public void [|m|]() { } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } - - [Fact] - public async Task TestPascalCaseMethod_NotInExplicitInterfaceImplementation() - { - await TestMissingInRegularAndScriptAsync( - """ - interface I - { - void m(); - } - - class C : I - { - void I.[|m|]() { } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } - - [Fact] - public async Task TestPascalCaseMethod_InAbstractType() - { - await TestInRegularAndScriptAsync( - """ - abstract class C - { - public abstract void [|m|](); - } - - class D : C - { - public override void m() { } - } - """, - """ - abstract class C - { - public abstract void M(); - } - - class D : C - { - public override void M() { } - } - """, - options: s_options.MethodNamesArePascalCase); - } + } + """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); + } - [Fact] - public async Task TestPascalCaseMethod_NotInAbstractMethodImplementation() - { - await TestMissingInRegularAndScriptAsync( - """ - abstract class C - { - public abstract void m(); - } + [Fact] + public async Task TestPascalCaseMethod_InInterfaceWithImplicitImplementation() + { + await TestInRegularAndScriptAsync( + """ + interface I + { + void [|m|](); + } + + class C : I + { + public void m() { } + } + """, + """ + interface I + { + void M(); + } + + class C : I + { + public void M() { } + } + """, + options: s_options.MethodNamesArePascalCase); + } - class D : C - { - public override void [|m|]() { } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + [Fact] + public async Task TestPascalCaseMethod_InInterfaceWithExplicitImplementation() + { + await TestInRegularAndScriptAsync( + """ + interface I + { + void [|m|](); + } + + class C : I + { + void I.m() { } + } + """, + """ + interface I + { + void M(); + } + + class C : I + { + void I.M() { } + } + """, + options: s_options.MethodNamesArePascalCase); + } - [Fact] - public async Task TestPascalCaseProperty_InInterface() - { - await TestInRegularAndScriptAsync( - """ - interface I - { - int [|p|] { get; set; } - } + [Fact] + public async Task TestPascalCaseMethod_NotInImplicitInterfaceImplementation() + { + await TestMissingInRegularAndScriptAsync( + """ + interface I + { + void m(); + } + + class C : I + { + public void [|m|]() { } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - class C : I - { - public int p { get { return 1; } set { } } - } - """, - """ - interface I - { - int P { get; set; } - } + [Fact] + public async Task TestPascalCaseMethod_NotInExplicitInterfaceImplementation() + { + await TestMissingInRegularAndScriptAsync( + """ + interface I + { + void m(); + } + + class C : I + { + void I.[|m|]() { } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - class C : I - { - public int P { get { return 1; } set { } } - } - """, - options: s_options.PropertyNamesArePascalCase); - } + [Fact] + public async Task TestPascalCaseMethod_InAbstractType() + { + await TestInRegularAndScriptAsync( + """ + abstract class C + { + public abstract void [|m|](); + } + + class D : C + { + public override void m() { } + } + """, + """ + abstract class C + { + public abstract void M(); + } + + class D : C + { + public override void M() { } + } + """, + options: s_options.MethodNamesArePascalCase); + } - [Fact] - public async Task TestPascalCaseProperty_NotInImplicitInterfaceImplementation() - { - await TestMissingInRegularAndScriptAsync( - """ - interface I - { - int p { get; set; } - } + [Fact] + public async Task TestPascalCaseMethod_NotInAbstractMethodImplementation() + { + await TestMissingInRegularAndScriptAsync( + """ + abstract class C + { + public abstract void m(); + } + + class D : C + { + public override void [|m|]() { } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - class C : I - { - public int [|p|] { get { return 1; } set { } } - } - """, new TestParameters(options: s_options.PropertyNamesArePascalCase)); - } + [Fact] + public async Task TestPascalCaseProperty_InInterface() + { + await TestInRegularAndScriptAsync( + """ + interface I + { + int [|p|] { get; set; } + } + + class C : I + { + public int p { get { return 1; } set { } } + } + """, + """ + interface I + { + int P { get; set; } + } + + class C : I + { + public int P { get { return 1; } set { } } + } + """, + options: s_options.PropertyNamesArePascalCase); + } - [Fact] - public async Task TestPascalCaseMethod_OverrideInternalMethod() - { - await TestMissingInRegularAndScriptAsync( - """ - abstract class C - { - internal abstract void m(); - } + [Fact] + public async Task TestPascalCaseProperty_NotInImplicitInterfaceImplementation() + { + await TestMissingInRegularAndScriptAsync( + """ + interface I + { + int p { get; set; } + } + + class C : I + { + public int [|p|] { get { return 1; } set { } } + } + """, new TestParameters(options: s_options.PropertyNamesArePascalCase)); + } - class D : C - { - internal override void [|m|]() { } - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + [Fact] + public async Task TestPascalCaseMethod_OverrideInternalMethod() + { + await TestMissingInRegularAndScriptAsync( + """ + abstract class C + { + internal abstract void m(); + } + + class D : C + { + internal override void [|m|]() { } + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19106")] - public async Task TestMissingOnSymbolsWithNoName() - { - await TestMissingInRegularAndScriptAsync( - """ - namespace Microsoft.CodeAnalysis.Host - { - internal interface - [|}|] - """, new TestParameters(options: s_options.InterfaceNamesStartWithI)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19106")] + public async Task TestMissingOnSymbolsWithNoName() + { + await TestMissingInRegularAndScriptAsync( + """ + namespace Microsoft.CodeAnalysis.Host + { + internal interface + [|}|] + """, new TestParameters(options: s_options.InterfaceNamesStartWithI)); + } #if CODE_STYLE - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/42218")] + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/42218")] #else - [Fact] + [Fact] #endif - [WorkItem("https://github.com/dotnet/roslyn/issues/16562")] - public async Task TestRefactorNotify() - { - var markup = @"public class [|c|] { }"; - var testParameters = new TestParameters(options: s_options.ClassNamesArePascalCase); + [WorkItem("https://github.com/dotnet/roslyn/issues/16562")] + public async Task TestRefactorNotify() + { + var markup = @"public class [|c|] { }"; + var testParameters = new TestParameters(options: s_options.ClassNamesArePascalCase); - using var workspace = CreateWorkspaceFromOptions(markup, testParameters); - var (_, action) = await GetCodeActionsAsync(workspace, testParameters); + using var workspace = CreateWorkspaceFromOptions(markup, testParameters); + var (_, action) = await GetCodeActionsAsync(workspace, testParameters); - var previewOperations = await action.GetPreviewOperationsAsync(CancellationToken.None); - Assert.Empty(previewOperations.OfType()); + var previewOperations = await action.GetPreviewOperationsAsync(CancellationToken.None); + Assert.Empty(previewOperations.OfType()); - var commitOperations = await action.GetOperationsAsync(CancellationToken.None); - Assert.Equal(2, commitOperations.Length); + var commitOperations = await action.GetOperationsAsync(CancellationToken.None); + Assert.Equal(2, commitOperations.Length); - var symbolRenamedOperation = (TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.Operation)commitOperations[1]; - Assert.Equal("c", symbolRenamedOperation._symbol.Name); - Assert.Equal("C", symbolRenamedOperation._newName); - } + var symbolRenamedOperation = (TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.Operation)commitOperations[1]; + Assert.Equal("c", symbolRenamedOperation._symbol.Name); + Assert.Equal("C", symbolRenamedOperation._newName); + } #if CODE_STYLE - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/42218")] + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/42218")] #else - [Fact] + [Fact] #endif - [WorkItem("https://github.com/dotnet/roslyn/issues/38513")] - public async Task TestRefactorNotifyInterfaceNamesStartWithI() - { - var markup = @"public interface [|test|] { }"; - var testParameters = new TestParameters(options: s_options.InterfaceNamesStartWithI); + [WorkItem("https://github.com/dotnet/roslyn/issues/38513")] + public async Task TestRefactorNotifyInterfaceNamesStartWithI() + { + var markup = @"public interface [|test|] { }"; + var testParameters = new TestParameters(options: s_options.InterfaceNamesStartWithI); - using var workspace = CreateWorkspaceFromOptions(markup, testParameters); - var (_, action) = await GetCodeActionsAsync(workspace, testParameters); + using var workspace = CreateWorkspaceFromOptions(markup, testParameters); + var (_, action) = await GetCodeActionsAsync(workspace, testParameters); - var previewOperations = await action.GetPreviewOperationsAsync(CancellationToken.None); - Assert.Empty(previewOperations.OfType()); + var previewOperations = await action.GetPreviewOperationsAsync(CancellationToken.None); + Assert.Empty(previewOperations.OfType()); - var commitOperations = await action.GetOperationsAsync(CancellationToken.None); - Assert.Equal(2, commitOperations.Length); + var commitOperations = await action.GetOperationsAsync(CancellationToken.None); + Assert.Equal(2, commitOperations.Length); - var symbolRenamedOperation = (TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.Operation)commitOperations[1]; - Assert.Equal("test", symbolRenamedOperation._symbol.Name); - Assert.Equal("ITest", symbolRenamedOperation._newName); - } + var symbolRenamedOperation = (TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.Operation)commitOperations[1]; + Assert.Equal("test", symbolRenamedOperation._symbol.Name); + Assert.Equal("ITest", symbolRenamedOperation._newName); + } #if CODE_STYLE - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/42218")] + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/42218")] #else - [Fact] + [Fact] #endif - [WorkItem("https://github.com/dotnet/roslyn/issues/38513")] - public async Task TestRefactorNotifyTypeParameterNamesStartWithT() - { - var markup = """ - public class A - { - void DoOtherThing<[|arg|]>() { } - } - """; - var testParameters = new TestParameters(options: s_options.TypeParameterNamesStartWithT); - - using var workspace = CreateWorkspaceFromOptions(markup, testParameters); - var (_, action) = await GetCodeActionsAsync(workspace, testParameters); - - var previewOperations = await action.GetPreviewOperationsAsync(CancellationToken.None); - Assert.Empty(previewOperations.OfType()); - - var commitOperations = await action.GetOperationsAsync(CancellationToken.None); - Assert.Equal(2, commitOperations.Length); - - var symbolRenamedOperation = (TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.Operation)commitOperations[1]; - Assert.Equal("arg", symbolRenamedOperation._symbol.Name); - Assert.Equal("TArg", symbolRenamedOperation._newName); - } + [WorkItem("https://github.com/dotnet/roslyn/issues/38513")] + public async Task TestRefactorNotifyTypeParameterNamesStartWithT() + { + var markup = """ + public class A + { + void DoOtherThing<[|arg|]>() { } + } + """; + var testParameters = new TestParameters(options: s_options.TypeParameterNamesStartWithT); + + using var workspace = CreateWorkspaceFromOptions(markup, testParameters); + var (_, action) = await GetCodeActionsAsync(workspace, testParameters); + + var previewOperations = await action.GetPreviewOperationsAsync(CancellationToken.None); + Assert.Empty(previewOperations.OfType()); + + var commitOperations = await action.GetOperationsAsync(CancellationToken.None); + Assert.Equal(2, commitOperations.Length); + + var symbolRenamedOperation = (TestSymbolRenamedCodeActionOperationFactoryWorkspaceService.Operation)commitOperations[1]; + Assert.Equal("arg", symbolRenamedOperation._symbol.Name); + Assert.Equal("TArg", symbolRenamedOperation._newName); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47508")] - public async Task TestRecordParameter_NoDiagnosticWhenCorrect() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47508")] + public async Task TestRecordParameter_NoDiagnosticWhenCorrect() + { + await TestMissingInRegularAndScriptAsync( @"record Foo(int [|MyInt|]);", - new TestParameters(options: s_options.MergeStyles(s_options.PropertyNamesArePascalCase, s_options.ParameterNamesAreCamelCaseWithPUnderscorePrefix))); - } + new TestParameters(options: s_options.MergeStyles(s_options.PropertyNamesArePascalCase, s_options.ParameterNamesAreCamelCaseWithPUnderscorePrefix))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47508")] - public async Task TestRecordConstructorParameter_NoDiagnosticWhenCorrect() - { - await TestMissingInRegularAndScriptAsync( - """ - record Foo(int MyInt) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47508")] + public async Task TestRecordConstructorParameter_NoDiagnosticWhenCorrect() + { + await TestMissingInRegularAndScriptAsync( + """ + record Foo(int MyInt) + { + public Foo(string [|p_myString|]) : this(1) { - public Foo(string [|p_myString|]) : this(1) - { - } } - """, - new TestParameters(options: s_options.MergeStyles(s_options.PropertyNamesArePascalCase, s_options.ParameterNamesAreCamelCaseWithPUnderscorePrefix))); - } + } + """, + new TestParameters(options: s_options.MergeStyles(s_options.PropertyNamesArePascalCase, s_options.ParameterNamesAreCamelCaseWithPUnderscorePrefix))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47508")] - public async Task TestRecordParameter_ParameterFormattedAsProperties() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47508")] + public async Task TestRecordParameter_ParameterFormattedAsProperties() + { + await TestInRegularAndScriptAsync( @"public record Foo(int [|myInt|]);", @"public record Foo(int [|MyInt|]);", - options: s_options.MergeStyles(s_options.PropertyNamesArePascalCase, s_options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); - } - - [Theory] - [InlineData("_")] - [InlineData("_1")] - [InlineData("_123")] - [InlineData("__")] - [InlineData("___")] - public async Task TestDiscardParameterAsync(string identifier) - { - await TestMissingInRegularAndScriptAsync( - $$""" - class C - { - void M(int [|{{identifier}}|]) - { - } - } - """, new TestParameters(options: s_options.ParameterNamesAreCamelCase)); - } - - [Theory] - [InlineData("_")] - [InlineData("_1")] - [InlineData("_123")] - [InlineData("__")] - [InlineData("___")] - public async Task TestDiscardLocalAsync(string identifier) - { - await TestMissingInRegularAndScriptAsync( - $$""" - class C - { - void M() - { - int [|{{identifier}}|] = 0; - } - } - """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); - } + options: s_options.MergeStyles(s_options.PropertyNamesArePascalCase, s_options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49535")] - public async Task TestGlobalDirectiveAsync() - { - await TestMissingInRegularAndScriptAsync( - """ - interface I + [Theory] + [InlineData("_")] + [InlineData("_1")] + [InlineData("_123")] + [InlineData("__")] + [InlineData("___")] + public async Task TestDiscardParameterAsync(string identifier) + { + await TestMissingInRegularAndScriptAsync( + $$""" + class C + { + void M(int [|{{identifier}}|]) { - int X { get; } } + } + """, new TestParameters(options: s_options.ParameterNamesAreCamelCase)); + } - class C : I + [Theory] + [InlineData("_")] + [InlineData("_1")] + [InlineData("_123")] + [InlineData("__")] + [InlineData("___")] + public async Task TestDiscardLocalAsync(string identifier) + { + await TestMissingInRegularAndScriptAsync( + $$""" + class C + { + void M() { - int [|global::I.X|] => 0; + int [|{{identifier}}|] = 0; } - """, new TestParameters(options: s_options.PropertyNamesArePascalCase)); - } + } + """, new TestParameters(options: s_options.LocalNamesAreCamelCase)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50734")] - public async Task TestAsyncEntryPoint() - { - await TestMissingInRegularAndScriptAsync(""" - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49535")] + public async Task TestGlobalDirectiveAsync() + { + await TestMissingInRegularAndScriptAsync( + """ + interface I + { + int X { get; } + } + + class C : I + { + int [|global::I.X|] => 0; + } + """, new TestParameters(options: s_options.PropertyNamesArePascalCase)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50734")] + public async Task TestAsyncEntryPoint() + { + await TestMissingInRegularAndScriptAsync(""" + using System.Threading.Tasks; - class C + class C + { + static async Task [|Main|]() { - static async Task [|Main|]() - { - await Task.Delay(0); - } + await Task.Delay(0); } - """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); - } + } + """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49648")] - public async Task TestAsyncEntryPoint_TopLevel() - { - await TestMissingInRegularAndScriptAsync(""" - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49648")] + public async Task TestAsyncEntryPoint_TopLevel() + { + await TestMissingInRegularAndScriptAsync(""" + using System.Threading.Tasks; - [|await Task.Delay(0);|] - """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); - } + [|await Task.Delay(0);|] + """, new TestParameters(options: s_options.AsyncFunctionNamesEndWithAsync)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51727")] - public async Task TestExternAsync() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - static extern void [|some_p_invoke()|]; - } - """, new TestParameters(options: s_options.MethodNamesArePascalCase)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/51727")] + public async Task TestExternAsync() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + static extern void [|some_p_invoke()|]; + } + """, new TestParameters(options: s_options.MethodNamesArePascalCase)); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementTests.cs b/src/Analyzers/CSharp/Tests/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementTests.cs index 5a1e469013d22..46710ac1f8dbe 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/ArrowExpressionClausePlacement/ArrowExpressionClausePlacementTests.cs @@ -11,616 +11,615 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ArrowExpressionClausePlacement -{ - using Verify = CSharpCodeFixVerifier< - ArrowExpressionClausePlacementDiagnosticAnalyzer, - ArrowExpressionClausePlacementCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ArrowExpressionClausePlacement; + +using Verify = CSharpCodeFixVerifier< + ArrowExpressionClausePlacementDiagnosticAnalyzer, + ArrowExpressionClausePlacementCodeFixProvider>; - public class ArrowExpressionClausePlacementTests +public class ArrowExpressionClausePlacementTests +{ + [Fact] + public async Task TestNotWithOptionOff() { - [Fact] - public async Task TestNotWithOptionOff() + var code = + """ + class C + { + public int Add() => + 1 + 2; + } + """; + + await new Verify.Test { - var code = - """ - class C - { - public int Add() => - 1 + 2; - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithSingleLineMethod() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public int Add() => 1 + 2; + } + """; - [Fact] - public async Task TestNotWithSingleLineMethod() + await new Verify.Test { - var code = - """ - class C - { - public int Add() => 1 + 2; - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithSingleLineProperty() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public int Add => 1 + 2; + } + """; - [Fact] - public async Task TestNotWithSingleLineProperty() + await new Verify.Test { - var code = - """ - class C - { - public int Add => 1 + 2; - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithSingleLineLocalFunction() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public void Main() + { + int Add() => 1 + 2; + } + } + """; - [Fact] - public async Task TestNotWithSingleLineLocalFunction() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithLambda() + { + var code = + """ + class C + { + public void Main() { - public void Main() - { - int Add() => 1 + 2; - } + Goo(() => + 1 + 2); } - """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public void Goo(System.Func action) { } + } + """; - [Fact] - public async Task TestNotWithLambda() + await new Verify.Test { - var code = - """ - class C - { - public void Main() - { - Goo(() => - 1 + 2); - } - - public void Goo(System.Func action) { } - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestMethodCase() + { + var code = + """ + class C + { + public int Add() [|=>|] + 1 + 2; + } + """; + + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public int Add() + => 1 + 2; + } + """; - [Fact] - public async Task TestMethodCase() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotPropertyAccessor1() + { + var code = + """ + class C + { + public int Add { - public int Add() [|=>|] + get => 1 + 2; } - """; + } + """; - var fixedCode = - """ - class C - { - public int Add() - => 1 + 2; - } - """; + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestProperty() + { + var code = + """ + class C + { + public int Add [|=>|] + 1 + 2; + } + """; + + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add + => 1 + 2; + } + """; - [Fact] - public async Task TestNotPropertyAccessor1() + await new Verify.Test { - var code = - """ - class C - { - public int Add - { - get => - 1 + 2; - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestLocalFunction() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestProperty() - { - var code = - """ - class C + void Main() { - public int Add [|=>|] + int Add() [|=>|] 1 + 2; } - """; + } + """; - var fixedCode = - """ - class C + var fixedCode = + """ + class C + { + void Main() { - public int Add + int Add() => 1 + 2; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestLocalFunction() + await new Verify.Test { - var code = - """ - class C - { - void Main() - { - int Add() [|=>|] - 1 + 2; - } - } - """; - - var fixedCode = - """ - class C - { - void Main() - { - int Add() - => 1 + 2; - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithDiagnosticsInDeclaration() + { + var code = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add(int{|CS1001:)|} => + 1 + 2; + } + """; - [Fact] - public async Task TestNotWithDiagnosticsInDeclaration() + await new Verify.Test { - var code = - """ - class C - { - public int Add(int{|CS1001:)|} => - 1 + 2; - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithDiagnosticsInExpression() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public int Add() => + 1 + {|CS1525:;|} + } + """; - [Fact] - public async Task TestNotWithDiagnosticsInExpression() + await new Verify.Test { - var code = - """ - class C - { - public int Add() => - 1 + {|CS1525:;|} - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithDiagnosticsAtEnd() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public int Add() => + 1 + 2{|CS1002:|} + } + """; - [Fact] - public async Task TestNotWithDiagnosticsAtEnd() + await new Verify.Test { - var code = - """ - class C - { - public int Add() => - 1 + 2{|CS1002:|} - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia1() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia1() + public int Add() => + #if true + 1 + 2; + #endif + } + """; + + await new Verify.Test { - var code = - """ - class C - { - public int Add() => - #if true - 1 + 2; - #endif - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia2() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia2() + #if true + public int Add() => + #endif + 1 + 2; + } + """; + + await new Verify.Test { - var code = - """ - class C - { - #if true - public int Add() => - #endif - 1 + 2; - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestWithRegion1() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestWithRegion1() + public int Add() [|=>|] + #region section + 1 + 2; + #endregion + } + """; + + var fixedCode = + """ + class C + { + public int Add() + #region section + => 1 + 2; + #endregion + } + """; + + await new Verify.Test { - var code = - """ - class C - { - public int Add() [|=>|] - #region section - 1 + 2; - #endregion - } - """; - - var fixedCode = - """ - class C - { - public int Add() - #region section - => 1 + 2; - #endregion - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestWithRegion2() + { + var code = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestWithRegion2() + #region section + public int Add() [|=>|] + #endregion + 1 + 2; + } + """; + + var fixedCode = + """ + class C + { + #region section + public int Add() + #endregion + => 1 + 2; + } + """; + + await new Verify.Test { - var code = - """ - class C - { - #region section - public int Add() [|=>|] - #endregion - 1 + 2; - } - """; - - var fixedCode = - """ - class C - { - #region section - public int Add() - #endregion - => 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestWithNullableDirective1() + { + var code = + """ + class C + { + public int Add() [|=>|] + #nullable enable + 1 + 2; + } + """; + + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() + #nullable enable + => 1 + 2; + } + """; - [Fact] - public async Task TestWithNullableDirective1() + await new Verify.Test { - var code = - """ - class C - { - public int Add() [|=>|] - #nullable enable - 1 + 2; - } - """; - - var fixedCode = - """ - class C - { - public int Add() - #nullable enable - => 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestTrivia1() + { + var code = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() [|=>|] + 1 + 2; + } + """; + + var fixedCode = + """ + class C + { + public int Add() + => 1 + 2; + } + """; - [Fact] - public async Task TestTrivia1() + await new Verify.Test { - var code = - """ - class C - { - public int Add() [|=>|] - 1 + 2; - } - """; - - var fixedCode = - """ - class C - { - public int Add() - => 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestTrivia2() + { + var code = + """ + class C + { + public int Add() [|=>|] // comment + 1 + 2; + } + """; + + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() // comment + => 1 + 2; + } + """; - [Fact] - public async Task TestTrivia2() + await new Verify.Test { - var code = - """ - class C - { - public int Add() [|=>|] // comment - 1 + 2; - } - """; - - var fixedCode = - """ - class C - { - public int Add() // comment - => 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestTrivia3() + { + var code = + """ + class C + { + public int Add() /* comment */ [|=>|] + 1 + 2; + } + """; + + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() /* comment */ + => 1 + 2; + } + """; - [Fact] - public async Task TestTrivia3() + await new Verify.Test { - var code = - """ - class C - { - public int Add() /* comment */ [|=>|] - 1 + 2; - } - """; - - var fixedCode = - """ - class C - { - public int Add() /* comment */ - => 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestTrivia4() + { + var code = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() /* comment */ [|=>|] + 1 + 2; + } + """; + + var fixedCode = + """ + class C + { + public int Add() /* comment */ + => 1 + 2; + } + """; - [Fact] - public async Task TestTrivia4() + await new Verify.Test { - var code = - """ - class C - { - public int Add() /* comment */ [|=>|] - 1 + 2; - } - """; - - var fixedCode = - """ - class C - { - public int Add() /* comment */ - => 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestTrivia5() + { + var code = + """ + class C + { + public int Add() /* comment1 */ [|=>|] /* comment2 */ + 1 + 2; + } + """; + + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() /* comment1 */ /* comment2 */ + => 1 + 2; + } + """; - [Fact] - public async Task TestTrivia5() + await new Verify.Test { - var code = - """ - class C - { - public int Add() /* comment1 */ [|=>|] /* comment2 */ - 1 + 2; - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestWithDiagnosticsElsewhere() + { + var code = + """ + class C + { + public C(int{|CS1001:)|} { - public int Add() /* comment1 */ /* comment2 */ - => 1 + 2; } - """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public int Add() [|=>|] + 1 + 2; + } + """; - [Fact] - public async Task TestWithDiagnosticsElsewhere() - { - var code = - """ - class C + var fixedCode = + """ + class C + { + public C(int{|CS1001:)|} { - public C(int{|CS1001:)|} - { - } - - public int Add() [|=>|] - 1 + 2; } - """; - - var fixedCode = - """ - class C - { - public C(int{|CS1001:)|} - { - } - public int Add() - => 1 + 2; - } - """; + public int Add() + => 1 + 2; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInArrowExpressionClause, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/ConditionalExpressionPlacement/ConditionalExpressionPlacementTests.cs b/src/Analyzers/CSharp/Tests/NewLines/ConditionalExpressionPlacement/ConditionalExpressionPlacementTests.cs index 4979bcb12a413..b4e535b6ca768 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/ConditionalExpressionPlacement/ConditionalExpressionPlacementTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/ConditionalExpressionPlacement/ConditionalExpressionPlacementTests.cs @@ -10,845 +10,844 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConditionalExpressionPlacement -{ - using Verify = CSharpCodeFixVerifier< - ConditionalExpressionPlacementDiagnosticAnalyzer, - ConditionalExpressionPlacementCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConditionalExpressionPlacement; + +using Verify = CSharpCodeFixVerifier< + ConditionalExpressionPlacementDiagnosticAnalyzer, + ConditionalExpressionPlacementCodeFixProvider>; - public class ConditionalExpressionPlacementTests +public class ConditionalExpressionPlacementTests +{ + [Fact] + public async Task TestNotWithOptionOff() { - [Fact] - public async Task TestNotWithOptionOff() - { - var code = - """ - class C + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 0 : - 1; - } + var v = true ? + 0 : + 1; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestBaseCase() + await new Verify.Test { - var code = - """ - class C - { - public C() - { - var v = true [|?|] - 0 : - 1; - } - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestBaseCase() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true - ? 0 - : 1; - } + var v = true [|?|] + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithDiagnosticsInCondition() - { - var code = - """ - class C + public C() { - public C() - { - var v = true || {|CS1525:?|} - 0: - 1; - } + var v = true + ? 0 + : 1; } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotWithDiagnosticsInTrue() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithDiagnosticsInCondition() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 0 + {|CS1525::|} - 1; - } + var v = true || {|CS1525:?|} + 0: + 1; } - """; + } + """; - await new Verify.Test + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithDiagnosticsInTrue() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true ? + 0 + {|CS1525::|} + 1; + } + } + """; - [Fact] - public async Task TestNotWithDiagnosticsInFalse() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithDiagnosticsInFalse() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 0 : - 1 +{|CS1525:;|} - } + var v = true ? + 0 : + 1 +{|CS1525:;|} } - """; + } + """; - await new Verify.Test + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithMissingColon() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true ? + 0{|CS1003:{|CS1525:;|}|} + } + } + """; - [Fact] - public async Task TestNotWithMissingColon() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithQuestionNotAtEndOfLine() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 0{|CS1003:{|CS1525:;|}|} - } + var v = true ? 1 : + 1; } - """; + } + """; + + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithColonNotAtEndOfLine() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true ? + 1 : 1; + } + } + """; - [Fact] - public async Task TestNotWithQuestionNotAtEndOfLine() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia1() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? 1 : - 1; - } + var v = true ? + #if true + 1 : + 1; + #endif } - """; + } + """; + + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia2() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true ? + 1 : + #if true + 1; + #endif + } + } + """; - [Fact] - public async Task TestNotWithColonNotAtEndOfLine() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia3() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 1 : 1; - } + #if true + var v = true ? + #endif + 1 : + 1; } - """; + } + """; + + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia4() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + #if true + var v = true ? + 1 : + #endif + 1; + } + } + """; - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia1() + await new Verify.Test { - var code = - """ - class C - { - public C() - { - var v = true ? - #if true - 1 : - 1; - #endif - } - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotWithFirstExprWithPPTrivia5() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true ? + 1 : + #if true + 1; + #endif + } + } + """; - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia2() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithRegion1() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 1 : - #if true - 1; - #endif - } + var v = true [|?|] + #region true section + 0 : + #endregion + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true + #region true section + ? 0 + #endregion + : 1; + } + } + """; - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia3() + await new Verify.Test { - var code = - """ - class C - { - public C() - { - #if true - var v = true ? - #endif - 1 : - 1; - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestWithRegion2() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia4() - { - var code = - """ - class C - { - public C() - { - #if true - var v = true ? - 1 : - #endif - 1; - } + public C() + { + var v = true [|?|] + 0 : + #region true section + 1; + #endregion } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true + ? 0 + #region true section + : 1; + #endregion + } + } + """; - [Fact] - public async Task TestNotWithFirstExprWithPPTrivia5() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithNullableDirective1() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true ? - 1 : - #if true - 1; - #endif - } + var v = true [|?|] + #nullable enable + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true + #nullable enable + ? 0 + : 1; + } + } + """; - [Fact] - public async Task TestWithRegion1() + await new Verify.Test { - var code = - """ - class C - { - public C() - { - var v = true [|?|] - #region true section - 0 : - #endregion - 1; - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestWithNullableDirective2() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true - #region true section - ? 0 - #endregion - : 1; - } + var v = true [|?|] + 0 : + #nullable enable + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true + ? 0 + #nullable enable + : 1; + } + } + """; - [Fact] - public async Task TestWithRegion2() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNested1() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true [|?|] + var v = true [|?|] + true [|?|] 0 : - #region true section - 1; - #endregion - } + 1 : + 2; } - """; + } + """; - var fixedCode = - """ - class C + var fixedCode = + """ + class C + { + public C() { - public C() - { - var v = true + var v = true + ? true ? 0 - #region true section - : 1; - #endregion - } + : 1 + : 2; } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestWithNullableDirective1() + await new Verify.Test { - var code = - """ - class C - { - public C() - { - var v = true [|?|] - #nullable enable - 0 : - 1; - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestNested2() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true - #nullable enable - ? 0 - : 1; - } + var v = true [|?|] + true ? + 0 : 1 : + 2; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true + ? true ? + 0 : 1 + : 2; + } + } + """; - [Fact] - public async Task TestWithNullableDirective2() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNested3() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true [|?|] + var v = true ? + true [|?|] 0 : - #nullable enable - 1; - } + 1 : 2; } - """; + } + """; - var fixedCode = - """ - class C + var fixedCode = + """ + class C + { + public C() { - public C() - { - var v = true + var v = true ? + true ? 0 - #nullable enable - : 1; - } + : 1 : 2; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNested1() - { - var code = - """ - class C - { - public C() - { - var v = true [|?|] - true [|?|] - 0 : - 1 : - 2; - } - } - """; - - var fixedCode = - """ - class C - { - public C() - { - var v = true - ? true - ? 0 - : 1 - : 2; - } - } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNested2() - { - var code = - """ - class C - { - public C() - { - var v = true [|?|] - true ? - 0 : 1 : - 2; - } - } - """; - - var fixedCode = - """ - class C - { - public C() - { - var v = true - ? true ? - 0 : 1 - : 2; - } - } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNested3() + await new Verify.Test { - var code = - """ - class C - { - public C() - { - var v = true ? - true [|?|] - 0 : - 1 : 2; - } - } - """; - - var fixedCode = - """ - class C - { - public C() - { - var v = true ? - true - ? 0 - : 1 : 2; - } - } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTrivia1() - { - var code = - """ - class C - { - public C() - { - var v = true [|?|] - 0 : - 1; - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestTrivia1() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true - ? 0 - : 1; - } + var v = true [|?|] + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTrivia2() - { - var code = - """ - class C + public C() { - public C() - { - var v = true [|?|] // comment - 0 : - 1; - } + var v = true + ? 0 + : 1; } - """; + } + """; + + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestTrivia2() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true // comment - ? 0 - : 1; - } + var v = true [|?|] // comment + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTrivia3() - { - var code = - """ - class C + public C() { - public C() - { - var v = true /*comment*/ [|?|] - 0 : - 1; - } + var v = true // comment + ? 0 + : 1; } - """; + } + """; - var fixedCode = - """ - class C + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTrivia3() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true /*comment*/ - ? 0 - : 1; - } + var v = true /*comment*/ [|?|] + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTrivia4() - { - var code = - """ - class C + public C() { - public C() - { - var v = true /*comment*/ [|?|] - 0 : - 1; - } + var v = true /*comment*/ + ? 0 + : 1; } - """; + } + """; + + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestTrivia4() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true /*comment*/ - ? 0 - : 1; - } + var v = true /*comment*/ [|?|] + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTrivia5() - { - var code = - """ - class C + public C() { - public C() - { - var v = true /*comment1*/ [|?|] /*comment2*/ - 0 : - 1; - } + var v = true /*comment*/ + ? 0 + : 1; } - """; + } + """; - var fixedCode = - """ - class C + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTrivia5() + { + var code = + """ + class C + { + public C() { - public C() - { - var v = true /*comment1*/ /*comment2*/ - ? 0 - : 1; - } + var v = true /*comment1*/ [|?|] /*comment2*/ + 0 : + 1; } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public C() + { + var v = true /*comment1*/ /*comment2*/ + ? 0 + : 1; + } + } + """; - [Fact] - public async Task TestWithDiagnosticsElsewhere() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithDiagnosticsElsewhere() + { + var code = + """ + class C + { + public C(int{|CS1001:)|} { - public C(int{|CS1001:)|} - { - var v = true [|?|] - 0 : - 1; - } + var v = true [|?|] + 0 : + 1; } - """; + } + """; - var fixedCode = - """ - class C + var fixedCode = + """ + class C + { + public C(int{|CS1001:)|} { - public C(int{|CS1001:)|} - { - var v = true - ? 0 - : 1; - } + var v = true + ? 0 + : 1; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterTokenInConditionalExpression, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveBracePlacement/ConsecutiveBracePlacementTests.cs b/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveBracePlacement/ConsecutiveBracePlacementTests.cs index 5470ebeedddb3..0fffe3768cf00 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveBracePlacement/ConsecutiveBracePlacementTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveBracePlacement/ConsecutiveBracePlacementTests.cs @@ -9,210 +9,285 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConsecutiveBracePlacement +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConsecutiveBracePlacement; + +using VerifyCS = CSharpCodeFixVerifier< + ConsecutiveBracePlacementDiagnosticAnalyzer, + ConsecutiveBracePlacementCodeFixProvider>; + +public class ConsecutiveBracePlacementTests { - using VerifyCS = CSharpCodeFixVerifier< - ConsecutiveBracePlacementDiagnosticAnalyzer, - ConsecutiveBracePlacementCodeFixProvider>; + [Fact] + public async Task NotForBracesOnSameLineDirectlyTouching() + { + var code = +@"class C { void M() { }}"; - public class ConsecutiveBracePlacementTests + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesOnSameLineWithSpace() { - [Fact] - public async Task NotForBracesOnSameLineDirectlyTouching() + var code = +@"class C { void M() { } }"; + + await new VerifyCS.Test { - var code = -@"class C { void M() { }}"; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + [Fact] + public async Task NotForBracesOnSameLineWithComment() + { + var code = +@"class C { void M() { }/*goo*/}"; - [Fact] - public async Task NotForBracesOnSameLineWithSpace() + await new VerifyCS.Test { - var code = -@"class C { void M() { } }"; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task NotForBracesOnSameLineWithCommentAndSpaces() + { + var code = +@"class C { void M() { } /*goo*/ }"; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesOnSubsequentLines_TopLevel() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } + } + """; - [Fact] - public async Task NotForBracesOnSameLineWithComment() + await new VerifyCS.Test { - var code = -@"class C { void M() { }/*goo*/}"; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task NotForBracesOnSubsequentLinesWithComment1_TopLevel() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } // comment + } + """; - [Fact] - public async Task NotForBracesOnSameLineWithCommentAndSpaces() + await new VerifyCS.Test { - var code = -@"class C { void M() { } /*goo*/ }"; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task NotForBracesOnSubsequentLinesWithComment2_TopLevel() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } /* comment */ + } + """; - [Fact] - public async Task NotForBracesOnSubsequentLines_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesOnSubsequentLinesIndented() + { + var code = + """ + namespace N + { class C { void M() { } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task NotForBracesOnSubsequentLinesWithComment1_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesOnSubsequentLinesIndentedWithComment1() + { + var code = + """ + namespace N + { class C { void M() { } // comment } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task NotForBracesOnSubsequentLinesWithComment2_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesOnSubsequentLinesIndentedWithComment2() + { + var code = + """ + namespace N + { class C { void M() { } /* comment */ } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task NotForBracesOnSubsequentLinesIndented() + await new VerifyCS.Test { - var code = - """ - namespace N + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesWithBlankLinesIfCommentBetween1_TopLevel() + { + var code = + """ + class C + { + void M() { - class C - { - void M() - { - } - } } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + // comment + + } + """; - [Fact] - public async Task NotForBracesOnSubsequentLinesIndentedWithComment1() + await new VerifyCS.Test { - var code = - """ - namespace N + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesWithBlankLinesIfCommentBetween2_TopLevel() + { + var code = + """ + class C + { + void M() { - class C - { - void M() - { - } // comment - } } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + /* comment */ + + } + """; - [Fact] - public async Task NotForBracesOnSubsequentLinesIndentedWithComment2() + await new VerifyCS.Test { - var code = - """ - namespace N + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesWithBlankLinesIfDirectiveBetween1_TopLeve() + { + var code = + """ + class C + { + void M() { - class C - { - void M() - { - } /* comment */ - } } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + #nullable enable + + } + """; - [Fact] - public async Task NotForBracesWithBlankLinesIfCommentBetween1_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesWithBlankLinesIfCommentBetween1_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -222,21 +297,24 @@ void M() // comment } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task NotForBracesWithBlankLinesIfCommentBetween2_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesWithBlankLinesIfCommentBetween2_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -246,21 +324,24 @@ void M() /* comment */ } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task NotForBracesWithBlankLinesIfDirectiveBetween1_TopLeve() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NotForBracesWithBlankLinesIfDirectiveBetween_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -270,104 +351,209 @@ void M() #nullable enable } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task OneBlankLineBetweenBraces_TopLevel() + { + var code = + """ + class C + { + void M() + { + } + + [|}|] + """; + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } + } + """; - [Fact] - public async Task NotForBracesWithBlankLinesIfCommentBetween1_Nested() + await new VerifyCS.Test { - var code = - """ - namespace N + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task OneBlankLineBetweenBraces_TopLevel_OptionDisabled() + { + var code = + """ + class C + { + void M() { - class C - { - void M() - { - } + } - // comment + } + """; - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.TrueWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TwoBlankLinesBetweenBraces_TopLevel() + { + var code = + """ + class C + { + void M() + { } - """; - await new VerifyCS.Test + + [|}|] + """; + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } + } + """; - [Fact] - public async Task NotForBracesWithBlankLinesIfCommentBetween2_Nested() + await new VerifyCS.Test { - var code = - """ - namespace N + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task ThreeBlankLinesBetweenBraces_TopLevel() + { + var code = + """ + class C + { + void M() { - class C - { - void M() - { - } + } - /* comment */ - } - } - """; - await new VerifyCS.Test + [|}|] + """; + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } + } + """; - [Fact] - public async Task NotForBracesWithBlankLinesIfDirectiveBetween_Nested() + await new VerifyCS.Test { - var code = - """ - namespace N + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task BlankLinesBetweenBraces_LeadingComment_TopLevel() + { + var code = + """ + class C + { + void M() { - class C - { - void M() - { - } + } - #nullable enable - } + + /*comment*/[|}|] + """; + var fixedCode = + """ + class C + { + void M() + { } - """; + /*comment*/} + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task BlankLinesBetweenBraces_TrailingComment_TopLevel() + { + var code = + """ + class C + { + void M() + { + } /*comment*/ + - await new VerifyCS.Test + + [|}|] + """; + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + } /*comment*/ + } + """; - [Fact] - public async Task OneBlankLineBetweenBraces_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task OneBlankLineBetweenBraces_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -375,52 +561,36 @@ void M() } [|}|] - """; - var fixedCode = - """ + } + """; + var fixedCode = + """ + namespace N + { class C { void M() { } } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task OneBlankLineBetweenBraces_TopLevel_OptionDisabled() + await new VerifyCS.Test { - var code = - """ - class C - { - void M() - { - } - - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TwoBlankLinesBetweenBraces_Nested() + { + var code = + """ + namespace N { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.TrueWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TwoBlankLinesBetweenBraces_TopLevel() - { - var code = - """ class C { void M() @@ -429,30 +599,36 @@ void M() [|}|] - """; - var fixedCode = - """ + } + """; + var fixedCode = + """ + namespace N + { class C { void M() { } } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task ThreeBlankLinesBetweenBraces_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task ThreeBlankLinesBetweenBraces_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -462,30 +638,36 @@ void M() [|}|] - """; - var fixedCode = - """ + } + """; + var fixedCode = + """ + namespace N + { class C { void M() { } } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task BlankLinesBetweenBraces_LeadingComment_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task BlankLinesBetweenBraces_LeadingComment_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -495,30 +677,36 @@ void M() /*comment*/[|}|] - """; - var fixedCode = - """ + } + """; + var fixedCode = + """ + namespace N + { class C { void M() { } /*comment*/} - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task BlankLinesBetweenBraces_TrailingComment_TopLevel() + await new VerifyCS.Test { - var code = - """ + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task BlankLinesBetweenBraces_TrailingComment_Nested() + { + var code = + """ + namespace N + { class C { void M() @@ -528,346 +716,157 @@ void M() [|}|] - """; - var fixedCode = - """ + } + """; + var fixedCode = + """ + namespace N + { class C { void M() { } /*comment*/ } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task OneBlankLineBetweenBraces_Nested() + await new VerifyCS.Test { - var code = - """ - namespace N - { - class C - { - void M() - { - } - - [|}|] - } - """; - var fixedCode = - """ - namespace N - { - class C - { - void M() - { - } - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task FixAll1() + { + var code = + """ + namespace N { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TwoBlankLinesBetweenBraces_Nested() - { - var code = - """ - namespace N - { - class C - { - void M() - { - } - - - [|}|] - } - """; - var fixedCode = - """ - namespace N + class C { - class C + void M() { - void M() - { - } } - } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task ThreeBlankLinesBetweenBraces_Nested() - { - var code = - """ - namespace N - { - class C - { - void M() - { - } - - - - [|}|] - } - """; - var fixedCode = - """ - namespace N - { - class C - { - void M() - { - } - } - } - """; + [|}|] - await new VerifyCS.Test + [|}|] + """; + var fixedCode = + """ + namespace N { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task BlankLinesBetweenBraces_LeadingComment_Nested() - { - var code = - """ - namespace N - { - class C - { - void M() - { - } - - - - /*comment*/[|}|] - } - """; - var fixedCode = - """ - namespace N + class C { - class C + void M() { - void M() - { - } - /*comment*/} + } } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task BlankLinesBetweenBraces_TrailingComment_Nested() + await new VerifyCS.Test { - var code = - """ - namespace N - { - class C - { - void M() - { - } /*comment*/ + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + [Fact] + public async Task RealCode1() + { + var code = + """ + #nullable enable + using System; - [|}|] - } - """; - var fixedCode = - """ - namespace N - { - class C - { - void M() - { - } /*comment*/ - } - } - """; + #if CODE_STYLE + using System.Collections.Generic; + #endif - await new VerifyCS.Test + namespace Microsoft.CodeAnalysis.Options { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + internal interface IOption { } - [Fact] - public async Task FixAll1() - { - var code = - """ - namespace N + internal interface IOption2 + #if !CODE_STYLE + : IOption + #endif { - class C - { - void M() - { - } + string OptionDefinition { get; } - [|}|] + #if CODE_STYLE + string Feature { get; } + string Name { get; } + Type Type { get; } + object? DefaultValue { get; } + bool IsPerLanguage { get; } - [|}|] - """; - var fixedCode = - """ - namespace N - { - class C - { - void M() - { - } - } + List StorageLocations { get; } + #endif } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task RealCode1() + await new VerifyCS.Test { - var code = - """ - #nullable enable - - using System; - - #if CODE_STYLE - using System.Collections.Generic; - #endif + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - namespace Microsoft.CodeAnalysis.Options - { - internal interface IOption { } + [Fact] + public async Task RealCode2() + { + var code = + """ + #define CODE_STYLE + #nullable enable - internal interface IOption2 - #if !CODE_STYLE - : IOption - #endif - { - string OptionDefinition { get; } + using System; - #if CODE_STYLE - string Feature { get; } - string Name { get; } - Type Type { get; } - object? DefaultValue { get; } - bool IsPerLanguage { get; } + #if CODE_STYLE + using System.Collections.Generic; + #endif - List StorageLocations { get; } - #endif - } - } - """; - - await new VerifyCS.Test + namespace Microsoft.CodeAnalysis.Options { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + internal interface IOption { } - [Fact] - public async Task RealCode2() - { - var code = - """ - #define CODE_STYLE - #nullable enable - - using System; - - #if CODE_STYLE - using System.Collections.Generic; - #endif - - namespace Microsoft.CodeAnalysis.Options + internal interface IOption2 + #if !CODE_STYLE + : IOption + #endif { - internal interface IOption { } - - internal interface IOption2 - #if !CODE_STYLE - : IOption - #endif - { - string OptionDefinition { get; } + string OptionDefinition { get; } - #if CODE_STYLE - string Feature { get; } - string Name { get; } - Type Type { get; } - object? DefaultValue { get; } - bool IsPerLanguage { get; } + #if CODE_STYLE + string Feature { get; } + string Name { get; } + Type Type { get; } + object? DefaultValue { get; } + bool IsPerLanguage { get; } - List StorageLocations { get; } - #endif - } + List StorageLocations { get; } + #endif } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CSharpCodeStyleOptions.AllowBlankLinesBetweenConsecutiveBraces, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementTests.cs b/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementTests.cs index 3b5f1559c5673..8b7a4122d28b4 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/ConsecutiveStatementPlacement/ConsecutiveStatementPlacementTests.cs @@ -9,1130 +9,1129 @@ using Microsoft.CodeAnalysis.NewLines.ConsecutiveStatementPlacement; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConsecutiveStatementPlacement -{ - using Verify = CSharpCodeFixVerifier< - CSharpConsecutiveStatementPlacementDiagnosticAnalyzer, - ConsecutiveStatementPlacementCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConsecutiveStatementPlacement; + +using Verify = CSharpCodeFixVerifier< + CSharpConsecutiveStatementPlacementDiagnosticAnalyzer, + ConsecutiveStatementPlacementCodeFixProvider>; - public class ConsecutiveStatementPlacementTests +public class ConsecutiveStatementPlacementTests +{ + [Fact] + public async Task TestNotAfterPropertyBlock() { - [Fact] - public async Task TestNotAfterPropertyBlock() + var code = + """ + class C + { + int X { get; } + int Y { get; } + } + """; + + await new Verify.Test { - var code = - """ - class C - { - int X { get; } - int Y { get; } - } - """; + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotAfterMethodBlock() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void X() { } + void Y() { } + } + """; - [Fact] - public async Task TestNotAfterMethodBlock() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsOnSingleLine() + { + var code = + """ + class C + { + void M() { - void X() { } - void Y() { } + if (true) { } return; } - """; + } + """; - await new Verify.Test + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsOnSingleLineWithComment() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + if (true) { }/*x*/return; + } + } + """; - [Fact] - public async Task TestNotAfterStatementsOnSingleLine() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsOnMultipleLinesWithCommentBetween1() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) { } return; } + /*x*/ return; } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotAfterStatementsOnSingleLineWithComment() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsOnMultipleLinesWithCommentBetween2() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) { }/*x*/return; } + /*x*/ return; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotAfterStatementsOnMultipleLinesWithCommentBetween1() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsWithSingleBlankLines() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) - { - } - /*x*/ return; } - } - """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + return; + } + } + """; - [Fact] - public async Task TestNotAfterStatementsOnMultipleLinesWithCommentBetween2() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsWithSingleBlankLinesWithSpaces() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) - { - } - /*x*/ return; } - } - """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + return; + } + } + """; - [Fact] - public async Task TestNotAfterStatementsWithSingleBlankLines() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsWithMultipleBlankLines() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) - { - } - - return; } - } - """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + return; + } + } + """; - [Fact] - public async Task TestNotAfterStatementsWithSingleBlankLinesWithSpaces() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotAfterStatementsOnMultipleLinesWithPPDirectiveBetween1() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) - { - } - - return; } + #pragma warning disable CS0001 + return; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotAfterStatementsWithMultipleBlankLines() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotBetweenBlockAndElseClause() + { + var code = + """ + class C + { + void M() { - void M() + if (true) + { + } + else { - if (true) - { - } - - return; } } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotAfterStatementsOnMultipleLinesWithPPDirectiveBetween1() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotBetweenBlockAndOuterBlocker() + { + var code = + """ + class C + { + void M() { - void M() + if (true) { - if (true) { } - #pragma warning disable CS0001 - return; } } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotBetweenBlockAndElseClause() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotBetweenBlockAndCase() + { + var code = + """ + class C + { + void M() { - void M() + switch (0) { - if (true) - { - } - else + case 0: { + break; } + case 1: + break; } } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestNotBetweenBlockAndOuterBlocker() + [Fact] + public async Task TestBetweenBlockAndStatement1() + { + await new Verify.Test { - var code = - """ - class C + TestCode = """ + class C + { + void M() { - void M() + if (true) + { + [|}|] + return; + } + } + """, + FixedCode = """ + class C + { + void M() + { + if (true) { - if (true) - { - { - } - } } + + return; } - """; + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotBetweenBlockAndStatement1_WhenOptionOff() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotBetweenBlockAndCase() - { - var code = - """ - class C + void M() { - void M() + if (true) { - switch (0) - { - case 0: - { - break; - } - case 1: - break; - } } + return; } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestBetweenBlockAndStatement1() + [Fact] + public async Task TestBetweenSwitchAndStatement1() + { + await new Verify.Test { - await new Verify.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() + switch (0) { - if (true) - { - [|}|] - return; - } + [|}|] + return; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M() { - void M() + switch (0) { - if (true) - { - } - - return; } - } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - [Fact] - public async Task TestNotBetweenBlockAndStatement1_WhenOptionOff() - { - var code = """ - class C - { - void M() - { - if (true) - { - } - return; - } + return; } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestBetweenSwitchAndStatement1() + [Fact] + public async Task TestBetweenBlockAndStatement2() + { + await new Verify.Test { - await new Verify.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() + if (true) { - switch (0) - { - [|}|] - return; - } + [|}|] // trailing comment + return; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M() { - void M() + if (true) { - switch (0) - { - } + } // trailing comment - return; - } + return; } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestBetweenBlockAndStatement2() + [Fact] + public async Task TestBetweenBlockAndStatement3() + { + await new Verify.Test { - await new Verify.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() - { - if (true) - { - [|}|] // trailing comment - return; - } + if (true) { [|}|] + return; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M() { - void M() - { - if (true) - { - } // trailing comment + if (true) { } - return; - } + return; } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestBetweenBlockAndStatement3() + [Fact] + public async Task TestBetweenBlockAndStatement4() + { + await new Verify.Test { - await new Verify.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() + switch (0) { + case 0: if (true) { [|}|] return; } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M() { - void M() + switch (0) { + case 0: if (true) { } return; } } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestBetweenBlockAndStatement4() + [Fact] + public async Task TestFixAll1() + { + await new Verify.Test { - await new Verify.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() + if (true) { - switch (0) - { - case 0: - if (true) { [|}|] - return; - } - } + [|}|] + return; + if (true) + { + [|}|] + return; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M() { - void M() + if (true) { - switch (0) - { - case 0: - if (true) { } + } - return; - } + return; + if (true) + { } + + return; } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestFixAll1() - { - await new Verify.Test + [Fact] + public async Task TestSA1513NegativeCases() + { + var code = """ + using System; + using System.Linq; + using System.Collections.Generic; + public class Foo { - TestCode = """ - class C + private int x; + // Valid #1 + public int Bar { - void M() - { - if (true) - { - [|}|] - return; - if (true) - { - [|}|] - return; - } + get { return this.x; } + set { this.x = value; } } - """, - FixedCode = """ - class C + public void Baz() { - void M() + // Valid #2 + try { - if (true) - { - } - - return; - if (true) - { - } - - return; + this.x++; } - } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestSA1513NegativeCases() - { - var code = """ - using System; - using System.Linq; - using System.Collections.Generic; - public class Foo - { - private int x; - // Valid #1 - public int Bar + catch (Exception) { - get { return this.x; } - set { this.x = value; } + this.x = 0; } - public void Baz() + finally { - // Valid #2 - try - { - this.x++; - } - catch (Exception) + this.x++; + } + // Valid #3 + do + { + this.x++; + } + while (this.x < 10); + // Valid #4 + if (this.x > 0) + { + this.x++; + } + else + { + this.x = 0; + } + // Valid #5 + var y = new[] { 1, 2, 3 }; + // Valid #6 + if (this.x > 0) + { + if (y != null) { - this.x = 0; + this.x = -this.x; } - finally + } + // Valid #7 + if (this.x > 0) + { + this.x = 0; + } + #if !SOMETHING + else + { + this.x++; + } + #endif + // Valid #8 + #if !SOMETHING + if (this.x > 0) + { + this.x = 0; + } + #else + if (this.x < 0) + { + this.x++; + } + #endif + // Valid #9 + var q1 = + from a in new[] { - this.x++; + 1, + 2, + 3 } - // Valid #3 - do - { - this.x++; + from b in new[] { 4, 5, 6} + select a*b; + // Valid #10 + var q2 = + from a in new[] + { + 1, + 2, + 3 } - while (this.x < 10); - // Valid #4 - if (this.x > 0) - { - this.x++; + let b = new[] + { + a, + a * a, + a * a * a } - else + select b; + // Valid #11 + var q3 = + from a in new[] { - this.x = 0; + 1, + 2, + 3 } - // Valid #5 - var y = new[] { 1, 2, 3 }; - // Valid #6 - if (this.x > 0) - { - if (y != null) - { - this.x = -this.x; - } + where a > 0 + select a; + // Valid #12 + var q4 = + from a in new[] + { + new { Number = 1 }, + new { Number = 2 }, + new { Number = 3 } } - // Valid #7 - if (this.x > 0) - { - this.x = 0; + join b in new[] + { + new { Number = 2 }, + new { Number = 3 }, + new { Number = 4 } } - #if !SOMETHING - else - { - this.x++; + on a.Number equals b.Number + select new { Number1 = a.Number, Number2 = b.Number }; + // Valid #13 + var q5 = + from a in new[] + { + new { Number = 1 }, + new { Number = 2 }, + new { Number = 3 } } - #endif - // Valid #8 - #if !SOMETHING - if (this.x > 0) - { - this.x = 0; + orderby a.Number descending + select a; + // Valid #14 + var q6 = + from a in new[] + { + 1, + 2, + 3 } - #else - if (this.x < 0) + group new { - this.x++; + Number = a, + Square = a * a } - #endif - // Valid #9 - var q1 = - from a in new[] - { - 1, - 2, - 3 - } - from b in new[] { 4, 5, 6} - select a*b; - // Valid #10 - var q2 = - from a in new[] - { - 1, - 2, - 3 - } - let b = new[] - { - a, - a * a, - a * a * a - } - select b; - // Valid #11 - var q3 = - from a in new[] - { - 1, - 2, - 3 - } - where a > 0 - select a; - // Valid #12 - var q4 = - from a in new[] - { - new { Number = 1 }, - new { Number = 2 }, - new { Number = 3 } - } - join b in new[] - { - new { Number = 2 }, - new { Number = 3 }, - new { Number = 4 } - } - on a.Number equals b.Number - select new { Number1 = a.Number, Number2 = b.Number }; - // Valid #13 - var q5 = - from a in new[] - { - new { Number = 1 }, - new { Number = 2 }, - new { Number = 3 } - } - orderby a.Number descending - select a; - // Valid #14 - var q6 = - from a in new[] - { - 1, - 2, - 3 - } - group new - { - Number = a, - Square = a * a - } - by a; - // Valid #15 - var d = new[] + by a; + // Valid #15 + var d = new[] + { + 1, 2, 3 + }; + // Valid #16 + this.Qux(i => + { + return d[i] * 2; + }); + // Valid #17 + if (this.x > 2) + { + this.x = 3; + } /* Some comment */ + // Valid #18 + int[] testArray; + testArray = + new[] { - 1, 2, 3 + 1 }; - // Valid #16 - this.Qux(i => + // Valid #19 + var z1 = new object[] + { + new { - return d[i] * 2; - }); - // Valid #17 - if (this.x > 2) + Id = 12 + }, + new + { + Id = 13 + } + }; + // Valid #20 + var z2 = new System.Action[] + { + () => { this.x = 3; - } /* Some comment */ - // Valid #18 - int[] testArray; - testArray = - new[] - { - 1 - }; - // Valid #19 - var z1 = new object[] + }, + () => { - new - { - Id = 12 - }, - new - { - Id = 13 - } - }; - // Valid #20 - var z2 = new System.Action[] + this.x = 4; + } + }; + // Valid #21 + var z3 = new + { + Value1 = new + { + Id = 12 + }, + Value2 = new { - () => - { - this.x = 3; - }, - () => - { - this.x = 4; - } - }; - // Valid #21 - var z3 = new + Id = 13 + } + }; + // Valid #22 + var z4 = new System.Collections.Generic.List + { + new { - Value1 = new - { - Id = 12 - }, - Value2 = new - { - Id = 13 - } - }; - // Valid #22 - var z4 = new System.Collections.Generic.List + Id = 12 + }, + new { - new - { - Id = 12 - }, - new - { - Id = 13 - } - }; - } - public void Qux(Func function) + Id = 13 + } + }; + } + public void Qux(Func function) + { + this.x = function(this.x); + } + public Func Quux() + { + // Valid #23 + #if SOMETHING + return null; + #else + return value => { - this.x = function(this.x); + return value * 2; + }; + #endif + } + // Valid #24 (will be handled by SA1516) + public int Corge + { + get + { + return this.x; } - public Func Quux() - { - // Valid #23 - #if SOMETHING - return null; - #else - return value => - { - return value * 2; - }; - #endif + set { this.x = value; } + } + // Valid #25 (will be handled by SA1516) + public int Grault + { + set + { + this.x = value; } - // Valid #24 (will be handled by SA1516) - public int Corge - { - get - { - return this.x; - } - set { this.x = value; } + get + { + return this.x; } - // Valid #25 (will be handled by SA1516) - public int Grault + } + // Valid #26 (will be handled by SA1516) + public event EventHandler Garply + { + add { - set - { - this.x = value; - } - get - { - return this.x; - } } - // Valid #26 (will be handled by SA1516) - public event EventHandler Garply + remove { - add - { - } - remove - { - } } - // Valid #27 (will be handled by SA1516) - public event EventHandler Waldo + } + // Valid #27 (will be handled by SA1516) + public event EventHandler Waldo + { + remove { - remove - { - } - add - { - } } - // Valid #28 - Test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1020 - private static IEnumerable Method() + add { - yield return new - { - prop = "A" - }; - } - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/784 - public void MultiLineLinqQuery() - { - var someQuery = (from f in Enumerable.Empty() - where f != 0 - select new { Fish = "Face" }).ToList(); - var someOtherQuery = (from f in Enumerable.Empty() - where f != 0 - select new - { - Fish = "AreFriends", - Not = "Food" - }).ToList(); - } - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2306 - public void MultiLineGroupByLinqQuery() - { - var someQuery = from f in Enumerable.Empty() - group f by new - { - f, - } - into a - select a; - var someOtherQuery = from f in Enumerable.Empty() - group f by new { f } - into a - select a; } - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 - public object[] ExpressionBodiedProperty => - new[] - { - new object() - }; - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 - public object[] ExpressionBodiedMethod() => - new[] - { - new object() - }; - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 - public object[] GetterOnlyAutoProperty1 { get; } = - new[] - { - new object() - }; - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 - public object[] GetterOnlyAutoProperty2 { get; } = - { - }; - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1173 - bool contained = - new[] - { - 1, - 2, - 3 - } - .Contains(3); - // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1583 - public void TestTernaryConstruction() - { - var target = contained - ? new Dictionary - { - { "target", "_parent" } - } - : new Dictionary(); + } + // Valid #28 - Test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1020 + private static IEnumerable Method() + { + yield return new + { + prop = "A" + }; + } + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/784 + public void MultiLineLinqQuery() + { + var someQuery = (from f in Enumerable.Empty() + where f != 0 + select new { Fish = "Face" }).ToList(); + var someOtherQuery = (from f in Enumerable.Empty() + where f != 0 + select new + { + Fish = "AreFriends", + Not = "Food" + }).ToList(); + } + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2306 + public void MultiLineGroupByLinqQuery() + { + var someQuery = from f in Enumerable.Empty() + group f by new + { + f, + } + into a + select a; + var someOtherQuery = from f in Enumerable.Empty() + group f by new { f } + into a + select a; + } + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 + public object[] ExpressionBodiedProperty => + new[] + { + new object() + }; + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 + public object[] ExpressionBodiedMethod() => + new[] + { + new object() + }; + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 + public object[] GetterOnlyAutoProperty1 { get; } = + new[] + { + new object() + }; + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1049 + public object[] GetterOnlyAutoProperty2 { get; } = + { + }; + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1173 + bool contained = + new[] + { + 1, + 2, + 3 } + .Contains(3); + // This is a regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1583 + public void TestTernaryConstruction() + { + var target = contained + ? new Dictionary + { + { "target", "_parent" } + } + : new Dictionary(); } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - [Fact] - public async Task TestSA1513PositiveCases() + [Fact] + public async Task TestSA1513PositiveCases() + { + await new Verify.Test { - await new Verify.Test + TestCode = """ + using System; + using System.Collections.Generic; + public class Goo { - TestCode = """ - using System; - using System.Collections.Generic; - public class Goo + private int x; + // Invalid #1 + public int Property1 { - private int x; - // Invalid #1 - public int Property1 - { - get - { - return this.x; - } - set - { - this.x = value; - } - /* some comment */ + get + { + return this.x; } - // Invalid #2 - public int Property2 + set { - get { return this.x; } + this.x = value; } - public void Baz() + /* some comment */ + } + // Invalid #2 + public int Property2 + { + get { return this.x; } + } + public void Baz() + { + // Invalid #3 + switch (this.x) { - // Invalid #3 - switch (this.x) + case 1: { - case 1: - { - this.x = 1; - break; - } - case 2: - this.x = 2; - break; + this.x = 1; + break; } - // Invalid #4 - { - var temp = this.x; - this.x = temp * temp; - [|}|] - this.x++; - // Invalid #5 - if (this.x > 1) + case 2: + this.x = 2; + break; + } + // Invalid #4 + { + var temp = this.x; + this.x = temp * temp; + [|}|] + this.x++; + // Invalid #5 + if (this.x > 1) + { + this.x = 1; + [|}|] + if (this.x < 0) + { + this.x = 0; + [|}|] + switch (this.x) + { + // Invalid #6 + case 0: + if (this.x < 0) { - this.x = 1; + this.x = -1; [|}|] - if (this.x < 0) + break; + // Invalid #7 + case 1: { - this.x = 0; + var temp = this.x * this.x; + this.x = temp; [|}|] - switch (this.x) + break; + } + } + public void Example() + { + new List + { + () => { - // Invalid #6 - case 0: - if (this.x < 0) + if (true) { - this.x = -1; - [|}|] - break; - // Invalid #7 - case 1: - { - var temp = this.x * this.x; - this.x = temp; + return; [|}|] - break; + return; } + }; + } + } + """, + FixedCode = """ + using System; + using System.Collections.Generic; + public class Goo + { + private int x; + // Invalid #1 + public int Property1 + { + get + { + return this.x; } - public void Example() + set { - new List - { - () => - { - if (true) - { - return; - [|}|] - return; - } - }; + this.x = value; } + /* some comment */ } - """, - FixedCode = """ - using System; - using System.Collections.Generic; - public class Goo + // Invalid #2 + public int Property2 { - private int x; - // Invalid #1 - public int Property1 + get { return this.x; } + } + public void Baz() + { + // Invalid #3 + switch (this.x) { - get - { - return this.x; - } - set + case 1: { - this.x = value; + this.x = 1; + break; } - /* some comment */ + case 2: + this.x = 2; + break; } - // Invalid #2 - public int Property2 + // Invalid #4 { - get { return this.x; } + var temp = this.x; + this.x = temp * temp; } - public void Baz() + + this.x++; + // Invalid #5 + if (this.x > 1) { - // Invalid #3 - switch (this.x) - { - case 1: - { - this.x = 1; - break; - } - case 2: - this.x = 2; - break; - } - // Invalid #4 - { - var temp = this.x; - this.x = temp * temp; - } + this.x = 1; + } - this.x++; - // Invalid #5 - if (this.x > 1) - { - this.x = 1; - } + if (this.x < 0) + { + this.x = 0; + } + switch (this.x) + { + // Invalid #6 + case 0: if (this.x < 0) { - this.x = 0; + this.x = -1; } - switch (this.x) + break; + // Invalid #7 + case 1: { - // Invalid #6 - case 0: - if (this.x < 0) - { - this.x = -1; - } - - break; - // Invalid #7 - case 1: - { - var temp = this.x * this.x; - this.x = temp; - } - - break; + var temp = this.x * this.x; + this.x = temp; } + + break; } - public void Example() + } + public void Example() + { + new List { - new List + () => { - () => + if (true) { - if (true) - { - return; - } - return; } - }; - } + + return; + } + }; } - """, - Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """, + Options = { { CodeStyleOptions2.AllowStatementImmediatelyAfterBlock, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementTests.cs b/src/Analyzers/CSharp/Tests/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementTests.cs index 9336ce4491685..da77078eaf284 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/ConstructorInitializerPlacement/ConstructorInitializerPlacementTests.cs @@ -9,258 +9,257 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConstructorInitializerPlacement -{ - using Verify = CSharpCodeFixVerifier< - ConstructorInitializerPlacementDiagnosticAnalyzer, - ConstructorInitializerPlacementCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.ConstructorInitializerPlacement; + +using Verify = CSharpCodeFixVerifier< + ConstructorInitializerPlacementDiagnosticAnalyzer, + ConstructorInitializerPlacementCodeFixProvider>; - public class ConstructorInitializerPlacementTests +public class ConstructorInitializerPlacementTests +{ + [Fact] + public async Task TestNotWithOptionOff() { - [Fact] - public async Task TestNotWithOptionOff() - { - var code = - """ - class C + var code = + """ + class C + { + public C() : + base() { - public C() : - base() - { - } } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.TrueWithSilentEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestSimpleCase() + await new Verify.Test { - var code = - """ - class C - { - public C() [|:|] - base() - { - } - } - """; + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.TrueWithSilentEnforcement } } + }.RunAsync(); + } - var fixedCode = - """ - class C + [Fact] + public async Task TestSimpleCase() + { + var code = + """ + class C + { + public C() [|:|] + base() { - public C() - : base() - { - } } - """; + } + """; - await new Verify.Test + var fixedCode = + """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNotOnSameLine1() - { - var code = - """ - class C + public C() + : base() { - public C() : base() - { - } } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotOnSameLine2() + await new Verify.Test { - var code = - """ - class C - { - public C() - : base() - { - } - } - """; + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - await new Verify.Test + [Fact] + public async Task TestNotOnSameLine1() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public C() : base() + { + } + } + """; - [Fact] - public async Task TestNotWithColonTrailingComment() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotOnSameLine2() + { + var code = + """ + class C + { + public C() + : base() { - public C() : //comment - base() - { - } } - """; + } + """; - await new Verify.Test + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithColonTrailingComment() + { + var code = + """ + class C { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + public C() : //comment + base() + { + } + } + """; - [Fact] - public async Task TestWithCloseParenTrailingComment1() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithCloseParenTrailingComment1() + { + var code = + """ + class C + { + public C() /*comment*/ [|:|] + base() { - public C() /*comment*/ [|:|] - base() - { - } } - """; - var fixedCode = - """ - class C + } + """; + var fixedCode = + """ + class C + { + public C() /*comment*/ + : base() { - public C() /*comment*/ - : base() - { - } } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestWithColonLeadingComment1() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithColonLeadingComment1() + { + var code = + """ + class C + { + public C() + // comment + [|:|] + base() { - public C() - // comment - [|:|] - base() - { - } } - """; - var fixedCode = - """ - class C + } + """; + var fixedCode = + """ + class C + { + public C() + // comment + + : base() { - public C() - // comment - - : base() - { - } } - """; + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestWithLeadingComment() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithLeadingComment() + { + var code = + """ + class C + { + public C() [|:|] + // comment + base() { - public C() [|:|] - // comment - base() - { - } } - """; - var fixedCode = - """ - class C + } + """; + var fixedCode = + """ + class C + { + public C() + // comment + : base() { - public C() - // comment - : base() - { - } } - """; - - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestWithLeadingDirective() + await new Verify.Test { - var code = - """ - class C + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestWithLeadingDirective() + { + var code = + """ + class C + { + public C() : + #if true + base() { - public C() : - #if true - base() - { - } - #endif } - """; + #endif + } + """; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = code, + Options = { { CSharpCodeStyleOptions.AllowBlankLineAfterColonInConstructorInitializer, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementTests.cs b/src/Analyzers/CSharp/Tests/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementTests.cs index 8ec6e9eb87f3f..8388ab43f13c9 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/EmbeddedStatementPlacement/EmbeddedStatementPlacementTests.cs @@ -9,335 +9,334 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.EmbeddedStatementPlacement -{ - using VerifyCS = CSharpCodeFixVerifier< - EmbeddedStatementPlacementDiagnosticAnalyzer, - EmbeddedStatementPlacementCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.EmbeddedStatementPlacement; + +using VerifyCS = CSharpCodeFixVerifier< + EmbeddedStatementPlacementDiagnosticAnalyzer, + EmbeddedStatementPlacementCodeFixProvider>; - public class EmbeddedStatementPlacementTests +public class EmbeddedStatementPlacementTests +{ + [Fact] + public async Task NoErrorOnWrappedStatement() { - [Fact] - public async Task NoErrorOnWrappedStatement() - { - var source = """ - class TestClass - { - void M() - { - if (true) - return; - } - } - """; - await new VerifyCS.Test + var source = """ + class TestClass { - TestCode = source, - FixedCode = source, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task ErrorOnNonWrappedIfStatement() - { - var source = """ - class TestClass + void M() { - void M() - { - if (true) [|return|]; - } + if (true) + return; } - """; - var fixedCode = """ - class TestClass + } + """; + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task ErrorOnNonWrappedIfStatement() + { + var source = """ + class TestClass + { + void M() { - void M() - { - if (true) - return; - } + if (true) [|return|]; } - """; - await new VerifyCS.Test + } + """; + var fixedCode = """ + class TestClass { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task NoErrorOnNonWrappedIfStatement_WhenOptionDisabled() - { - var source = """ - class TestClass + void M() { - void M() - { - if (true) return; - } + if (true) + return; } - """; - await new VerifyCS.Test - { - TestCode = source, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, true, NotificationOption2.Suggestion } } - }.RunAsync(); - } - - [Fact] - public async Task NotOnElseIf() + } + """; + await new VerifyCS.Test { - var source = """ - class TestClass + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task NoErrorOnNonWrappedIfStatement_WhenOptionDisabled() + { + var source = """ + class TestClass + { + void M() { - void M() - { - if (true) - return; - else if (true) - return; - } + if (true) return; } - """; + } + """; + await new VerifyCS.Test + { + TestCode = source, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, true, NotificationOption2.Suggestion } } + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task NotOnElseIf() + { + var source = """ + class TestClass { - TestCode = source, - FixedCode = source, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + if (true) + return; + else if (true) + return; + } + } + """; - [Fact] - public async Task ErrorOnElseWithNonIfStatementOnSameLine() + await new VerifyCS.Test { - var source = """ - class TestClass + TestCode = source, + FixedCode = source, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task ErrorOnElseWithNonIfStatementOnSameLine() + { + var source = """ + class TestClass + { + void M() { - void M() - { - if (true) - return; - else [|return|]; - } + if (true) + return; + else [|return|]; } - """; - var fixedCode = """ - class TestClass + } + """; + var fixedCode = """ + class TestClass + { + void M() { - void M() - { - if (true) - return; - else - return; - } + if (true) + return; + else + return; } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task ErrorOnIfWithSingleLineBlock() + } + """; + await new VerifyCS.Test { - var source = """ - class TestClass + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task ErrorOnIfWithSingleLineBlock() + { + var source = """ + class TestClass + { + void M() { - void M() - { - if (true) [|{|] return; } - } + if (true) [|{|] return; } } - """; - var fixedCode = """ - class TestClass + } + """; + var fixedCode = """ + class TestClass + { + void M() { - void M() + if (true) { - if (true) - { - return; - } + return; } } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task NoWrappingForMemberOrLambdaBlock() + } + """; + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - class TestClass - { - void M() { return; } - void N() - { - Action a1 = () => { return; }; - Action a2 = delegate () { return; }; - } + [Fact] + public async Task NoWrappingForMemberOrLambdaBlock() + { + var source = """ + using System; - int Prop1 { get { return 1; } } - int Prop2 - { - get { return 1; } - } - } - """; - await new VerifyCS.Test + class TestClass { - TestCode = source, - FixedCode = source, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task WrappingForLocalFunction() - { - var source = """ - class TestClass + void M() { return; } + void N() { - void N() - { - void Local() [|{|] return; } - } + Action a1 = () => { return; }; + Action a2 = delegate () { return; }; } - """; - var fixedCode = """ - class TestClass + + int Prop1 { get { return 1; } } + int Prop2 { - void N() - { - void Local() - { - return; - } - } + get { return 1; } } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task ErrorOnNonWrappedIfStatementWithEmptyBlock() + } + """; + await new VerifyCS.Test { - var source = """ - class TestClass + TestCode = source, + FixedCode = source, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task WrappingForLocalFunction() + { + var source = """ + class TestClass + { + void N() { - void M() - { - if (true) [|{|] } - } + void Local() [|{|] return; } } - """; - var fixedCode = """ - class TestClass + } + """; + var fixedCode = """ + class TestClass + { + void N() { - void M() + void Local() { - if (true) - { - } + return; } } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task WrapLambdaWithNestedStatement() + } + """; + await new VerifyCS.Test { - var source = """ - using System; + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } - class TestClass + [Fact] + public async Task ErrorOnNonWrappedIfStatementWithEmptyBlock() + { + var source = """ + class TestClass + { + void M() { - void N() - { - Action a1 = () => { [|if|] (true) return; }; - } + if (true) [|{|] } } - """; - var fixedCode = """ - using System; - - class TestClass + } + """; + var fixedCode = """ + class TestClass + { + void M() { - void N() + if (true) { - Action a1 = () => - { - if (true) - return; - }; } } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task FixAll1() + } + """; + await new VerifyCS.Test { - var source = """ - class TestClass + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task WrapLambdaWithNestedStatement() + { + var source = """ + using System; + + class TestClass + { + void N() { - void M() - { - if (true) [|return|]; - if (true) [|return|]; - } + Action a1 = () => { [|if|] (true) return; }; } - """; - var fixedCode = """ - class TestClass + } + """; + var fixedCode = """ + using System; + + class TestClass + { + void N() { - void M() + Action a1 = () => { if (true) return; - if (true) - return; - } + }; + } + } + """; + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task FixAll1() + { + var source = """ + class TestClass + { + void M() + { + if (true) [|return|]; + if (true) [|return|]; } - """; - await new VerifyCS.Test + } + """; + var fixedCode = """ + class TestClass { - TestCode = source, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + void M() + { + if (true) + return; + if (true) + return; + } + } + """; + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.AllowEmbeddedStatementsOnSameLine, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/NewLines/MultipleBlankLines/MultipleBlankLinesTests.cs b/src/Analyzers/CSharp/Tests/NewLines/MultipleBlankLines/MultipleBlankLinesTests.cs index 224902324d539..b1dcc6edc3e62 100644 --- a/src/Analyzers/CSharp/Tests/NewLines/MultipleBlankLines/MultipleBlankLinesTests.cs +++ b/src/Analyzers/CSharp/Tests/NewLines/MultipleBlankLines/MultipleBlankLinesTests.cs @@ -9,260 +9,260 @@ using Microsoft.CodeAnalysis.NewLines.MultipleBlankLines; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.MultipleBlankLines -{ - using Verify = CSharpCodeFixVerifier< - CSharpMultipleBlankLinesDiagnosticAnalyzer, - MultipleBlankLinesCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.NewLines.MultipleBlankLines; + +using Verify = CSharpCodeFixVerifier< + CSharpMultipleBlankLinesDiagnosticAnalyzer, + MultipleBlankLinesCodeFixProvider>; - public class MultipleBlankLinesTests +public class MultipleBlankLinesTests +{ + [Fact] + public async Task TestOneBlankLineAtTopOfFile() { - [Fact] - public async Task TestOneBlankLineAtTopOfFile() - { - var code = + var code = @" // comment"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAtTopOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAtTopOfFile() + { + var code = @"[||] // comment"; - var fixedCode = + var fixedCode = @" // comment"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAtTopOfFile_NotWithOptionOff() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAtTopOfFile_NotWithOptionOff() + { + var code = @" // comment"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.TrueWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineAtTopOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.TrueWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineAtTopOfFile() + { + var code = @"[||] // comment"; - var fixedCode = + var fixedCode = @" // comment"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineAtTopOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineAtTopOfFile() + { + var code = @"[||] // comment"; - var fixedCode = + var fixedCode = @" // comment"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineAtTopOfEmptyFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineAtTopOfEmptyFile() + { + var code = @" "; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLinesAtTopOfEmptyFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLinesAtTopOfEmptyFile() + { + var code = @"[||] "; - var fixedCode = + var fixedCode = @" "; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLinesAtTopOfEmptyFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLinesAtTopOfEmptyFile() + { + var code = @"[||] "; - var fixedCode = + var fixedCode = @" "; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLinesAtTopOfEmptyFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLinesAtTopOfEmptyFile() + { + var code = @"[||] "; - var fixedCode = + var fixedCode = @" "; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineAtEndOfFile_1() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineAtEndOfFile_1() + { + var code = @"class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineAtEndOfFile_2() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineAtEndOfFile_2() + { + var code = @"class C { } "; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineAtEndOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineAtEndOfFile() + { + var code = @"class C { } "; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAtEndOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAtEndOfFile() + { + var code = @"class C { } [||] "; - var fixedCode = + var fixedCode = @"class C { } "; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineAtEndOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineAtEndOfFile() + { + var code = @"class C { } @@ -270,25 +270,25 @@ public async Task TestThreeBlankLineAtEndOfFile() "; - var fixedCode = + var fixedCode = @"class C { } "; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineAtEndOfFile() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineAtEndOfFile() + { + var code = @"class C { } @@ -297,105 +297,105 @@ public async Task TestFourBlankLineAtEndOfFile() "; - var fixedCode = + var fixedCode = @"class C { } "; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineBetweenTokens() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineBetweenTokens() + { + var code = @"class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineBetweenTokens() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineBetweenTokens() + { + var code = @"class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineBetweenTokens() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineBetweenTokens() + { + var code = @"class C { [||] }"; - var fixedCode = + var fixedCode = @"class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineBetweenTokens() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineBetweenTokens() + { + var code = @"class C { [||] }"; - var fixedCode = + var fixedCode = @"class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineBetweenTokens() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineBetweenTokens() + { + var code = @"class C { [||] @@ -403,84 +403,84 @@ public async Task TestFourBlankLineBetweenTokens() }"; - var fixedCode = + var fixedCode = @"class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineAfterComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineAfterComment() + { + var code = @"class C { // comment }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineAfterComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineAfterComment() + { + var code = @"class C { // comment }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAfterComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAfterComment() + { + var code = @"class C { // comment [||] }"; - var fixedCode = + var fixedCode = @"class C { // comment }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineAfterComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineAfterComment() + { + var code = @"class C { // comment @@ -488,25 +488,25 @@ public async Task TestThreeBlankLineAfterComment() }"; - var fixedCode = + var fixedCode = @"class C { // comment }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineAfterComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineAfterComment() + { + var code = @"class C { // comment @@ -514,88 +514,88 @@ public async Task TestFourBlankLineAfterComment() }"; - var fixedCode = + var fixedCode = @"class C { // comment }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineAfterDirective() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineAfterDirective() + { + var code = @"class C { #nullable enable }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineAfterDirective() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineAfterDirective() + { + var code = @"class C { #nullable enable }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAfterDirective() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAfterDirective() + { + var code = @"class C { #nullable enable [||] }"; - var fixedCode = + var fixedCode = @"class C { #nullable enable }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineAfterDirective() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineAfterDirective() + { + var code = @"class C { #nullable enable @@ -603,26 +603,26 @@ public async Task TestThreeBlankLineAfterDirective() }"; - var fixedCode = + var fixedCode = @"class C { #nullable enable }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineAfterDirective() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineAfterDirective() + { + var code = @"class C { #nullable enable @@ -630,44 +630,44 @@ public async Task TestFourBlankLineAfterDirective() }"; - var fixedCode = + var fixedCode = @"class C { #nullable enable }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineAfterDocComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineAfterDocComment() + { + var code = @" /// class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineAfterDocComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineAfterDocComment() + { + var code = @" /// @@ -675,18 +675,18 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAfterDocComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAfterDocComment() + { + var code = @" /// [||] @@ -694,7 +694,7 @@ public async Task TestTwoBlankLineAfterDocComment() class C { }"; - var fixedCode = + var fixedCode = @" /// @@ -702,18 +702,18 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineAfterDocComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineAfterDocComment() + { + var code = @" /// [||] @@ -722,7 +722,7 @@ public async Task TestThreeBlankLineAfterDocComment() class C { }"; - var fixedCode = + var fixedCode = @" /// @@ -730,18 +730,18 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineAfterDocComment() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineAfterDocComment() + { + var code = @" /// [||] @@ -751,7 +751,7 @@ public async Task TestFourBlankLineAfterDocComment() class C { }"; - var fixedCode = + var fixedCode = @" /// @@ -759,18 +759,18 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestNoBlankLineAllConstructs() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestNoBlankLineAllConstructs() + { + var code = @"/// // #nullable enable @@ -778,19 +778,19 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestOneBlankLineAllConstructs() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestOneBlankLineAllConstructs() + { + var code = @" /// @@ -802,19 +802,19 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestTwoBlankLineAllConstructs() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = code, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestTwoBlankLineAllConstructs() + { + var code = @"[||] /// @@ -829,7 +829,7 @@ public async Task TestTwoBlankLineAllConstructs() class C { }"; - var fixedCode = + var fixedCode = @" /// @@ -841,19 +841,19 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestThreeBlankLineAllConstructs() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestThreeBlankLineAllConstructs() + { + var code = @"[||] @@ -872,7 +872,7 @@ public async Task TestThreeBlankLineAllConstructs() class C { }"; - var fixedCode = + var fixedCode = @" /// @@ -884,19 +884,19 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } - - [Fact] - public async Task TestFourBlankLineAllConstructs() + await new Verify.Test { - var code = + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); + } + + [Fact] + public async Task TestFourBlankLineAllConstructs() + { + var code = @"[||] @@ -919,7 +919,7 @@ public async Task TestFourBlankLineAllConstructs() class C { }"; - var fixedCode = + var fixedCode = @" /// @@ -931,13 +931,12 @@ class C { }"; - await new Verify.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, - Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } - }.RunAsync(); - } + await new Verify.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp8, + Options = { { CodeStyleOptions2.AllowMultipleBlankLines, CodeStyleOption2.FalseWithSuggestionEnforcement } } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/Nullable/CSharpDeclareAsNullableCodeFixTests.cs b/src/Analyzers/CSharp/Tests/Nullable/CSharpDeclareAsNullableCodeFixTests.cs index 465b16db2bcf6..0329c24a7a6cb 100644 --- a/src/Analyzers/CSharp/Tests/Nullable/CSharpDeclareAsNullableCodeFixTests.cs +++ b/src/Analyzers/CSharp/Tests/Nullable/CSharpDeclareAsNullableCodeFixTests.cs @@ -12,1300 +12,1299 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.DeclareAsNullable +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.DeclareAsNullable; + +[Trait(Traits.Feature, Traits.Features.CodeActionsDeclareAsNullable)] +public class CSharpDeclareAsNullableCodeFixTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsDeclareAsNullable)] - public class CSharpDeclareAsNullableCodeFixTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public CSharpDeclareAsNullableCodeFixTests(ITestOutputHelper logger) + : base(logger) { - public CSharpDeclareAsNullableCodeFixTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpDeclareAsNullableCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpDeclareAsNullableCodeFixProvider()); - private static readonly TestParameters s_nullableFeature = new TestParameters(parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + private static readonly TestParameters s_nullableFeature = new TestParameters(parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - [Fact] - public async Task FixAll() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + [Fact] + public async Task FixAll() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static string M() { - static string M() - { - return {|FixAllInDocument:null|}; - } - static string M2(bool b) - { - if (b) - return null; - else - return null; - } + return {|FixAllInDocument:null|}; } - """, - """ - #nullable enable - class Program + static string M2(bool b) { - static string? M() - { + if (b) + return null; + else return null; - } - static string? M2(bool b) - { - if (b) - return null; - else - return null; - } } - """, parameters: s_nullableFeature); - } - - [Fact] - public async Task FixReturnType() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + } + """, + """ + #nullable enable + class Program + { + static string? M() { - static string M() - { - return [|null|]; - } + return null; } - """, - """ - #nullable enable - class Program + static string? M2(bool b) { - static string? M() - { + if (b) + return null; + else return null; - } } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixReturnType() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static string M() + { + return [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static string? M() + { + return null; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_Async() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + [Fact] + public async Task FixReturnType_Async() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static async System.Threading.Tasks.Task M() + { + return [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static async System.Threading.Tasks.Task M() + { + return null; + } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixReturnType_AsyncLocalFunction() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void M() { - static async System.Threading.Tasks.Task M() + async System.Threading.Tasks.Task local() { return [|null|]; } } - """, - """ - #nullable enable - class Program + } + """, + """ + #nullable enable + class Program + { + static void M() { - static async System.Threading.Tasks.Task M() + async System.Threading.Tasks.Task local() { return null; } } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_AsyncLocalFunction() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void M() - { - async System.Threading.Tasks.Task local() - { - return [|null|]; - } - } - } - """, - """ - #nullable enable - class Program + [Fact] + public async Task FixReturnType_WithTrivia() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static /*before*/ string /*after*/ M() + { + return [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static /*before*/ string? /*after*/ M() + { + return null; + } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixReturnType_ArrowBody() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static string M() => [|null|]; + } + """, + """ + #nullable enable + class Program + { + static string? M() => null; + } + """, parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26639")] + public async Task FixReturnType_LocalFunction_ArrowBody() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + static void M() { - static void M() - { - async System.Threading.Tasks.Task local() - { - return null; - } - } + string local() => [|null|]; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_WithTrivia() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26639")] + public async Task FixLocalFunctionReturnType() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + void M() { - static /*before*/ string /*after*/ M() + string local() { return [|null|]; } } - """, - """ - #nullable enable - class Program + } + """, + """ + #nullable enable + class Program + { + void M() { - static /*before*/ string? /*after*/ M() + string? local() { return null; } } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_ArrowBody() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static string M() => [|null|]; - } - """, - """ - #nullable enable - class Program + [Fact] + public async Task NoFixAlreadyNullableReturnType() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + static string? M() { - static string? M() => null; + return [|null|]; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26639")] - public async Task FixReturnType_LocalFunction_ArrowBody() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - static void M() - { - string local() => [|null|]; - } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26628")] + public async Task FixField() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string x = [|null|]; + } + """, + """ + #nullable enable + class Program + { + string? x = null; + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26639")] - public async Task FixLocalFunctionReturnType() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - void M() - { - string local() - { - return [|null|]; - } - } - } - """, - """ - #nullable enable - class Program - { - void M() - { - string? local() - { - return null; - } - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixFieldEqualsNull() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string x; + void M() + { + x = [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + string? x; + void M() + { + x = null; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task NoFixAlreadyNullableReturnType() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - static string? M() - { - return [|null|]; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixPropertyEqualsNull() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string x { get; set; } + void M() + { + x = [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + string? x { get; set; } + void M() + { + x = null; + } + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26628")] - public async Task FixField() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + [Fact] + public async Task FixLocalDeclaration() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void M() { string x = [|null|]; } - """, - """ - #nullable enable - class Program + } + """, + """ + #nullable enable + class Program + { + static void M() { string? x = null; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixFieldEqualsNull() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - string x; - void M() - { - x = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - string? x; - void M() - { - x = null; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixLocalDeclaration_FromAssignment() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void M() + { + string x = ""; + x = [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static void M() + { + string? x = ""; + x = null; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixPropertyEqualsNull() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - string x { get; set; } - void M() - { - x = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - string? x { get; set; } - void M() - { - x = null; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task CannotFixMultiLocalDeclaration_FromAssignment() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + static void M() + { + string x, y; + x = [|null|]; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixLocalDeclaration() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void M() - { - string x = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - static void M() - { - string? x = null; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixParameter_FromAssignment() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void M(out string x) + { + x = [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static void M(out string? x) + { + x = null; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixLocalDeclaration_FromAssignment() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void M() - { - string x = ""; - x = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - static void M() - { - string? x = ""; - x = null; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task CannotFixParameterOfPartialMethod_FromAssignment() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + partial class Program + { + partial void M(out string x); - [Fact] - public async Task CannotFixMultiLocalDeclaration_FromAssignment() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program + partial void M(out string x) { - static void M() - { - string x, y; - x = [|null|]; - } + x = [|null|]; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixParameter_FromAssignment() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void M(out string x) - { - x = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - static void M(out string? x) - { - x = null; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task CannotFixParameterOfExtendedPartialMethod_FromAssignment() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + partial class Program + { + public partial void M(out string x); - [Fact] - public async Task CannotFixParameterOfPartialMethod_FromAssignment() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - partial class Program + public partial void M(out string x) { - partial void M(out string x); - - partial void M(out string x) - { - x = [|null|]; - } + x = [|null|]; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task CannotFixParameterOfExtendedPartialMethod_FromAssignment() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - partial class Program + [Fact] + public async Task FixLocalDeclaration_WithVar() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + static void M() { - public partial void M(out string x); - - public partial void M(out string x) - { - x = [|null|]; - } + var x = [|null|]; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixLocalDeclaration_WithVar() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program + [Fact] + public async Task NoFixMultiDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + static void M() { - static void M() - { - var x = [|null|]; - } + string x = [|null|], y = null; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task NoFixMultiDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - static void M() - { - string x = [|null|], y = null; - } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26628")] + public async Task FixPropertyDeclaration() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string x { get; set; } = [|null|]; + } + """, + """ + #nullable enable + class Program + { + string? x { get; set; } = null; + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26628")] - public async Task FixPropertyDeclaration() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - string x { get; set; } = [|null|]; - } - """, - """ - #nullable enable - class Program - { - string? x { get; set; } = null; - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixPropertyDeclaration_WithReturnNull() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string x { get { return [|null|]; } } + } + """, + """ + #nullable enable + class Program + { + string? x { get { return null; } } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixPropertyDeclaration_WithReturnNull() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - string x { get { return [|null|]; } } - } - """, - """ - #nullable enable - class Program - { - string? x { get { return null; } } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixPropertyDeclaration_ArrowBody() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string x => [|null|]; + } + """, + """ + #nullable enable + class Program + { + string? x => null; + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixPropertyDeclaration_ArrowBody() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - string x => [|null|]; - } - """, - """ - #nullable enable - class Program - { - string? x => null; - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26626")] + [WorkItem("https://github.com/dotnet/roslyn/issues/30026")] + public async Task FixOptionalParameter() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void M(string x = [|null|]) { } + } + """, + """ + #nullable enable + class Program + { + static void M(string? x = null) { } + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26626")] - [WorkItem("https://github.com/dotnet/roslyn/issues/30026")] - public async Task FixOptionalParameter() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void M(string x = [|null|]) { } - } - """, - """ - #nullable enable - class Program - { - static void M(string? x = null) { } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixLocalWithAs() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void M(object o) + { + string x = [|o as string|]; + } + } + """, + """ + #nullable enable + class Program + { + static void M(object o) + { + string? x = o as string; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixLocalWithAs() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void M(object o) - { - string x = [|o as string|]; - } - } - """, - """ - #nullable enable - class Program - { - static void M(object o) - { - string? x = o as string; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixReturnType_Iterator_Enumerable() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static System.Collections.Generic.IEnumerable M() + { + yield return [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static System.Collections.Generic.IEnumerable M() + { + yield return null; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_Iterator_Enumerable() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + [Fact] + public async Task FixReturnType_Iterator_Enumerator() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static System.Collections.Generic.IEnumerator M() + { + yield return [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static System.Collections.Generic.IEnumerator M() + { + yield return null; + } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixReturnType_IteratorProperty() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + System.Collections.Generic.IEnumerable Property { - static System.Collections.Generic.IEnumerable M() + get { yield return [|null|]; } } - """, - """ - #nullable enable - class Program + } + """, + """ + #nullable enable + class Program + { + System.Collections.Generic.IEnumerable Property { - static System.Collections.Generic.IEnumerable M() + get { yield return null; } } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_Iterator_Enumerator() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + [Fact] + public async Task FixReturnType_Iterator_LocalFunction() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + void M() { - static System.Collections.Generic.IEnumerator M() + System.Collections.Generic.IEnumerable local() { yield return [|null|]; } } - """, - """ - #nullable enable - class Program + } + """, + """ + #nullable enable + class Program + { + void M() { - static System.Collections.Generic.IEnumerator M() + System.Collections.Generic.IEnumerable local() { yield return null; } } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_IteratorProperty() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - System.Collections.Generic.IEnumerable Property - { - get - { - yield return [|null|]; - } - } - } - """, - """ - #nullable enable - class Program - { - System.Collections.Generic.IEnumerable Property - { - get - { - yield return null; - } - } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39422")] + public async Task FixReturnType_ConditionalOperator_Function() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string Test(bool? value) + { + return [|value?.ToString()|]; + } + } + """, + """ + #nullable enable + class Program + { + string? Test(bool? value) + { + return value?.ToString(); + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixReturnType_Iterator_LocalFunction() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - void M() - { - System.Collections.Generic.IEnumerable local() - { - yield return [|null|]; - } - } - } - """, - """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39422")] + public async Task FixAllReturnType_ConditionalOperator_Function() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string field; + string Property { get; set; } + + string Test(bool? value) { - void M() - { - System.Collections.Generic.IEnumerable local() - { - yield return null; - } - } + return {|FixAllInDocument:value?.ToString()|}; } - """, parameters: s_nullableFeature); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39422")] - public async Task FixReturnType_ConditionalOperator_Function() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + string Test1(bool? value) { - string Test(bool? value) - { - return [|value?.ToString()|]; - } + return value?.ToString(); } - """, - """ - #nullable enable - class Program + + string Test2(bool? value) { - string? Test(bool? value) - { - return value?.ToString(); - } + field = null; + Property = null; + return null; } - """, parameters: s_nullableFeature); - } + } + """, + """ + #nullable enable + class Program + { + string field; + string Property { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39422")] - public async Task FixAllReturnType_ConditionalOperator_Function() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + string? Test(bool? value) { - string field; - string Property { get; set; } - - string Test(bool? value) - { - return {|FixAllInDocument:value?.ToString()|}; - } - - string Test1(bool? value) - { - return value?.ToString(); - } - - string Test2(bool? value) - { - field = null; - Property = null; - return null; - } + return value?.ToString(); } - """, - """ - #nullable enable - class Program - { - string field; - string Property { get; set; } - string? Test(bool? value) - { - return value?.ToString(); - } - - string? Test1(bool? value) - { - return value?.ToString(); - } - - string Test2(bool? value) - { - field = null; - Property = null; - return null; - } + string? Test1(bool? value) + { + return value?.ToString(); } - """, parameters: s_nullableFeature); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39422")] - public async Task FixAllReturnType_Invocation() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + string Test2(bool? value) { - string field; - string Property { get; set; } - - void M(string value) - { - M({|FixAllInDocument:null|}); - } - void M2(string value) - { - M2(null); - } - string Test(bool? value) - { - return value?.ToString(); - } - string Test2(bool? value) - { - field = null; - Property = null; - return null; - } + field = null; + Property = null; + return null; } - """, - """ - #nullable enable - class Program - { - string? field; - string? Property { get; set; } + } + """, parameters: s_nullableFeature); + } - void M(string? value) - { - M(null); - } - void M2(string? value) - { - M2(null); - } - string Test(bool? value) - { - return value?.ToString(); - } - string Test2(bool? value) - { - field = null; - Property = null; - return null; - } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39422")] + public async Task FixAllReturnType_Invocation() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string field; + string Property { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39420")] - public async Task FixReturnType_TernaryExpression_Function() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + void M(string value) { - string Test(bool value) - { - return [|value ? "text" : null|]; - } + M({|FixAllInDocument:null|}); } - """, - """ - #nullable enable - class Program + void M2(string value) { - string? Test(bool value) - { - return value ? "text" : null; - } + M2(null); } - """, parameters: s_nullableFeature); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39423")] - public async Task FixReturnType_Default() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + string Test(bool? value) { - string Test() - { - return [|default|]; - } + return value?.ToString(); } - """, - """ - #nullable enable - class Program + string Test2(bool? value) { - string? Test() - { - return default; - } + field = null; + Property = null; + return null; } - """, parameters: s_nullableFeature); - } + } + """, + """ + #nullable enable + class Program + { + string? field; + string? Property { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39423")] - public async Task FixReturnType_DefaultWithNullableType() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + void M(string? value) { - string Test() - { - return [|default(string)|]; - } + M(null); } - """, - """ - #nullable enable - class Program + void M2(string? value) { - string? Test() - { - return default(string); - } + M2(null); } - """, parameters: s_nullableFeature); - } - - [Fact] - public async Task FixInvocation_NamedArgument() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program + string Test(bool? value) { - void M() - { - M2(x: [|null|]); - } - void M2(string x) { } + return value?.ToString(); } - """, - """ - #nullable enable - class Program + string Test2(bool? value) { - void M() - { - M2(x: null); - } - void M2(string? x) { } + field = null; + Property = null; + return null; } - """, parameters: s_nullableFeature); - } + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44338")] - public async Task NoFixInvocationOfExternalMethod_NamedArgument() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - void M() - { - var list = new System.Collections.Generic.List(); - list.Add(item: [|null|]); - } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39420")] + public async Task FixReturnType_TernaryExpression_Function() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string Test(bool value) + { + return [|value ? "text" : null|]; + } + } + """, + """ + #nullable enable + class Program + { + string? Test(bool value) + { + return value ? "text" : null; + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixInvocation_NamedArgument_OutOfOrder() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - void M() - { - M2(x: [|null|], i: 1); - } - void M2(int i, string x) { } - } - """, - """ - #nullable enable - class Program - { - void M() - { - M2(x: null, i: 1); - } - void M2(int i, string? x) { } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39423")] + public async Task FixReturnType_Default() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string Test() + { + return [|default|]; + } + } + """, + """ + #nullable enable + class Program + { + string? Test() + { + return default; + } + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44338")] - public async Task NoFixInvocationOfExternalMethod_NamedArgument_OutOfOrder() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - void M() - { - var dict = new System.Collections.Generic.Dictionary(); - dict.Add(value: 0, key: [|null|]); - } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39423")] + public async Task FixReturnType_DefaultWithNullableType() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + string Test() + { + return [|default(string)|]; + } + } + """, + """ + #nullable enable + class Program + { + string? Test() + { + return default(string); + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixInvocation_NamedArgument_Partial() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - partial class Program - { - void M() - { - M2(x: [|null|]); - } - partial void M2(string x); - partial void M2(string x) { } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixInvocation_NamedArgument() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + void M() + { + M2(x: [|null|]); + } + void M2(string x) { } + } + """, + """ + #nullable enable + class Program + { + void M() + { + M2(x: null); + } + void M2(string? x) { } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixInvocation_PositionArgument() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - void M() - { - M2([|null|]); - } - void M2(string x) { } - } - """, - """ - #nullable enable - class Program - { - void M() - { - M2(null); - } - void M2(string? x) { } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44338")] + public async Task NoFixInvocationOfExternalMethod_NamedArgument() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + void M() + { + var list = new System.Collections.Generic.List(); + list.Add(item: [|null|]); + } + } + """, parameters: s_nullableFeature); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44338")] - public async Task NoFixInvocationOfExternalMethod_PositionArgument() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - void M() - { - var list = new System.Collections.Generic.List(); - list.Add([|null|]); - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixInvocation_NamedArgument_OutOfOrder() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + void M() + { + M2(x: [|null|], i: 1); + } + void M2(int i, string x) { } + } + """, + """ + #nullable enable + class Program + { + void M() + { + M2(x: null, i: 1); + } + void M2(int i, string? x) { } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixInvocation_PositionArgument_SecondPosition() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - void M() - { - M2(1, [|null|]); - } - void M2(int i, string x) { } - } - """, - """ - #nullable enable - class Program - { - void M() - { - M2(1, null); - } - void M2(int i, string? x) { } - } - """, parameters: s_nullableFeature); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44338")] + public async Task NoFixInvocationOfExternalMethod_NamedArgument_OutOfOrder() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + void M() + { + var dict = new System.Collections.Generic.Dictionary(); + dict.Add(value: 0, key: [|null|]); + } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixInvocation_PositionArgument_Params() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - void M() - { - M2("", [|null|]); - } - void M2(params string[] x) { } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixInvocation_NamedArgument_Partial() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + partial class Program + { + void M() + { + M2(x: [|null|]); + } + partial void M2(string x); + partial void M2(string x) { } + } + """, parameters: s_nullableFeature); + } - [Fact] - public async Task FixInvocation_Indexer() - { - // Not supported yet - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - void M() - { - this[[|null|]]; - } - int this[string x] { get { throw null!; } set { throw null!; } } - } - """, parameters: s_nullableFeature); - } - - [Fact] - public async Task FixPropertyDeclaration_Unassigned() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - - class C - { - string [|S|] { get; } - } - """, - """ - #nullable enable - - class C - { - string? S { get; } - } - """, - parameters: s_nullableFeature); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44983")] - public async Task FixFieldDeclaration_Unassigned() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - - class C - { - private string [|_value|]; - } - """, - """ - #nullable enable - - class C - { - private string? _value; - } - """, - parameters: s_nullableFeature); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44983")] - public async Task MultipleDeclarator_NoDiagnostic() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable - class Program - { - string [|s|], s2 = "hello"; - } - """, parameters: s_nullableFeature); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46354")] - public async Task FixTupleFieldAssignment() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void F1((string, string?) t) - { - if (t.Item2 == null) return; - t.Item1 = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - static void F1((string?, string?) t) - { - if (t.Item2 == null) return; - t.Item1 = null; - } - } - """, parameters: s_nullableFeature); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46354")] - public async Task FixTupleNamedFieldAssignment() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void F1((string Foo, string? Bar) t) - { - if (t.Bar == null) return; - t.Foo = [|null|]; - } - } - """, - """ - #nullable enable - class Program - { - static void F1((string? Foo, string? Bar) t) - { - if (t.Bar == null) return; - t.Foo = null; - } - } - """, parameters: s_nullableFeature); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46354")] - public async Task FixTupleGenericFieldAssignment() - { - await TestInRegularAndScript1Async( - """ - #nullable enable - class Program - { - static void F1((T, T?) t) where T : class - { - if (t.Item2 == null) return; - t.Item1 = [|null|]; - - var (a, b) = t; - } - } - """, - """ - #nullable enable - class Program - { - static void F1((T?, T?) t) where T : class - { - if (t.Item2 == null) return; - t.Item1 = null; - - var (a, b) = t; - } - } - """, parameters: s_nullableFeature); - } + [Fact] + public async Task FixInvocation_PositionArgument() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + void M() + { + M2([|null|]); + } + void M2(string x) { } + } + """, + """ + #nullable enable + class Program + { + void M() + { + M2(null); + } + void M2(string? x) { } + } + """, parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44338")] + public async Task NoFixInvocationOfExternalMethod_PositionArgument() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + void M() + { + var list = new System.Collections.Generic.List(); + list.Add([|null|]); + } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixInvocation_PositionArgument_SecondPosition() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + void M() + { + M2(1, [|null|]); + } + void M2(int i, string x) { } + } + """, + """ + #nullable enable + class Program + { + void M() + { + M2(1, null); + } + void M2(int i, string? x) { } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixInvocation_PositionArgument_Params() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + void M() + { + M2("", [|null|]); + } + void M2(params string[] x) { } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixInvocation_Indexer() + { + // Not supported yet + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + void M() + { + this[[|null|]]; + } + int this[string x] { get { throw null!; } set { throw null!; } } + } + """, parameters: s_nullableFeature); + } + + [Fact] + public async Task FixPropertyDeclaration_Unassigned() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + + class C + { + string [|S|] { get; } + } + """, + """ + #nullable enable + + class C + { + string? S { get; } + } + """, + parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44983")] + public async Task FixFieldDeclaration_Unassigned() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + + class C + { + private string [|_value|]; + } + """, + """ + #nullable enable + + class C + { + private string? _value; + } + """, + parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44983")] + public async Task MultipleDeclarator_NoDiagnostic() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable + class Program + { + string [|s|], s2 = "hello"; + } + """, parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46354")] + public async Task FixTupleFieldAssignment() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void F1((string, string?) t) + { + if (t.Item2 == null) return; + t.Item1 = [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static void F1((string?, string?) t) + { + if (t.Item2 == null) return; + t.Item1 = null; + } + } + """, parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46354")] + public async Task FixTupleNamedFieldAssignment() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void F1((string Foo, string? Bar) t) + { + if (t.Bar == null) return; + t.Foo = [|null|]; + } + } + """, + """ + #nullable enable + class Program + { + static void F1((string? Foo, string? Bar) t) + { + if (t.Bar == null) return; + t.Foo = null; + } + } + """, parameters: s_nullableFeature); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46354")] + public async Task FixTupleGenericFieldAssignment() + { + await TestInRegularAndScript1Async( + """ + #nullable enable + class Program + { + static void F1((T, T?) t) where T : class + { + if (t.Item2 == null) return; + t.Item1 = [|null|]; + + var (a, b) = t; + } + } + """, + """ + #nullable enable + class Program + { + static void F1((T?, T?) t) where T : class + { + if (t.Item2 == null) return; + t.Item1 = null; + + var (a, b) = t; + } + } + """, parameters: s_nullableFeature); } } diff --git a/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersCompilerErrorTests.cs b/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersCompilerErrorTests.cs index 698589a73d760..9360507e4f262 100644 --- a/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersCompilerErrorTests.cs +++ b/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersCompilerErrorTests.cs @@ -12,26 +12,25 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.OrderModifiers +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.OrderModifiers; + +public sealed class OrderModifiersCompilerErrorTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - public sealed class OrderModifiersCompilerErrorTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public OrderModifiersCompilerErrorTests(ITestOutputHelper logger) + : base(logger) { - public OrderModifiersCompilerErrorTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpOrderModifiersCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpOrderModifiersCodeFixProvider()); - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsOrderModifiers)] - [WorkItem("https://github.com/dotnet/roslyn/issues/30352")] - public async Task PartialAtTheEnd() - { - // Verify that the code fix claims it fixes the compiler error (CS0267) in addition to the analyzer diagnostic. - await TestInRegularAndScript1Async( + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsOrderModifiers)] + [WorkItem("https://github.com/dotnet/roslyn/issues/30352")] + public async Task PartialAtTheEnd() + { + // Verify that the code fix claims it fixes the compiler error (CS0267) in addition to the analyzer diagnostic. + await TestInRegularAndScript1Async( @"[|partial|] public class C { }", @"public partial class C { }"); - } } } diff --git a/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersTests.cs b/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersTests.cs index db781400d388b..626e1f7038727 100644 --- a/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersTests.cs +++ b/src/Analyzers/CSharp/Tests/OrderModifiers/OrderModifiersTests.cs @@ -12,551 +12,550 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.OrderModifiers +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.OrderModifiers; + +[Trait(Traits.Feature, Traits.Features.CodeActionsOrderModifiers)] +public class OrderModifiersTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsOrderModifiers)] - public class OrderModifiersTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor - { - public OrderModifiersTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpOrderModifiersDiagnosticAnalyzer(), new CSharpOrderModifiersCodeFixProvider()); - - [Fact] - public async Task TestClass() - { - await TestInRegularAndScript1Async( - """ - [|static|] internal class C - { - } - """, - """ - internal static class C - { - } - """); - } - - [Fact] - public async Task TestStruct() - { - await TestInRegularAndScript1Async( - """ - [|unsafe|] public struct C - { - } - """, - """ - public unsafe struct C - { - } - """); - } - - [Fact] - public async Task TestInterface() - { - await TestInRegularAndScript1Async( - """ - [|unsafe|] public interface C - { - } - """, - """ - public unsafe interface C - { - } - """); - } - - [Fact] - public async Task TestEnum() - { - await TestInRegularAndScript1Async( - """ - [|internal|] protected enum C - { - } - """, - """ - protected internal enum C - { - } - """); - } - - [Fact] - public async Task TestDelegate() - { - await TestInRegularAndScript1Async( - @"[|unsafe|] public delegate void D();", - @"public unsafe delegate void D();"); - } - - [Fact] - public async Task TestMethod() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|unsafe|] public void M() { } - } - """, - """ - class C - { - public unsafe void M() { } - } - """); - } - - [Fact] - public async Task TestField() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|unsafe|] public int a; - } - """, - """ - class C - { - public unsafe int a; - } - """); - } - - [Fact] - public async Task TestConstructor() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|unsafe|] public C() { } - } - """, - """ - class C - { - public unsafe C() { } - } - """); - } - - [Fact] - public async Task TestProperty() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|unsafe|] public int P { get; } - } - """, - """ - class C - { - public unsafe int P { get; } - } - """); - } - - [Fact] - public async Task TestAccessor() - { - await TestInRegularAndScript1Async( - """ - class C - { - int P { [|internal|] protected get; } - } - """, - """ - class C - { - int P { protected internal get; } - } - """); - } - - [Fact] - public async Task TestPropertyEvent() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|internal|] protected event Action P { add { } remove { } } - } - """, - """ - class C - { - protected internal event Action P { add { } remove { } } - } - """); - } - - [Fact] - public async Task TestFieldEvent() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|internal|] protected event Action P; - } - """, - """ - class C - { - protected internal event Action P; - } - """); - } - - [Fact] - public async Task TestOperator() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|static|] public C operator +(C c1, C c2) { } - } - """, - """ - class C - { - public static C operator +(C c1, C c2) { } - } - """); - } - - [Fact] - public async Task TestConversionOperator() - { - await TestInRegularAndScript1Async( - """ - class C - { - [|static|] public implicit operator bool(C c1) { } - } - """, - """ - class C - { - public static implicit operator bool(C c1) { } - } - """); - } - - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - {|FixAllInDocument:static|} internal class C - { - static internal class Nested { } - } - """, - """ - internal static class C - { - internal static class Nested { } - } - """); - } - - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScript1Async( - """ - static internal class C - { - {|FixAllInDocument:static|} internal class Nested { } - } - """, - """ - internal static class C - { - internal static class Nested { } - } - """); - } - - [Fact] - public async Task TestTrivia1() - { - await TestInRegularAndScript1Async( - """ - /// Doc comment - [|static|] internal class C - { - } - """, - """ - /// Doc comment - internal static class C - { - } - """); - } - - [Fact] - public async Task TestTrivia2() - { - await TestInRegularAndScript1Async( - """ - /* start */ [|static|] /* middle */ internal /* end */ class C - { - } - """, - """ - /* start */ internal /* middle */ static /* end */ class C - { - } - """); - } - - [Fact] - public async Task TestTrivia3() - { - await TestInRegularAndScript1Async( - """ - #if true - [|static|] internal class C - { - } - #endif - """, - """ - #if true - internal static class C - { - } - #endif - """); - } - - [Fact] - public async Task PartialAtTheEndClass1() - { - await TestInRegularAndScript1Async( + public OrderModifiersTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpOrderModifiersDiagnosticAnalyzer(), new CSharpOrderModifiersCodeFixProvider()); + + [Fact] + public async Task TestClass() + { + await TestInRegularAndScript1Async( + """ + [|static|] internal class C + { + } + """, + """ + internal static class C + { + } + """); + } + + [Fact] + public async Task TestStruct() + { + await TestInRegularAndScript1Async( + """ + [|unsafe|] public struct C + { + } + """, + """ + public unsafe struct C + { + } + """); + } + + [Fact] + public async Task TestInterface() + { + await TestInRegularAndScript1Async( + """ + [|unsafe|] public interface C + { + } + """, + """ + public unsafe interface C + { + } + """); + } + + [Fact] + public async Task TestEnum() + { + await TestInRegularAndScript1Async( + """ + [|internal|] protected enum C + { + } + """, + """ + protected internal enum C + { + } + """); + } + + [Fact] + public async Task TestDelegate() + { + await TestInRegularAndScript1Async( + @"[|unsafe|] public delegate void D();", + @"public unsafe delegate void D();"); + } + + [Fact] + public async Task TestMethod() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|unsafe|] public void M() { } + } + """, + """ + class C + { + public unsafe void M() { } + } + """); + } + + [Fact] + public async Task TestField() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|unsafe|] public int a; + } + """, + """ + class C + { + public unsafe int a; + } + """); + } + + [Fact] + public async Task TestConstructor() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|unsafe|] public C() { } + } + """, + """ + class C + { + public unsafe C() { } + } + """); + } + + [Fact] + public async Task TestProperty() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|unsafe|] public int P { get; } + } + """, + """ + class C + { + public unsafe int P { get; } + } + """); + } + + [Fact] + public async Task TestAccessor() + { + await TestInRegularAndScript1Async( + """ + class C + { + int P { [|internal|] protected get; } + } + """, + """ + class C + { + int P { protected internal get; } + } + """); + } + + [Fact] + public async Task TestPropertyEvent() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|internal|] protected event Action P { add { } remove { } } + } + """, + """ + class C + { + protected internal event Action P { add { } remove { } } + } + """); + } + + [Fact] + public async Task TestFieldEvent() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|internal|] protected event Action P; + } + """, + """ + class C + { + protected internal event Action P; + } + """); + } + + [Fact] + public async Task TestOperator() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|static|] public C operator +(C c1, C c2) { } + } + """, + """ + class C + { + public static C operator +(C c1, C c2) { } + } + """); + } + + [Fact] + public async Task TestConversionOperator() + { + await TestInRegularAndScript1Async( + """ + class C + { + [|static|] public implicit operator bool(C c1) { } + } + """, + """ + class C + { + public static implicit operator bool(C c1) { } + } + """); + } + + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + {|FixAllInDocument:static|} internal class C + { + static internal class Nested { } + } + """, + """ + internal static class C + { + internal static class Nested { } + } + """); + } + + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScript1Async( + """ + static internal class C + { + {|FixAllInDocument:static|} internal class Nested { } + } + """, + """ + internal static class C + { + internal static class Nested { } + } + """); + } + + [Fact] + public async Task TestTrivia1() + { + await TestInRegularAndScript1Async( + """ + /// Doc comment + [|static|] internal class C + { + } + """, + """ + /// Doc comment + internal static class C + { + } + """); + } + + [Fact] + public async Task TestTrivia2() + { + await TestInRegularAndScript1Async( + """ + /* start */ [|static|] /* middle */ internal /* end */ class C + { + } + """, + """ + /* start */ internal /* middle */ static /* end */ class C + { + } + """); + } + + [Fact] + public async Task TestTrivia3() + { + await TestInRegularAndScript1Async( + """ + #if true + [|static|] internal class C + { + } + #endif + """, + """ + #if true + internal static class C + { + } + #endif + """); + } + + [Fact] + public async Task PartialAtTheEndClass1() + { + await TestInRegularAndScript1Async( @"[|partial|] public class C { }", @"public partial class C { }"); - } - - [Fact] - public async Task PartialAtTheEndClass2() - { - await TestInRegularAndScript1Async( - @"[|partial|] abstract class C { }", - @"abstract partial class C { }"); - } - - [Fact] - public async Task PartialAtTheEndClass3() - { - await TestInRegularAndScript1Async( - @"[|partial|] sealed class C { }", - @"sealed partial class C { }"); - } - - [Fact] - public async Task PartialAtTheEndClass4() - { - await TestInRegularAndScript1Async( - @"[|partial|] static class C { }", - @"static partial class C { }"); - } - - [Fact] - public async Task PartialAtTheEndClass5() - { - await TestInRegularAndScript1Async( - @"[|partial|] unsafe class C { }", - @"unsafe partial class C { }"); - } - - [Fact] - public async Task PartialAtTheEndStruct1() - { - await TestInRegularAndScript1Async( - @"[|partial|] public struct S { }", - @"public partial struct S { }"); - } - - [Fact] - public async Task PartialAtTheEndStruct2() - { - await TestInRegularAndScript1Async( - @"[|partial|] unsafe struct S { }", - @"unsafe partial struct S { }"); - } - - [Fact] - public async Task PartialAtTheEndInterface() - { - await TestInRegularAndScript1Async( - @"[|partial|] public interface I { }", - @"public partial interface I { }"); - } - - [Fact] - public async Task PartialAtTheEndMethod1() - { - await TestInRegularAndScript1Async( - """ - partial class C - { - [|partial|] static void M(); - } - """, - """ - partial class C - { - static partial void M(); - } - """); - } - - [Fact] - public async Task PartialAtTheEndMethod2() - { - await TestInRegularAndScript1Async( - """ - partial class C - { - [|partial|] unsafe void M(); - } - """, - """ - partial class C - { - unsafe partial void M(); - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/52297")] - public async Task TestInLocalFunction() - { - // Not handled for performance reason. - await TestMissingInRegularAndScriptAsync( - """ - class C - { - public static async void M() - { - [|async|] static void Local() { } - } - } - """); - } - - [Fact] - public async Task TestFixAllInContainingMember_NotApplicable() - { - await TestMissingInRegularAndScriptAsync( - """ - {|FixAllInContainingMember:static|} internal class C - { - static internal class Nested { } - } + } - static internal class C2 - { - static internal class Nested { } - } - """); - } - - [Fact] - public async Task TestFixAllInContainingType() - { - await TestInRegularAndScript1Async( - """ - {|FixAllInContainingType:static|} internal class C - { - static internal class Nested { } - } + [Fact] + public async Task PartialAtTheEndClass2() + { + await TestInRegularAndScript1Async( + @"[|partial|] abstract class C { }", + @"abstract partial class C { }"); + } - static internal class C2 - { - static internal class Nested { } - } - """, - """ - internal static class C - { - internal static class Nested { } - } + [Fact] + public async Task PartialAtTheEndClass3() + { + await TestInRegularAndScript1Async( + @"[|partial|] sealed class C { }", + @"sealed partial class C { }"); + } - static internal class C2 - { - static internal class Nested { } - } - """); - } - - [Fact] - public async Task RequiredAfterAllOnProp() - { - await TestInRegularAndScriptAsync(""" - class C - { - [|required|] public virtual unsafe int Prop { get; init; } - } - """, - """ - class C - { - public virtual unsafe required int Prop { get; init; } - } - """); - } - - [Fact] - public async Task RequiredAfterAllButVolatileOnField() - { - await TestInRegularAndScriptAsync(""" - class C - { - [|required|] public unsafe volatile int Field; - } - """, - """ - class C - { - public unsafe required volatile int Field; - } - """); - } - - [Fact] - public async Task TestFileClass() - { - await TestInRegularAndScriptAsync(""" - [|abstract file|] class C - { - } - """, - """ - file abstract class C + [Fact] + public async Task PartialAtTheEndClass4() + { + await TestInRegularAndScript1Async( + @"[|partial|] static class C { }", + @"static partial class C { }"); + } + + [Fact] + public async Task PartialAtTheEndClass5() + { + await TestInRegularAndScript1Async( + @"[|partial|] unsafe class C { }", + @"unsafe partial class C { }"); + } + + [Fact] + public async Task PartialAtTheEndStruct1() + { + await TestInRegularAndScript1Async( + @"[|partial|] public struct S { }", + @"public partial struct S { }"); + } + + [Fact] + public async Task PartialAtTheEndStruct2() + { + await TestInRegularAndScript1Async( + @"[|partial|] unsafe struct S { }", + @"unsafe partial struct S { }"); + } + + [Fact] + public async Task PartialAtTheEndInterface() + { + await TestInRegularAndScript1Async( + @"[|partial|] public interface I { }", + @"public partial interface I { }"); + } + + [Fact] + public async Task PartialAtTheEndMethod1() + { + await TestInRegularAndScript1Async( + """ + partial class C + { + [|partial|] static void M(); + } + """, + """ + partial class C + { + static partial void M(); + } + """); + } + + [Fact] + public async Task PartialAtTheEndMethod2() + { + await TestInRegularAndScript1Async( + """ + partial class C + { + [|partial|] unsafe void M(); + } + """, + """ + partial class C + { + unsafe partial void M(); + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/52297")] + public async Task TestInLocalFunction() + { + // Not handled for performance reason. + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public static async void M() { + [|async|] static void Local() { } } - """); - } + } + """); + } + + [Fact] + public async Task TestFixAllInContainingMember_NotApplicable() + { + await TestMissingInRegularAndScriptAsync( + """ + {|FixAllInContainingMember:static|} internal class C + { + static internal class Nested { } + } + + static internal class C2 + { + static internal class Nested { } + } + """); + } + + [Fact] + public async Task TestFixAllInContainingType() + { + await TestInRegularAndScript1Async( + """ + {|FixAllInContainingType:static|} internal class C + { + static internal class Nested { } + } + + static internal class C2 + { + static internal class Nested { } + } + """, + """ + internal static class C + { + internal static class Nested { } + } + + static internal class C2 + { + static internal class Nested { } + } + """); + } + + [Fact] + public async Task RequiredAfterAllOnProp() + { + await TestInRegularAndScriptAsync(""" + class C + { + [|required|] public virtual unsafe int Prop { get; init; } + } + """, + """ + class C + { + public virtual unsafe required int Prop { get; init; } + } + """); + } + + [Fact] + public async Task RequiredAfterAllButVolatileOnField() + { + await TestInRegularAndScriptAsync(""" + class C + { + [|required|] public unsafe volatile int Field; + } + """, + """ + class C + { + public unsafe required volatile int Field; + } + """); + } + + [Fact] + public async Task TestFileClass() + { + await TestInRegularAndScriptAsync(""" + [|abstract file|] class C + { + } + """, + """ + file abstract class C + { + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests.cs b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests.cs index 85275d0820a53..d2bb6dddf6e42 100644 --- a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests.cs @@ -12,941 +12,804 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch; + +[Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] +public partial class PopulateSwitchExpressionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] - public partial class PopulateSwitchExpressionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public PopulateSwitchExpressionTests(ITestOutputHelper logger) + : base(logger) { - public PopulateSwitchExpressionTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpPopulateSwitchExpressionDiagnosticAnalyzer(), new CSharpPopulateSwitchExpressionCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpPopulateSwitchExpressionDiagnosticAnalyzer(), new CSharpPopulateSwitchExpressionCodeFixProvider()); - [Fact] - public async Task NotOnRangeToken() - { - await TestMissingInRegularAndScriptAsync( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NotOnRangeToken() + { + await TestMissingInRegularAndScriptAsync( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = [||]e switch { - var e = MyEnum.Fizz; - _ = [||]e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - _ => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + _ => 3, + }; } } - """); - } + } + """); + } - [Fact] - public async Task AllMembersAndDefaultExist() - { - await TestMissingInRegularAndScriptAsync( - """ - namespace ConsoleApplication1 + [Fact] + public async Task AllMembersAndDefaultExist() + { + await TestMissingInRegularAndScriptAsync( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => 4, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => 4, + }; } } - """); - } + } + """); + } - [Fact] - public async Task AllMembersExist_NotDefault() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task AllMembersExist_NotDefault() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - """); - } + } + """); + } - [Fact] - public async Task AllMembersExist_NotDefault_NoComma() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task AllMembersExist_NotDefault_NoComma() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3 - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3 + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => throw new System.NotImplementedException() - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => throw new System.NotImplementedException() + }; } } - """); - } + } + """); + } - [Fact] - public async Task NotAllMembersExist_NotDefault() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NotAllMembersExist_NotDefault() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => throw new System.NotImplementedException(), + }; } } - """, index: 2); - } + } + """, index: 2); + } - [Fact] - public async Task NotAllMembersExist_WithDefault() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NotAllMembersExist_WithDefault() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - _ => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + _ => 3, + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => 3, + }; } } - """); - } + } + """); + } - [Fact] - public async Task NotAllMembersExist_NotDefault_EnumHasExplicitType() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NotAllMembersExist_NotDefault_EnumHasExplicitType() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum : long { - enum MyEnum : long - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum : long { - enum MyEnum : long - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => throw new System.NotImplementedException(), + }; } } - """, index: 2); - } + } + """, index: 2); + } - [Fact] - public async Task NotAllMembersExist_WithMembersAndDefaultInSection_NewValuesAboveDefaultSection() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NotAllMembersExist_WithMembersAndDefaultInSection_NewValuesAboveDefaultSection() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - _ => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + _ => 3, + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => 3, + }; } } - """); - } + } + """); + } - [Fact] - public async Task NotAllMembersExist_WithMembersAndDefaultInSection_AssumesDefaultIsInLastSection() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NotAllMembersExist_WithMembersAndDefaultInSection_AssumesDefaultIsInLastSection() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - _ => 1, - MyEnum.Fizz => 2, - MyEnum.Buzz => 3, - }; - } + _ => 1, + MyEnum.Fizz => 2, + MyEnum.Buzz => 3, + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - _ => 1, - MyEnum.Fizz => 2, - MyEnum.Buzz => 3, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - }; - } + _ => 1, + MyEnum.Fizz => 2, + MyEnum.Buzz => 3, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + }; } } - """); - } + } + """); + } - [Fact] - public async Task NoMembersExist0() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NoMembersExist0() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - }; - } + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => throw new System.NotImplementedException(), - MyEnum.Buzz => throw new System.NotImplementedException(), - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => throw new System.NotImplementedException(), + MyEnum.Buzz => throw new System.NotImplementedException(), + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + }; } } - """, index: 0); - } + } + """, index: 0); + } - [Fact] - public async Task NoMembersExist1() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NoMembersExist1() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - }; - } + }; } } - """, - """ - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - _ => throw new System.NotImplementedException(), - }; - } + _ => throw new System.NotImplementedException(), + }; } } - """, index: 1); - } + } + """, index: 1); + } - [Fact] - public async Task NoMembersExist2() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + [Fact] + public async Task NoMembersExist2() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + Fizz, + Buzz, + FizzBuzz + } - class MyClass + class MyClass + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - }; - } + }; } } - """, - """ - namespace ConsoleApplication1 - { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } - - class MyClass - { - void Method() - { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => throw new System.NotImplementedException(), - MyEnum.Buzz => throw new System.NotImplementedException(), - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => throw new System.NotImplementedException(), - }; - } - } - } - """, index: 2); - } - - [Fact] - public async Task UsingStaticEnum_AllMembersExist() - { - await TestMissingInRegularAndScriptAsync( - """ - using static System.IO.FileMode; - - namespace ConsoleApplication1 + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum { - class MyClass - { - void Method() - { - var e = Append; - _ = e [||]switch - { - CreateNew => 1, - Create => 2, - Open => 3, - OpenOrCreate => 4, - Truncate => 5, - Append => 6, - _ => 7, - }; - } - } + Fizz, + Buzz, + FizzBuzz } - """); - } - - [Fact] - public async Task UsingStaticEnum_AllMembersExist_OutOfDefaultOrder() - { - await TestMissingInRegularAndScriptAsync( - """ - using static System.IO.FileMode; - namespace ConsoleApplication1 + class MyClass { - class MyClass + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e [||]switch { - var e = Append; - _ = e [||]switch - { - CreateNew => 1, - OpenOrCreate => 2, - Truncate => 3, - Open => 4, - Append => 5, - Create => 6, - _ => 7, - }; - } + MyEnum.Fizz => throw new System.NotImplementedException(), + MyEnum.Buzz => throw new System.NotImplementedException(), + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => throw new System.NotImplementedException(), + }; } } - """); - } - - [Fact] - public async Task UsingStaticEnum_MembersExist() - { - await TestInRegularAndScript1Async( - """ - using static System.IO.FileMode; + } + """, index: 2); + } - namespace ConsoleApplication1 - { - class MyClass - { - void Method() - { - var e = Append; - _ = e [||]switch - { - CreateNew => 1, - Create => 2, - Open => 3, - OpenOrCreate => 4, - _ => 5, - }; - } - } - } - """, - """ - using static System.IO.FileMode; + [Fact] + public async Task UsingStaticEnum_AllMembersExist() + { + await TestMissingInRegularAndScriptAsync( + """ + using static System.IO.FileMode; - namespace ConsoleApplication1 + namespace ConsoleApplication1 + { + class MyClass { - class MyClass + void Method() { - void Method() + var e = Append; + _ = e [||]switch { - var e = Append; - _ = e switch - { - CreateNew => 1, - Create => 2, - Open => 3, - OpenOrCreate => 4, - Truncate => throw new System.NotImplementedException(), - Append => throw new System.NotImplementedException(), - _ => 5, - }; - } + CreateNew => 1, + Create => 2, + Open => 3, + OpenOrCreate => 4, + Truncate => 5, + Append => 6, + _ => 7, + }; } } - """); - } + } + """); + } - [Fact] - public async Task UsingStaticEnum_NoMembersExist() - { - await TestInRegularAndScript1Async( - """ - using static System.IO.FileMode; + [Fact] + public async Task UsingStaticEnum_AllMembersExist_OutOfDefaultOrder() + { + await TestMissingInRegularAndScriptAsync( + """ + using static System.IO.FileMode; - namespace ConsoleApplication1 + namespace ConsoleApplication1 + { + class MyClass { - class MyClass + void Method() { - void Method() + var e = Append; + _ = e [||]switch { - var e = Append; - _ = e [||]switch - { - }; - } + CreateNew => 1, + OpenOrCreate => 2, + Truncate => 3, + Open => 4, + Append => 5, + Create => 6, + _ => 7, + }; } } - """, - """ - using static System.IO.FileMode; + } + """); + } - namespace ConsoleApplication1 - { - class MyClass - { - void Method() - { - var e = Append; - _ = e switch - { - CreateNew => throw new System.NotImplementedException(), - Create => throw new System.NotImplementedException(), - Open => throw new System.NotImplementedException(), - OpenOrCreate => throw new System.NotImplementedException(), - Truncate => throw new System.NotImplementedException(), - Append => throw new System.NotImplementedException(), - _ => throw new System.NotImplementedException(), - }; - } - } - } - """, index: 2); - } + [Fact] + public async Task UsingStaticEnum_MembersExist() + { + await TestInRegularAndScript1Async( + """ + using static System.IO.FileMode; - [Fact] - public async Task NotAllMembersExist_NotDefault_EnumHasNonFlagsAttribute() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 + namespace ConsoleApplication1 + { + class MyClass { - [System.Obsolete] - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } - - class MyClass + void Method() { - void Method() + var e = Append; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - }; - } + CreateNew => 1, + Create => 2, + Open => 3, + OpenOrCreate => 4, + _ => 5, + }; } } - """, - """ - namespace ConsoleApplication1 - { - [System.Obsolete] - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + } + """, + """ + using static System.IO.FileMode; - class MyClass + namespace ConsoleApplication1 + { + class MyClass + { + void Method() { - void Method() + var e = Append; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => throw new System.NotImplementedException(), - }; - } + CreateNew => 1, + Create => 2, + Open => 3, + OpenOrCreate => 4, + Truncate => throw new System.NotImplementedException(), + Append => throw new System.NotImplementedException(), + _ => 5, + }; } } - """, index: 2); - } + } + """); + } - [Fact] - public async Task NotAllMembersExist_NotDefault_EnumIsNested() - { - await TestInRegularAndScript1Async( - """ - namespace ConsoleApplication1 - { - class MyClass - { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + [Fact] + public async Task UsingStaticEnum_NoMembersExist() + { + await TestInRegularAndScript1Async( + """ + using static System.IO.FileMode; - void Method() - { - var e = MyEnum.Fizz; - _ = e [||]switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - }; - } - } - } - """, - """ - namespace ConsoleApplication1 + namespace ConsoleApplication1 + { + class MyClass { - class MyClass + void Method() { - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } - - void Method() + var e = Append; + _ = e [||]switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => throw new System.NotImplementedException(), - _ => throw new System.NotImplementedException(), - }; - } + }; } } - """, index: 2); - } - - [Fact] - public async Task NotAllMembersExist_SwitchIsNotEnum() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using static System.IO.FileMode; - namespace ConsoleApplication1 + namespace ConsoleApplication1 + { + class MyClass { - class MyClass + void Method() { - void Method() + var e = Append; + _ = e switch { - var e = "test"; - _ = e [||]switch - { - "test1" => 1, - "test2" => 2, - _ => 3, - } - } + CreateNew => throw new System.NotImplementedException(), + Create => throw new System.NotImplementedException(), + Open => throw new System.NotImplementedException(), + OpenOrCreate => throw new System.NotImplementedException(), + Truncate => throw new System.NotImplementedException(), + Append => throw new System.NotImplementedException(), + _ => throw new System.NotImplementedException(), + }; } } - """); - } + } + """, index: 2); + } - [Fact] - public async Task NotAllMembersExist_NotDefault_UsingConstants() - { - await TestInRegularAndScript1Async( - """ + [Fact] + public async Task NotAllMembersExist_NotDefault_EnumHasNonFlagsAttribute() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { + [System.Obsolete] enum MyEnum { Fizz, @@ -961,13 +824,17 @@ void Method() var e = MyEnum.Fizz; _ = e [||]switch { - (MyEnum)0 => 1, - (MyEnum)1 => 2, - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + }; } } - """, - """ + } + """, + """ + namespace ConsoleApplication1 + { + [System.Obsolete] enum MyEnum { Fizz, @@ -982,90 +849,132 @@ void Method() var e = MyEnum.Fizz; _ = e switch { - (MyEnum)0 => 1, - (MyEnum)1 => 2, + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, MyEnum.FizzBuzz => throw new System.NotImplementedException(), _ => throw new System.NotImplementedException(), - } + }; } } - """, index: 2); - } - - [Fact] - public async Task NotAllMembersExist_NotDefault_WithMismatchingConstantType() - { - await TestInRegularAndScript1Async( - """ - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } + } + """, index: 2); + } + [Fact] + public async Task NotAllMembersExist_NotDefault_EnumIsNested() + { + await TestInRegularAndScript1Async( + """ + namespace ConsoleApplication1 + { class MyClass { + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz + } + void Method() { var e = MyEnum.Fizz; _ = e [||]switch { - (MyEnum)0 => 1, - (MyEnum)1 => 2, - "Mismatching constant" => 3, - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + }; } } - """, - """ - enum MyEnum - { - Fizz, - Buzz, - FizzBuzz - } - + } + """, + """ + namespace ConsoleApplication1 + { class MyClass { + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz + } + void Method() { var e = MyEnum.Fizz; _ = e switch { - (MyEnum)0 => 1, - (MyEnum)1 => 2, - "Mismatching constant" => 3, + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => throw new System.NotImplementedException(), + }; + } + } + } + """, index: 2); + } + + [Fact] + public async Task NotAllMembersExist_SwitchIsNotEnum() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + namespace ConsoleApplication1 + { + class MyClass + { + void Method() + { + var e = "test"; + _ = e [||]switch + { + "test1" => 1, + "test2" => 2, + _ => 3, } } } - """); - } + } + """); + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/40399")] - public async Task AllMissingTokens() - { - await TestInRegularAndScript1Async( + [Fact] + public async Task NotAllMembersExist_NotDefault_UsingConstants() + { + await TestInRegularAndScript1Async( """ enum MyEnum { - Fizz + Fizz, + Buzz, + FizzBuzz } + class MyClass { void Method() { var e = MyEnum.Fizz; _ = e [||]switch + { + (MyEnum)0 => 1, + (MyEnum)1 => 2, + } } } """, """ enum MyEnum { - Fizz + Fizz, + Buzz, + FizzBuzz } + class MyClass { void Method() @@ -1073,648 +982,738 @@ void Method() var e = MyEnum.Fizz; _ = e switch { - MyEnum.Fizz => throw new System.NotImplementedException(), - }; + (MyEnum)0 => 1, + (MyEnum)1 => 2, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), + _ => throw new System.NotImplementedException(), + } } } - """); - } + """, index: 2); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40240")] - public async Task TestAddMissingCasesForNullableEnum() - { - await TestInRegularAndScript1Async( - """ - public class Program + [Fact] + public async Task NotAllMembersExist_NotDefault_WithMismatchingConstantType() + { + await TestInRegularAndScript1Async( + """ + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz + } + + class MyClass + { + void Method() { - void Main() + var e = MyEnum.Fizz; + _ = e [||]switch { - var bar = Bar.Option1; - var b = bar [||]switch - { - Bar.Option1 => 1, - Bar.Option2 => 2, - null => null, - }; + (MyEnum)0 => 1, + (MyEnum)1 => 2, + "Mismatching constant" => 3, } - - public enum Bar - { - Option1, - Option2, - Option3, - } } - """, - """ - public class Program + } + """, + """ + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz + } + + class MyClass + { + void Method() { - void Main() + var e = MyEnum.Fizz; + _ = e switch { - var bar = Bar.Option1; - var b = bar switch - { - Bar.Option1 => 1, - Bar.Option2 => 2, - null => null, - Bar.Option3 => throw new System.NotImplementedException(), - }; + (MyEnum)0 => 1, + (MyEnum)1 => 2, + "Mismatching constant" => 3, + MyEnum.FizzBuzz => throw new System.NotImplementedException(), } + } + } + """); + } - public enum Bar + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/40399")] + public async Task AllMissingTokens() + { + await TestInRegularAndScript1Async( + """ + enum MyEnum + { + Fizz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + _ = e [||]switch + } + } + """, + """ + enum MyEnum + { + Fizz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + _ = e switch { - Option1, - Option2, - Option3, - } - } - """); + MyEnum.Fizz => throw new System.NotImplementedException(), + }; + } } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] - public async Task TestOrPatternIsHandled() - { - await TestInRegularAndScript1Async( - """ - public static class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40240")] + public async Task TestAddMissingCasesForNullableEnum() + { + await TestInRegularAndScript1Async( + """ + public class Program + { + void Main() { - static bool IsValidValue(E e) + var bar = Bar.Option1; + var b = bar [||]switch { - return e [||]switch - { - E.A or E.B or E.C => true, - _ = false - }; - } + Bar.Option1 => 1, + Bar.Option2 => 2, + null => null, + }; + } - public enum E + public enum Bar + { + Option1, + Option2, + Option3, + } + } + """, + """ + public class Program + { + void Main() + { + var bar = Bar.Option1; + var b = bar switch { - A, - B, - C, - D, - E, - F, - G, - } + Bar.Option1 => 1, + Bar.Option2 => 2, + null => null, + Bar.Option3 => throw new System.NotImplementedException(), + }; } - """, - """ - public static class C + + public enum Bar + { + Option1, + Option2, + Option3, + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] + public async Task TestOrPatternIsHandled() + { + await TestInRegularAndScript1Async( + """ + public static class C + { + static bool IsValidValue(E e) { - static bool IsValidValue(E e) + return e [||]switch { - return e [||]switch - { - E.A or E.B or E.C => true, - E.D => throw new System.NotImplementedException(), - E.E => throw new System.NotImplementedException(), - E.F => throw new System.NotImplementedException(), - E.G => throw new System.NotImplementedException(), - _ = false - }; - } + E.A or E.B or E.C => true, + _ = false + }; + } - public enum E + public enum E + { + A, + B, + C, + D, + E, + F, + G, + } + } + """, + """ + public static class C + { + static bool IsValidValue(E e) + { + return e [||]switch { - A, - B, - C, - D, - E, - F, - G, - } + E.A or E.B or E.C => true, + E.D => throw new System.NotImplementedException(), + E.E => throw new System.NotImplementedException(), + E.F => throw new System.NotImplementedException(), + E.G => throw new System.NotImplementedException(), + _ = false + }; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] - public async Task TestOrPatternIsHandled_AllEnumValuesAreHandled_NoDiagnostic() - { - await TestMissingInRegularAndScriptAsync( - """ - public static class C + public enum E { - static bool IsValidValue(E e) - { - return e [||]switch - { - (E.A or E.B) or (E.C or E.D) => true, - (E.E or E.F) or (E.G) => true, - _ = false - }; - } + A, + B, + C, + D, + E, + F, + G, + } + } + """); + } - public enum E + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] + public async Task TestOrPatternIsHandled_AllEnumValuesAreHandled_NoDiagnostic() + { + await TestMissingInRegularAndScriptAsync( + """ + public static class C + { + static bool IsValidValue(E e) + { + return e [||]switch { - A, - B, - C, - D, - E, - F, - G, - } + (E.A or E.B) or (E.C or E.D) => true, + (E.E or E.F) or (E.G) => true, + _ = false + }; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] - public async Task TestMixingOrWithAndPatterns() - { - await TestInRegularAndScript1Async( - """ - public static class C + public enum E { - static bool M(E e) - { - return e [||]switch - { - (E.A or E.B) and (E.C or E.D) => true, - _ = false - }; - } + A, + B, + C, + D, + E, + F, + G, + } + } + """); + } - public enum E + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] + public async Task TestMixingOrWithAndPatterns() + { + await TestInRegularAndScript1Async( + """ + public static class C + { + static bool M(E e) + { + return e [||]switch { - A, - B, - C, - D, - E, - F, - G, - } + (E.A or E.B) and (E.C or E.D) => true, + _ = false + }; } - """, - """ - public static class C + + public enum E { - static bool M(E e) - { - return e [||]switch - { - (E.A or E.B) and (E.C or E.D) => true, - E.A => throw new System.NotImplementedException(), - E.B => throw new System.NotImplementedException(), - E.C => throw new System.NotImplementedException(), - E.D => throw new System.NotImplementedException(), - E.E => throw new System.NotImplementedException(), - E.F => throw new System.NotImplementedException(), - E.G => throw new System.NotImplementedException(), - _ = false - }; - } + A, + B, + C, + D, + E, + F, + G, + } + } + """, + """ + public static class C + { + static bool M(E e) + { + return e [||]switch + { + (E.A or E.B) and (E.C or E.D) => true, + E.A => throw new System.NotImplementedException(), + E.B => throw new System.NotImplementedException(), + E.C => throw new System.NotImplementedException(), + E.D => throw new System.NotImplementedException(), + E.E => throw new System.NotImplementedException(), + E.F => throw new System.NotImplementedException(), + E.G => throw new System.NotImplementedException(), + _ = false + }; + } - public enum E - { - A, - B, - C, - D, - E, - F, - G, - } + public enum E + { + A, + B, + C, + D, + E, + F, + G, } - """ + } + """ ); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] - public async Task TestMixingOrWithAndPatterns2() - { - await TestInRegularAndScript1Async( - """ - public static class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50982")] + public async Task TestMixingOrWithAndPatterns2() + { + await TestInRegularAndScript1Async( + """ + public static class C + { + static bool M(E e) { - static bool M(E e) + return e [||]switch { - return e [||]switch - { - (E.A or E.B) or (E.C and E.D) => true, - _ = false - }; - } + (E.A or E.B) or (E.C and E.D) => true, + _ = false + }; + } - public enum E - { - A, - B, - C, - D, - E, - F, - G, - } + public enum E + { + A, + B, + C, + D, + E, + F, + G, } - """, - """ - public static class C + } + """, + """ + public static class C + { + static bool M(E e) { - static bool M(E e) + return e [||]switch { - return e [||]switch - { - (E.A or E.B) or (E.C and E.D) => true, - E.C => throw new System.NotImplementedException(), - E.D => throw new System.NotImplementedException(), - E.E => throw new System.NotImplementedException(), - E.F => throw new System.NotImplementedException(), - E.G => throw new System.NotImplementedException(), - _ = false - }; - } + (E.A or E.B) or (E.C and E.D) => true, + E.C => throw new System.NotImplementedException(), + E.D => throw new System.NotImplementedException(), + E.E => throw new System.NotImplementedException(), + E.F => throw new System.NotImplementedException(), + E.G => throw new System.NotImplementedException(), + _ = false + }; + } - public enum E - { - A, - B, - C, - D, - E, - F, - G, - } + public enum E + { + A, + B, + C, + D, + E, + F, + G, } - """ + } + """ ); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] - public async Task NotOnOrPatternWhichAlwaysSucceeds1() - { - await TestMissingInRegularAndScriptAsync( - """ - enum Greeting - { - Hello, - Goodbye - }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] + public async Task NotOnOrPatternWhichAlwaysSucceeds1() + { + await TestMissingInRegularAndScriptAsync( + """ + enum Greeting + { + Hello, + Goodbye + }; - class C + class C + { + void M() { - void M() + Greeting greeting = Greeting.Hello; + string message = greeting [||]switch { - Greeting greeting = Greeting.Hello; - string message = greeting [||]switch - { - Greeting.Hello => "Hey!", - Greeting.Goodbye or _ => "Not sure what to say 🤔" - }; - } + Greeting.Hello => "Hey!", + Greeting.Goodbye or _ => "Not sure what to say 🤔" + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] - public async Task NotOnOrPatternWhichAlwaysSucceeds2() - { - await TestMissingInRegularAndScriptAsync( - """ - enum Greeting - { - Hello, - Goodbye - }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] + public async Task NotOnOrPatternWhichAlwaysSucceeds2() + { + await TestMissingInRegularAndScriptAsync( + """ + enum Greeting + { + Hello, + Goodbye + }; - class C + class C + { + void M() { - void M() + Greeting greeting = Greeting.Hello; + string message = greeting [||]switch { - Greeting greeting = Greeting.Hello; - string message = greeting [||]switch - { - Greeting.Hello => "Hey!", - _ or Greeting.Goodbye => "Not sure what to say 🤔" - }; - } + Greeting.Hello => "Hey!", + _ or Greeting.Goodbye => "Not sure what to say 🤔" + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] - public async Task NotOnOrPatternWhichAlwaysSucceeds3() - { - await TestMissingInRegularAndScriptAsync( - """ - enum Greeting - { - Hello, - Goodbye - }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] + public async Task NotOnOrPatternWhichAlwaysSucceeds3() + { + await TestMissingInRegularAndScriptAsync( + """ + enum Greeting + { + Hello, + Goodbye + }; - class C + class C + { + void M() { - void M() + Greeting greeting = Greeting.Hello; + string message = greeting [||]switch { - Greeting greeting = Greeting.Hello; - string message = greeting [||]switch - { - Greeting.Hello => "Hey!", - Greeting.Goodbye => "Bye!", - _ and var v => "Not sure what to say 🤔" - }; - } + Greeting.Hello => "Hey!", + Greeting.Goodbye => "Bye!", + _ and var v => "Not sure what to say 🤔" + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] - public async Task NotOnOrPatternWhichAlwaysSucceeds4() - { - await TestMissingInRegularAndScriptAsync( - """ - enum Greeting - { - Hello, - Goodbye - }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58468")] + public async Task NotOnOrPatternWhichAlwaysSucceeds4() + { + await TestMissingInRegularAndScriptAsync( + """ + enum Greeting + { + Hello, + Goodbye + }; - class C + class C + { + void M() { - void M() + Greeting greeting = Greeting.Hello; + string message = greeting [||]switch { - Greeting greeting = Greeting.Hello; - string message = greeting [||]switch - { - Greeting.Hello => "Hey!", - Greeting.Goodbye => "Bye!", - var x and var y => "Not sure what to say 🤔" - }; - } + Greeting.Hello => "Hey!", + Greeting.Goodbye => "Bye!", + var x and var y => "Not sure what to say 🤔" + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] - public async Task TestForNullableEnum_NullableEnabled() - { - await TestInRegularAndScript1Async( - """ - #nullable enable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] + public async Task TestForNullableEnum_NullableEnabled() + { + await TestInRegularAndScript1Async( + """ + #nullable enable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue [||]switch - { - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue [||]switch + { + }; + } - enum MyEnum - { - Value1, Value2 - } - """, - """ - #nullable enable + enum MyEnum + { + Value1, Value2 + } + """, + """ + #nullable enable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue switch - { - MyEnum.Value1 => throw new System.NotImplementedException(), - MyEnum.Value2 => throw new System.NotImplementedException(), - null => throw new System.NotImplementedException(), - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue switch + { + MyEnum.Value1 => throw new System.NotImplementedException(), + MyEnum.Value2 => throw new System.NotImplementedException(), + null => throw new System.NotImplementedException(), + }; + } - enum MyEnum - { - Value1, Value2 - } - """); - } + enum MyEnum + { + Value1, Value2 + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] - public async Task TestForNullableEnum_NullableEnabled_NotGenerateNullArmIfItAlreadyExists() - { - await TestInRegularAndScript1Async( - """ - #nullable enable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] + public async Task TestForNullableEnum_NullableEnabled_NotGenerateNullArmIfItAlreadyExists() + { + await TestInRegularAndScript1Async( + """ + #nullable enable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue [||]switch - { - null => throw null, - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue [||]switch + { + null => throw null, + }; + } - enum MyEnum - { - Value1, Value2 - } - """, - """ - #nullable enable + enum MyEnum + { + Value1, Value2 + } + """, + """ + #nullable enable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue switch - { - null => throw null, - MyEnum.Value1 => throw new System.NotImplementedException(), - MyEnum.Value2 => throw new System.NotImplementedException(), - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue switch + { + null => throw null, + MyEnum.Value1 => throw new System.NotImplementedException(), + MyEnum.Value2 => throw new System.NotImplementedException(), + }; + } - enum MyEnum - { - Value1, Value2 - } - """); - } + enum MyEnum + { + Value1, Value2 + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] - public async Task TestForNullableEnum_NullableDisabled() - { - await TestInRegularAndScript1Async( - """ - #nullable disable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] + public async Task TestForNullableEnum_NullableDisabled() + { + await TestInRegularAndScript1Async( + """ + #nullable disable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue [||]switch - { - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue [||]switch + { + }; + } - enum MyEnum - { - Value1, Value2 - } - """, - """ - #nullable disable + enum MyEnum + { + Value1, Value2 + } + """, + """ + #nullable disable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue switch - { - MyEnum.Value1 => throw new System.NotImplementedException(), - MyEnum.Value2 => throw new System.NotImplementedException(), - null => throw new System.NotImplementedException(), - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue switch + { + MyEnum.Value1 => throw new System.NotImplementedException(), + MyEnum.Value2 => throw new System.NotImplementedException(), + null => throw new System.NotImplementedException(), + }; + } - enum MyEnum - { - Value1, Value2 - } - """); - } + enum MyEnum + { + Value1, Value2 + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] - public async Task TestForNullableEnum_NullableDisabled_NotGenerateNullArmIfItAlreadyExists() - { - await TestInRegularAndScript1Async( - """ - #nullable disable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61594")] + public async Task TestForNullableEnum_NullableDisabled_NotGenerateNullArmIfItAlreadyExists() + { + await TestInRegularAndScript1Async( + """ + #nullable disable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue [||]switch - { - null => throw null, - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue [||]switch + { + null => throw null, + }; + } - enum MyEnum - { - Value1, Value2 - } - """, - """ - #nullable disable + enum MyEnum + { + Value1, Value2 + } + """, + """ + #nullable disable - static class MyEnumExtensions - { - public static string ToAnotherEnum(this MyEnum? myEnumValue) - => myEnumValue switch - { - null => throw null, - MyEnum.Value1 => throw new System.NotImplementedException(), - MyEnum.Value2 => throw new System.NotImplementedException(), - }; - } + static class MyEnumExtensions + { + public static string ToAnotherEnum(this MyEnum? myEnumValue) + => myEnumValue switch + { + null => throw null, + MyEnum.Value1 => throw new System.NotImplementedException(), + MyEnum.Value2 => throw new System.NotImplementedException(), + }; + } - enum MyEnum - { - Value1, Value2 - } - """); - } + enum MyEnum + { + Value1, Value2 + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] - public async Task NotOnCompleteBoolean1() - { - await TestMissingAsync( - """ - public class Sample + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] + public async Task NotOnCompleteBoolean1() + { + await TestMissingAsync( + """ + public class Sample + { + public string Method(bool boolean) { - public string Method(bool boolean) + return boolean [||]switch { - return boolean [||]switch - { - true => "true", - false => "false", - }; - } + true => "true", + false => "false", + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] - public async Task NotOnCompleteBoolean2() - { - await TestMissingAsync( - """ - public class Sample + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] + public async Task NotOnCompleteBoolean2() + { + await TestMissingAsync( + """ + public class Sample + { + public string Method(bool? boolean) { - public string Method(bool? boolean) + return boolean [||]switch { - return boolean [||]switch - { - true => "true", - false => "false", - null => "null", - }; - } + true => "true", + false => "false", + null => "null", + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] - public async Task OnIncompleteBoolean1() - { - await TestInRegularAndScript1Async( - """ - public class Sample + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] + public async Task OnIncompleteBoolean1() + { + await TestInRegularAndScript1Async( + """ + public class Sample + { + public string Method(bool boolean) { - public string Method(bool boolean) + return boolean [||]switch { - return boolean [||]switch - { - true => "true", - }; - } + true => "true", + }; } - """, - """ - public class Sample + } + """, + """ + public class Sample + { + public string Method(bool boolean) { - public string Method(bool boolean) + return boolean switch { - return boolean switch - { - true => "true", - _ => throw new System.NotImplementedException(), - }; - } + true => "true", + _ => throw new System.NotImplementedException(), + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] - public async Task OnIncompleteBoolean2() - { - await TestInRegularAndScript1Async( - """ - public class Sample + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48876")] + public async Task OnIncompleteBoolean2() + { + await TestInRegularAndScript1Async( + """ + public class Sample + { + public string Method(bool? boolean) { - public string Method(bool? boolean) + return boolean [||]switch { - return boolean [||]switch - { - true => "true", - false => "false", - }; - } + true => "true", + false => "false", + }; } - """, - """ - public class Sample + } + """, + """ + public class Sample + { + public string Method(bool? boolean) { - public string Method(bool? boolean) + return boolean switch { - return boolean switch - { - true => "true", - false => "false", - _ => throw new System.NotImplementedException(), - }; - } + true => "true", + false => "false", + _ => throw new System.NotImplementedException(), + }; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests_FixAllTests.cs index 0d928d22972c9..f34cf81e504b1 100644 --- a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchExpressionTests_FixAllTests.cs @@ -7,464 +7,463 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch; + +[Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] +public partial class PopulateSwitchExpressionTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public partial class PopulateSwitchExpressionTests + [Fact] + public async Task TestFixAllInDocument() { - [Fact] - public async Task TestFixAllInDocument() - { - var input = """ - - - - namespace ConsoleApplication1 + var input = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e {|FixAllInDocument:|}switch + { + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; + _ = e switch { - var e = MyEnum.Fizz; - _ = e {|FixAllInDocument:|}switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - """; + } + + + + """; - var expected = """ - - - - namespace ConsoleApplication1 + var expected = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch + { + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - public async Task TestFixAllInProject() - { - var input = """ - - - - namespace ConsoleApplication1 + [Fact] + public async Task TestFixAllInProject() + { + var input = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e {|FixAllInProject:|}switch { - var e = MyEnum.Fizz; - _ = e {|FixAllInProject:|}switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - """; + } + + + + """; - var expected = """ - - - - namespace ConsoleApplication1 + var expected = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + _ = e switch { - var e = MyEnum.Fizz; - _ = e switch - { - MyEnum.Fizz => 1, - MyEnum.Buzz => 2, - MyEnum.FizzBuzz => 3, - }; - } + MyEnum.Fizz => 1, + MyEnum.Buzz => 2, + MyEnum.FizzBuzz => 3, + }; } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - public async Task TestFixAllInSolution() - { - var input = """ - - - - namespace ConsoleApplication1 + [Fact] + public async Task TestFixAllInSolution() + { + var input = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum1 { - enum MyEnum1 - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum1.Fizz; + _ = e {|FixAllInSolution:|}switch { - var e = MyEnum1.Fizz; - _ = e {|FixAllInSolution:|}switch - { - MyEnum1.Fizz => 1, - MyEnum1.Buzz => 2, - MyEnum1.FizzBuzz => 3, - }; - } + MyEnum1.Fizz => 1, + MyEnum1.Buzz => 2, + MyEnum1.FizzBuzz => 3, + }; } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + enum MyEnum2 { - enum MyEnum2 - { - Fizz, Buzz, FizzBuzz - } - class MyClass2 + Fizz, Buzz, FizzBuzz + } + class MyClass2 + { + void Method() { - void Method() + var e = MyEnum2.Fizz; + _ = e switch { - var e = MyEnum2.Fizz; - _ = e switch - { - MyEnum2.Fizz => 1, - MyEnum2.Buzz => 2, - MyEnum2.FizzBuzz => 3, - }; - } + MyEnum2.Fizz => 1, + MyEnum2.Buzz => 2, + MyEnum2.FizzBuzz => 3, + }; } } - - - - - namespace ConsoleApplication2 + } + + + + + namespace ConsoleApplication2 + { + enum MyEnum3 { - enum MyEnum3 - { - Fizz, Buzz, FizzBuzz - } - class MyClass3 + Fizz, Buzz, FizzBuzz + } + class MyClass3 + { + void Method() { - void Method() + var e = MyEnum3.Fizz; + _ = e switch { - var e = MyEnum3.Fizz; - _ = e switch - { - MyEnum3.Fizz => 1, - MyEnum3.Buzz => 2, - MyEnum3.FizzBuzz => 3, - }; - } + MyEnum3.Fizz => 1, + MyEnum3.Buzz => 2, + MyEnum3.FizzBuzz => 3, + }; } } - - - - """; + } + + + + """; - var expected = """ - - - - namespace ConsoleApplication1 + var expected = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum1 { - enum MyEnum1 - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum1.Fizz; + _ = e switch { - var e = MyEnum1.Fizz; - _ = e switch - { - MyEnum1.Fizz => 1, - MyEnum1.Buzz => 2, - MyEnum1.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum1.Fizz => 1, + MyEnum1.Buzz => 2, + MyEnum1.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + enum MyEnum2 { - enum MyEnum2 - { - Fizz, Buzz, FizzBuzz - } - class MyClass2 + Fizz, Buzz, FizzBuzz + } + class MyClass2 + { + void Method() { - void Method() + var e = MyEnum2.Fizz; + _ = e switch { - var e = MyEnum2.Fizz; - _ = e switch - { - MyEnum2.Fizz => 1, - MyEnum2.Buzz => 2, - MyEnum2.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum2.Fizz => 1, + MyEnum2.Buzz => 2, + MyEnum2.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - - - - - namespace ConsoleApplication2 + } + + + + + namespace ConsoleApplication2 + { + enum MyEnum3 { - enum MyEnum3 - { - Fizz, Buzz, FizzBuzz - } - class MyClass3 + Fizz, Buzz, FizzBuzz + } + class MyClass3 + { + void Method() { - void Method() + var e = MyEnum3.Fizz; + _ = e switch { - var e = MyEnum3.Fizz; - _ = e switch - { - MyEnum3.Fizz => 1, - MyEnum3.Buzz => 2, - MyEnum3.FizzBuzz => 3, - _ => throw new System.NotImplementedException(), - }; - } + MyEnum3.Fizz => 1, + MyEnum3.Buzz => 2, + MyEnum3.FizzBuzz => 3, + _ => throw new System.NotImplementedException(), + }; } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); } } diff --git a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests.cs b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests.cs index 497e58d40da29..736560e85795a 100644 --- a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests.cs +++ b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests.cs @@ -1638,4 +1638,124 @@ void Method(int i) } """); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73245")] + public async Task NotAllMembersExist_NotDefault_OrPattern() + { + await TestInRegularAndScriptAsync( + """ + namespace ConsoleApplication1 + { + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz, + FizzBuzzFizz + } + + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + [||]switch (e) + { + case MyEnum.Fizz or MyEnum.Buzz or MyEnum.FizzBuzz: + break; + } + } + } + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz, + FizzBuzzFizz + } + + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz or MyEnum.Buzz or MyEnum.FizzBuzz: + break; + case MyEnum.FizzBuzzFizz: + break; + default: + break; + } + } + } + } + """, index: 2); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73245")] + public async Task NotAllMembersExist_WithDefault_OrPattern() + { + await TestInRegularAndScriptAsync( + """ + namespace ConsoleApplication1 + { + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz + } + + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + [||]switch (e) + { + case MyEnum.Fizz or MyEnum.Buzz: + break; + default: + break; + } + } + } + } + """, + """ + namespace ConsoleApplication1 + { + enum MyEnum + { + Fizz, + Buzz, + FizzBuzz + } + + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz or MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } + } + """); + } } diff --git a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests_FixAllTests.cs index f10c7c1c0ec48..95918924d3f2a 100644 --- a/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/PopulateSwitch/PopulateSwitchStatementTests_FixAllTests.cs @@ -9,496 +9,495 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch; + +public partial class PopulateSwitchStatementTests { - public partial class PopulateSwitchStatementTests + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() { - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument() - { - var input = """ - - - - namespace ConsoleApplication1 + var input = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + {|FixAllInDocument:|}switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + switch (e) { - var e = MyEnum.Fizz; - {|FixAllInDocument:|}switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - """; + } + + + + """; - var expected = """ - - - - namespace ConsoleApplication1 + var expected = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; + } + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - default: - break; - } - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - default: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; } } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject() - { - var input = """ - - - - namespace ConsoleApplication1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var input = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + {|FixAllInProject:|}switch (e) { - var e = MyEnum.Fizz; - {|FixAllInProject:|}switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - """; + } + + + + """; - var expected = """ - - - - namespace ConsoleApplication1 + var expected = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum { - enum MyEnum - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - default: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; } } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + class MyClass2 { - class MyClass2 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - default: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; } } } - - - - - namespace ConsoleApplication1 + } + + + + + namespace ConsoleApplication1 + { + class MyClass3 { - class MyClass3 + void Method() { - void Method() + var e = MyEnum.Fizz; + switch (e) { - var e = MyEnum.Fizz; - switch (e) - { - case MyEnum.Fizz: - case MyEnum.Buzz: - case MyEnum.FizzBuzz: - break; - } + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; } } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); + } - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution() - { - var input = """ - - - - namespace ConsoleApplication1 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() + { + var input = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum1 { - enum MyEnum1 - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum1.Fizz; + {|FixAllInSolution:|}switch (e) { - var e = MyEnum1.Fizz; - {|FixAllInSolution:|}switch (e) - { - case MyEnum1.Fizz: - case MyEnum1.Buzz: - case MyEnum1.FizzBuzz: - break; - } + case MyEnum1.Fizz: + case MyEnum1.Buzz: + case MyEnum1.FizzBuzz: + break; } } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + enum MyEnum2 { - enum MyEnum2 - { - Fizz, Buzz, FizzBuzz - } - class MyClass2 + Fizz, Buzz, FizzBuzz + } + class MyClass2 + { + void Method() { - void Method() + var e = MyEnum2.Fizz; + switch (e) { - var e = MyEnum2.Fizz; - switch (e) - { - case MyEnum2.Fizz: - case MyEnum2.Buzz: - case MyEnum2.FizzBuzz: - break; - } + case MyEnum2.Fizz: + case MyEnum2.Buzz: + case MyEnum2.FizzBuzz: + break; } } } - - - - - namespace ConsoleApplication2 + } + + + + + namespace ConsoleApplication2 + { + enum MyEnum3 { - enum MyEnum3 - { - Fizz, Buzz, FizzBuzz - } - class MyClass3 + Fizz, Buzz, FizzBuzz + } + class MyClass3 + { + void Method() { - void Method() + var e = MyEnum3.Fizz; + switch (e) { - var e = MyEnum3.Fizz; - switch (e) - { - case MyEnum3.Fizz: - case MyEnum3.Buzz: - case MyEnum3.FizzBuzz: - break; - } + case MyEnum3.Fizz: + case MyEnum3.Buzz: + case MyEnum3.FizzBuzz: + break; } } } - - - - """; + } + + + + """; - var expected = """ - - - - namespace ConsoleApplication1 + var expected = """ + + + + namespace ConsoleApplication1 + { + enum MyEnum1 { - enum MyEnum1 - { - Fizz, Buzz, FizzBuzz - } - class MyClass1 + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() { - void Method() + var e = MyEnum1.Fizz; + switch (e) { - var e = MyEnum1.Fizz; - switch (e) - { - case MyEnum1.Fizz: - case MyEnum1.Buzz: - case MyEnum1.FizzBuzz: - break; - default: - break; - } + case MyEnum1.Fizz: + case MyEnum1.Buzz: + case MyEnum1.FizzBuzz: + break; + default: + break; } } } - - - namespace ConsoleApplication1 + } + + + namespace ConsoleApplication1 + { + enum MyEnum2 { - enum MyEnum2 - { - Fizz, Buzz, FizzBuzz - } - class MyClass2 + Fizz, Buzz, FizzBuzz + } + class MyClass2 + { + void Method() { - void Method() + var e = MyEnum2.Fizz; + switch (e) { - var e = MyEnum2.Fizz; - switch (e) - { - case MyEnum2.Fizz: - case MyEnum2.Buzz: - case MyEnum2.FizzBuzz: - break; - default: - break; - } + case MyEnum2.Fizz: + case MyEnum2.Buzz: + case MyEnum2.FizzBuzz: + break; + default: + break; } } } - - - - - namespace ConsoleApplication2 + } + + + + + namespace ConsoleApplication2 + { + enum MyEnum3 { - enum MyEnum3 - { - Fizz, Buzz, FizzBuzz - } - class MyClass3 + Fizz, Buzz, FizzBuzz + } + class MyClass3 + { + void Method() { - void Method() + var e = MyEnum3.Fizz; + switch (e) { - var e = MyEnum3.Fizz; - switch (e) - { - case MyEnum3.Fizz: - case MyEnum3.Buzz: - case MyEnum3.FizzBuzz: - break; - default: - break; - } + case MyEnum3.Fizz: + case MyEnum3.Buzz: + case MyEnum3.FizzBuzz: + break; + default: + break; } } } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync(input, expected); - } + await TestInRegularAndScriptAsync(input, expected); } } diff --git a/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests.cs b/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests.cs index 3bf8e5f0d1c20..6fa35b77ada86 100644 --- a/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests.cs +++ b/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests.cs @@ -14,2146 +14,2145 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.QualifyMemberAccess +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.QualifyMemberAccess; + +[Trait(Traits.Feature, Traits.Features.CodeActionsQualifyMemberAccess)] +public partial class QualifyMemberAccessTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsQualifyMemberAccess)] - public partial class QualifyMemberAccessTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public QualifyMemberAccessTests(ITestOutputHelper logger) + : base(logger) { - public QualifyMemberAccessTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpQualifyMemberAccessDiagnosticAnalyzer(), new CSharpQualifyMemberAccessCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpQualifyMemberAccessDiagnosticAnalyzer(), new CSharpQualifyMemberAccessCodeFixProvider()); - private Task TestAsyncWithOption(string code, string expected, PerLanguageOption2> option) - => TestAsyncWithOptionAndNotificationOption(code, expected, option, NotificationOption2.Error); + private Task TestAsyncWithOption(string code, string expected, PerLanguageOption2> option) + => TestAsyncWithOptionAndNotificationOption(code, expected, option, NotificationOption2.Error); - private Task TestAsyncWithOptionAndNotificationOption(string code, string expected, PerLanguageOption2> option, NotificationOption2 notification) - => TestInRegularAndScriptAsync(code, expected, options: Option(option, true, notification)); + private Task TestAsyncWithOptionAndNotificationOption(string code, string expected, PerLanguageOption2> option, NotificationOption2 notification) + => TestInRegularAndScriptAsync(code, expected, options: Option(option, true, notification)); - private Task TestMissingAsyncWithOption(string code, PerLanguageOption2> option) - => TestMissingAsyncWithOptionAndNotificationOption(code, option, NotificationOption2.Error); + private Task TestMissingAsyncWithOption(string code, PerLanguageOption2> option) + => TestMissingAsyncWithOptionAndNotificationOption(code, option, NotificationOption2.Error); - private Task TestMissingAsyncWithOptionAndNotificationOption(string code, PerLanguageOption2> option, NotificationOption2 notification) - => TestMissingInRegularAndScriptAsync(code, new TestParameters(options: Option(option, true, notification))); + private Task TestMissingAsyncWithOptionAndNotificationOption(string code, PerLanguageOption2> option, NotificationOption2 notification) + => TestMissingInRegularAndScriptAsync(code, new TestParameters(options: Option(option, true, notification))); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_LHS() - { - await TestAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_LHS() + { + await TestAsyncWithOption( + """ + class Class + { + int i; - void M() - { - [|i|] = 1; - } - } - """, - """ - class Class + void M() { - int i; - - void M() - { - this.i = 1; - } + [|i|] = 1; } - """, -CodeStyleOptions2.QualifyFieldAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_RHS() - { - await TestAsyncWithOption( - """ - class Class - { - int i; + } + """, + """ + class Class + { + int i; - void M() - { - var x = [|i|]; - } - } - """, - """ - class Class + void M() { - int i; - - void M() - { - var x = this.i; - } + this.i = 1; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_MethodArgument() - { - await TestAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_RHS() + { + await TestAsyncWithOption( + """ + class Class + { + int i; - void M(int ii) - { - M([|i|]); - } - } - """, - """ - class Class + void M() { - int i; - - void M(int ii) - { - M(this.i); - } + var x = [|i|]; } - """, -CodeStyleOptions2.QualifyFieldAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_ChainedAccess() - { - await TestAsyncWithOption( - """ - class Class - { - int i; + } + """, + """ + class Class + { + int i; - void M() - { - var s = [|i|].ToString(); - } - } - """, - """ - class Class + void M() { - int i; - - void M() - { - var s = this.i.ToString(); - } + var x = this.i; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_ConditionalAccess() - { - await TestAsyncWithOption( - """ - class Class - { - string s; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_MethodArgument() + { + await TestAsyncWithOption( + """ + class Class + { + int i; - void M() - { - var x = [|s|]?.ToString(); - } - } - """, - """ - class Class + void M(int ii) { - string s; - - void M() - { - var x = this.s?.ToString(); - } + M([|i|]); } - """, -CodeStyleOptions2.QualifyFieldAccess); - } + } + """, + """ + class Class + { + int i; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_OnBase() - { - await TestAsyncWithOption( - """ - class Base + void M(int ii) { - protected int i; + M(this.i); } + } + """, +CodeStyleOptions2.QualifyFieldAccess); + } - class Derived : Base - { - void M() - { - [|i|] = 1; - } - } - """, - """ - class Base + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_ChainedAccess() + { + await TestAsyncWithOption( + """ + class Class + { + int i; + + void M() { - protected int i; + var s = [|i|].ToString(); } + } + """, + """ + class Class + { + int i; - class Derived : Base + void M() { - void M() - { - this.i = 1; - } + var s = this.i.ToString(); } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_ConditionalAccess() + { + await TestAsyncWithOption( + """ + class Class + { + string s; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyFieldAccess_InObjectInitializer() - { - await TestAsyncWithOption( - """ - class C + void M() { - int i = 1; - void M() - { - var test = new System.Collections.Generic.List { [|i|] }; - } + var x = [|s|]?.ToString(); } - """, - """ - class C + } + """, + """ + class Class + { + string s; + + void M() { - int i = 1; - void M() - { - var test = new System.Collections.Generic.List { this.i }; - } + var x = this.s?.ToString(); } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyFieldAccess_InCollectionInitializer() - { - await TestAsyncWithOption( - """ - class C - { - int i = 1; - void M() - { - var test = new System.Collections.Generic.List { [|i|] }; - } - } - """, - """ - class C - { - int i = 1; - void M() - { - var test = new System.Collections.Generic.List { this.i }; - } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_OnBase() + { + await TestAsyncWithOption( + """ + class Base + { + protected int i; + } + + class Derived : Base + { + void M() + { + [|i|] = 1; + } + } + """, + """ + class Base + { + protected int i; + } + + class Derived : Base + { + void M() + { + this.i = 1; + } + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_NotSuggestedOnInstance() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyFieldAccess_InObjectInitializer() + { + await TestAsyncWithOption( + """ + class C + { + int i = 1; + void M() + { + var test = new System.Collections.Generic.List { [|i|] }; + } + } + """, + """ + class C + { + int i = 1; + void M() + { + var test = new System.Collections.Generic.List { this.i }; + } + } + """, +CodeStyleOptions2.QualifyFieldAccess); + } - void M() - { - Class c = new Class(); - c.[|i|] = 1; - } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyFieldAccess_InCollectionInitializer() + { + await TestAsyncWithOption( + """ + class C + { + int i = 1; + void M() + { + var test = new System.Collections.Generic.List { [|i|] }; + } + } + """, + """ + class C + { + int i = 1; + void M() + { + var test = new System.Collections.Generic.List { this.i }; + } + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyFieldAccess_NotSuggestedOnStatic() - { - await TestMissingAsyncWithOption( - """ - class C - { - static int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_NotSuggestedOnInstance() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M() - { - [|i|] = 1; - } + void M() + { + Class c = new Class(); + c.[|i|] = 1; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyFieldAccess_NotSuggestedOnStatic() + { + await TestMissingAsyncWithOption( + """ + class C + { + static int i; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyFieldAccess_NotSuggestedOnLocalVarInObjectInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + void M() { - void M() - { - var foo = 1; - var test = new System.Collections.Generic.List { [|foo|] }; - } + [|i|] = 1; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyFieldAccess_NotSuggestedOnLocalVarInCollectionInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyFieldAccess_NotSuggestedOnLocalVarInObjectInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - var foo = 1; - var test = new System.Collections.Generic.List { [|foo|] }; - } + var foo = 1; + var test = new System.Collections.Generic.List { [|foo|] }; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28091")] - public async Task QualifyFieldAccess_NotSuggestedOnLocalVarInDictionaryInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyFieldAccess_NotSuggestedOnLocalVarInCollectionInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - var foo = 1; - var test = new System.Collections.Generic.Dictionary { { 2, [|foo|] } }; - } + var foo = 1; + var test = new System.Collections.Generic.List { [|foo|] }; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyFieldAccess_Subpattern1() - { - await TestMissingAsyncWithOption( - """ - class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28091")] + public async Task QualifyFieldAccess_NotSuggestedOnLocalVarInDictionaryInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - int i; - - void M(Class c) - { - if (c is { [|i|]: 1 }) - { - } - } + var foo = 1; + var test = new System.Collections.Generic.Dictionary { { 2, [|foo|] } }; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyFieldAccess_Subpattern2() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyFieldAccess_Subpattern1() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M(Class c) + void M(Class c) + { + if (c is { [|i|]: 1 }) { - switch (t) - { - case Class { [|i|]: 1 }: - return; - } } } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyFieldAccess_Subpattern3() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyFieldAccess_Subpattern2() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M(Class c) + void M(Class c) + { + switch (t) { - var a = c switch - { - { [|i|]: 0 } => 1, - _ => 0 - }; + case Class { [|i|]: 1 }: + return; } } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_LHS() - { - await TestAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyFieldAccess_Subpattern3() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M() + void M(Class c) + { + var a = c switch { - [|i|] = 1; - } + { [|i|]: 0 } => 1, + _ => 0 + }; } - """, - """ - class Class + } + """, +CodeStyleOptions2.QualifyFieldAccess); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_LHS() + { + await TestAsyncWithOption( + """ + class Class + { + int i { get; set; } + + void M() { - int i { get; set; } + [|i|] = 1; + } + } + """, + """ + class Class + { + int i { get; set; } - void M() - { - this.i = 1; - } + void M() + { + this.i = 1; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_RHS() - { - await TestAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_RHS() + { + await TestAsyncWithOption( + """ + class Class + { + int i { get; set; } - void M() - { - var x = [|i|]; - } - } - """, - """ - class Class + void M() { - int i { get; set; } + var x = [|i|]; + } + } + """, + """ + class Class + { + int i { get; set; } - void M() - { - var x = this.i; - } + void M() + { + var x = this.i; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_PropertySubpattern1() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_PropertySubpattern1() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i { get; set; } - void M(Class c) + void M(Class c) + { + if (c is { [|i|]: 1 }) { - if (c is { [|i|]: 1 }) - { - } } } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_PropertySubpattern2() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_PropertySubpattern2() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i { get; set; } - void M(Class c) + void M(Class c) + { + switch (t) { - switch (t) - { - case Class { [|i|]: 1 }: - return; - } + case Class { [|i|]: 1 }: + return; } } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_PropertySubpattern3() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_PropertySubpattern3() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i { get; set; } - void M(Class c) + void M(Class c) + { + var a = c switch { - var a = c switch - { - { [|i|]: 0 } => 1, - _ => 0 - }; - } + { [|i|]: 0 } => 1, + _ => 0 + }; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_PropertySubpattern4() - { - // it's ok that we qualify here because it's not a legal pattern (because it is not const). - await TestAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_PropertySubpattern4() + { + // it's ok that we qualify here because it's not a legal pattern (because it is not const). + await TestAsyncWithOption( + """ + class Class + { + int i { get; set; } - void M(Class c) - { - var a = c switch - { - { i: [|i|] } => 1, - _ => 0 - }; - } - } - """, - """ - class Class + void M(Class c) { - int i { get; set; } - - void M(Class c) + var a = c switch { - var a = c switch - { - { i: this.i } => 1, - _ => 0 - }; - } + { i: [|i|] } => 1, + _ => 0 + }; } - """, -CodeStyleOptions2.QualifyPropertyAccess); - } + } + """, + """ + class Class + { + int i { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_FieldSubpattern1() - { - await TestMissingAsyncWithOption( - """ - class Class + void M(Class c) { - int i; - - void M(Class c) + var a = c switch { - if (c is { [|i|]: 1 }) - { - } - } + { i: this.i } => 1, + _ => 0 + }; } - """, -CodeStyleOptions2.QualifyFieldAccess); - } + } + """, +CodeStyleOptions2.QualifyPropertyAccess); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_FieldSubpattern2() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_FieldSubpattern1() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M(Class c) + void M(Class c) + { + if (c is { [|i|]: 1 }) { - switch (t) - { - case Class { [|i|]: 1 }: - return; - } } } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_FieldSubpattern3() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_FieldSubpattern2() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M(Class c) + void M(Class c) + { + switch (t) { - var a = c switch - { - { [|i|]: 0 } => 1, - _ => 0 - }; + case Class { [|i|]: 1 }: + return; } } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] - public async Task QualifyPropertyAccess_FieldSubpattern4() - { - // it's ok that we qualify here because it's not a legal pattern (because it is not const). - await TestAsyncWithOption( - """ - class Class - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_FieldSubpattern3() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i; - void M(Class c) - { - var a = c switch - { - { i: [|i|] } => 1, - _ => 0 - }; - } - } - """, - """ - class Class + void M(Class c) { - int i; - - void M(Class c) + var a = c switch { - var a = c switch - { - { i: this.i } => 1, - _ => 0 - }; - } + { [|i|]: 0 } => 1, + _ => 0 + }; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_MethodArgument() - { - await TestAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40242")] + public async Task QualifyPropertyAccess_FieldSubpattern4() + { + // it's ok that we qualify here because it's not a legal pattern (because it is not const). + await TestAsyncWithOption( + """ + class Class + { + int i; - void M(int ii) - { - M([|i|]); - } - } - """, - """ - class Class + void M(Class c) { - int i { get; set; } - - void M(int ii) + var a = c switch { - M(this.i); - } + { i: [|i|] } => 1, + _ => 0 + }; } - """, -CodeStyleOptions2.QualifyPropertyAccess); - } + } + """, + """ + class Class + { + int i; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_ChainedAccess() - { - await TestAsyncWithOption( - """ - class Class + void M(Class c) { - int i { get; set; } - - void M() + var a = c switch { - var s = [|i|].ToString(); - } + { i: this.i } => 1, + _ => 0 + }; } - """, - """ - class Class - { - int i { get; set; } + } + """, +CodeStyleOptions2.QualifyFieldAccess); + } - void M() - { - var s = this.i.ToString(); - } - } - """, -CodeStyleOptions2.QualifyPropertyAccess); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_MethodArgument() + { + await TestAsyncWithOption( + """ + class Class + { + int i { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_ConditionalAccess() - { - await TestAsyncWithOption( - """ - class Class + void M(int ii) { - string s { get; set; } - - void M() - { - var x = [|s|]?.ToString(); - } + M([|i|]); } - """, - """ - class Class - { - string s { get; set; } + } + """, + """ + class Class + { + int i { get; set; } - void M() - { - var x = this.s?.ToString(); - } + void M(int ii) + { + M(this.i); } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_ChainedAccess() + { + await TestAsyncWithOption( + """ + class Class + { + int i { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_OnBase() - { - await TestAsyncWithOption( - """ - class Base + void M() { - protected int i { get; set; } + var s = [|i|].ToString(); } + } + """, + """ + class Class + { + int i { get; set; } - class Derived : Base + void M() { - void M() - { - [|i|] = 1; - } + var s = this.i.ToString(); } - """, - """ - class Base + } + """, +CodeStyleOptions2.QualifyPropertyAccess); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_ConditionalAccess() + { + await TestAsyncWithOption( + """ + class Class + { + string s { get; set; } + + void M() { - protected int i { get; set; } + var x = [|s|]?.ToString(); } + } + """, + """ + class Class + { + string s { get; set; } - class Derived : Base + void M() { - void M() - { - this.i = 1; - } + var x = this.s?.ToString(); } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_NotSuggestedOnInstance() - { - await TestMissingAsyncWithOption( - """ - class Class - { - int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_OnBase() + { + await TestAsyncWithOption( + """ + class Base + { + protected int i { get; set; } + } + + class Derived : Base + { + void M() + { + [|i|] = 1; + } + } + """, + """ + class Base + { + protected int i { get; set; } + } + + class Derived : Base + { + void M() + { + this.i = 1; + } + } + """, +CodeStyleOptions2.QualifyPropertyAccess); + } - void M(Class c) - { - c.[|i|] = 1; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_NotSuggestedOnInstance() + { + await TestMissingAsyncWithOption( + """ + class Class + { + int i { get; set; } + + void M(Class c) + { + c.[|i|] = 1; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyPropertyAccess_NotSuggestedOnStatic() - { - await TestMissingAsyncWithOption( - """ - class C - { - static int i { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyPropertyAccess_NotSuggestedOnStatic() + { + await TestMissingAsyncWithOption( + """ + class C + { + static int i { get; set; } - void M() - { - [|i|] = 1; - } + void M() + { + [|i|] = 1; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_VoidCallWithArguments() - { - await TestAsyncWithOption( - """ - class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_VoidCallWithArguments() + { + await TestAsyncWithOption( + """ + class Class + { + void M(int i) { - void M(int i) - { - [|M|](0); - } + [|M|](0); } - """, - """ - class Class + } + """, + """ + class Class + { + void M(int i) { - void M(int i) - { - this.M(0); - } + this.M(0); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_AsReturn() - { - await TestAsyncWithOption( - """ - class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_AsReturn() + { + await TestAsyncWithOption( + """ + class Class + { + int M() { - int M() - { - return [|M|](); - } - """, - """ - class Class + return [|M|](); + } + """, + """ + class Class + { + int M() { - int M() - { - return this.M(); - } - """, + return this.M(); + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_ChainedAccess() - { - await TestAsyncWithOption( - """ - class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_ChainedAccess() + { + await TestAsyncWithOption( + """ + class Class + { + string M() { - string M() - { - var s = [|M|]().ToString(); - } - """, - """ - class Class + var s = [|M|]().ToString(); + } + """, + """ + class Class + { + string M() { - string M() - { - var s = this.M().ToString(); - } - """, + var s = this.M().ToString(); + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_ConditionalAccess() - { - await TestAsyncWithOption( - """ - class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_ConditionalAccess() + { + await TestAsyncWithOption( + """ + class Class + { + string M() { - string M() - { - return [|M|]()?.ToString(); - } - """, - """ - class Class + return [|M|]()?.ToString(); + } + """, + """ + class Class + { + string M() { - string M() - { - return this.M()?.ToString(); - } - """, + return this.M()?.ToString(); + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_EventSubscription1() + { + await TestAsyncWithOption( + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_EventSubscription1() - { - await TestAsyncWithOption( - """ - using System; + class C + { + event EventHandler e; - class C + void Handler(object sender, EventArgs args) { - event EventHandler e; - - void Handler(object sender, EventArgs args) - { - e += [|Handler|]; - } + e += [|Handler|]; } - """, - """ - using System; + } + """, + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void Handler(object sender, EventArgs args) - { - e += this.Handler; - } + void Handler(object sender, EventArgs args) + { + e += this.Handler; } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_EventSubscription2() + { + await TestAsyncWithOption( + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_EventSubscription2() - { - await TestAsyncWithOption( - """ - using System; + class C + { + event EventHandler e; - class C + void Handler(object sender, EventArgs args) { - event EventHandler e; - - void Handler(object sender, EventArgs args) - { - e += new EventHandler([|Handler|]); - } + e += new EventHandler([|Handler|]); } - """, - """ - using System; + } + """, + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void Handler(object sender, EventArgs args) - { - e += new EventHandler(this.Handler); - } + void Handler(object sender, EventArgs args) + { + e += new EventHandler(this.Handler); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_OnBase() - { - await TestAsyncWithOption( - """ - class Base + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_OnBase() + { + await TestAsyncWithOption( + """ + class Base + { + protected void Method() { - protected void Method() - { - } } + } - class Derived : Base + class Derived : Base + { + void M() { - void M() - { - [|Method|](); - } + [|Method|](); } - """, - """ - class Base + } + """, + """ + class Base + { + protected void Method() { - protected void Method() - { - } } + } - class Derived : Base + class Derived : Base + { + void M() { - void M() - { - this.Method(); - } + this.Method(); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_NotSuggestedOnInstance() - { - await TestMissingAsyncWithOption( - """ - class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_NotSuggestedOnInstance() + { + await TestMissingAsyncWithOption( + """ + class Class + { + void M(Class c) { - void M(Class c) - { - c.[|M|](); - } + c.[|M|](); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyMethodAccess_NotSuggestedOnStatic() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyMethodAccess_NotSuggestedOnStatic() + { + await TestMissingAsyncWithOption( + """ + class C + { + static void Method() { - static void Method() - { - } + } - void M() - { - [|Method|](); - } + void M() + { + [|Method|](); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyMethodAccess_NotSuggestedOnObjectInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyMethodAccess_NotSuggestedOnObjectInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - var foo = 1; - var test = new System.Collections.Generic.List { [|foo|] }; - } + var foo = 1; + var test = new System.Collections.Generic.List { [|foo|] }; } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyLocalMethodAccess_NotSuggestedOnObjectInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyLocalMethodAccess_NotSuggestedOnObjectInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - int Local() => 1; - var test = new System.Collections.Generic.List { [|Local()|] }; - } + int Local() => 1; + var test = new System.Collections.Generic.List { [|Local()|] }; } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyMethodAccess_NotSuggestedOnCollectionInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyMethodAccess_NotSuggestedOnCollectionInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - var foo = 1; - var test = new System.Collections.Generic.List { [|foo|] }; - } + var foo = 1; + var test = new System.Collections.Generic.List { [|foo|] }; } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyLocalMethodAccess_NotSuggestedOnCollectionInitializer() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyLocalMethodAccess_NotSuggestedOnCollectionInitializer() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - int Local() => 1; - var test = new System.Collections.Generic.List { [|Local()|] }; - } + int Local() => 1; + var test = new System.Collections.Generic.List { [|Local()|] }; } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyLocalMethodAccess_NotSuggestedInMethodCall() - { - await TestMissingAsyncWithOption( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyLocalMethodAccess_NotSuggestedInMethodCall() + { + await TestMissingAsyncWithOption( + """ + class C + { + void M() { - void M() - { - int Local() => 1; - [|Local|](); - } + int Local() => 1; + [|Local|](); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38043")] - public async Task QualifyLocalMethodAccess_NotSuggestedInNestedMethodCall() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38043")] + public async Task QualifyLocalMethodAccess_NotSuggestedInNestedMethodCall() + { + await TestMissingAsyncWithOption( + """ + using System; - class C + class C + { + void Method() { - void Method() - { - object LocalFunction() => new object(); - this.Method2([|LocalFunction|]); - } + object LocalFunction() => new object(); + this.Method2([|LocalFunction|]); + } - void Method2(Func LocalFunction) - { - } + void Method2(Func LocalFunction) + { } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38043")] - public async Task QualifyLocalMethodAccess_NotSuggestedInCollectionInitializer() - { - await TestMissingAsyncWithOption( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38043")] + public async Task QualifyLocalMethodAccess_NotSuggestedInCollectionInitializer() + { + await TestMissingAsyncWithOption( + """ + using System; + using System.Collections.Generic; - class C + class C + { + void Method() { - void Method() - { - object LocalFunction() => new object(); - var dict = new Dictionary, int>() { { [|LocalFunction|], 1 } }; - } + object LocalFunction() => new object(); + var dict = new Dictionary, int>() { { [|LocalFunction|], 1 } }; } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38043")] - public async Task QualifyLocalMethodAccess_NotSuggestedInObjectMethodInvocation() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38043")] + public async Task QualifyLocalMethodAccess_NotSuggestedInObjectMethodInvocation() + { + await TestMissingAsyncWithOption( + """ + using System; - class C + class C + { + void Method() { - void Method() - { - object LocalFunction() => new object(); - [|LocalFunction|](); - } + object LocalFunction() => new object(); + [|LocalFunction|](); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] - [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_EventSubscription() - { - await TestAsyncWithOption( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] + [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_EventSubscription() + { + await TestAsyncWithOption( + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void Handler(object sender, EventArgs args) - { - [|e|] += Handler; - } + void Handler(object sender, EventArgs args) + { + [|e|] += Handler; } - """, - """ - using System; + } + """, + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void Handler(object sender, EventArgs args) - { - this.e += Handler; - } + void Handler(object sender, EventArgs args) + { + this.e += Handler; } - """, + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] - [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccessAsProperty_EventSubscription() - { - await TestAsyncWithOption( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] + [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccessAsProperty_EventSubscription() + { + await TestAsyncWithOption( + """ + using System; - class C + class C + { + event EventHandler e { - event EventHandler e + add { - add - { - } - - remove - { - } } - void Handler(object sender, EventArgs args) + remove { - [|e|] += Handler; } } - """, - """ - using System; - class C + void Handler(object sender, EventArgs args) { - event EventHandler e - { - add - { - } - - remove - { - } - } - - void Handler(object sender, EventArgs args) - { - this.e += Handler; - } + [|e|] += Handler; } - """, -CodeStyleOptions2.QualifyEventAccess); - } - - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] - [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_InvokeEvent1() - { - await TestAsyncWithOption( - """ - using System; + } + """, + """ + using System; - class C + class C + { + event EventHandler e { - event EventHandler e; + add + { + } - void OnSomeEvent() + remove { - [|e|](this, new EventArgs()); } } - """, - """ - using System; - class C + void Handler(object sender, EventArgs args) { - event EventHandler e; - - void OnSomeEvent() - { - this.e(this, new EventArgs()); - } + this.e += Handler; } - """, + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] - [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_InvokeEvent2() - { - await TestAsyncWithOption( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] + [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_InvokeEvent1() + { + await TestAsyncWithOption( + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void OnSomeEvent() - { - [|e|].Invoke(this, new EventArgs()); - } + void OnSomeEvent() + { + [|e|](this, new EventArgs()); } - """, - """ - using System; + } + """, + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void OnSomeEvent() - { - this.e.Invoke(this, new EventArgs()); - } + void OnSomeEvent() + { + this.e(this, new EventArgs()); } - """, + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] - [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_InvokeEvent3() - { - await TestAsyncWithOption( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] + [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_InvokeEvent2() + { + await TestAsyncWithOption( + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void OnSomeEvent() - { - [|e|]?.Invoke(this, new EventArgs()); - } + void OnSomeEvent() + { + [|e|].Invoke(this, new EventArgs()); } - """, - """ - using System; + } + """, + """ + using System; - class C - { - event EventHandler e; + class C + { + event EventHandler e; - void OnSomeEvent() - { - this.e?.Invoke(this, new EventArgs()); - } + void OnSomeEvent() + { + this.e.Invoke(this, new EventArgs()); } - """, + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] - [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_OnBase() - { - await TestAsyncWithOption( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] + [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_InvokeEvent3() + { + await TestAsyncWithOption( + """ + using System; - class Base - { - protected event EventHandler e; - } + class C + { + event EventHandler e; - class Derived : Base + void OnSomeEvent() { - void Handler(object sender, EventArgs args) - { - [|e|] += Handler; - } + [|e|]?.Invoke(this, new EventArgs()); } - """, - """ - using System; + } + """, + """ + using System; - class Base - { - protected event EventHandler e; - } + class C + { + event EventHandler e; - class Derived : Base + void OnSomeEvent() { - void Handler(object sender, EventArgs args) - { - this.e += Handler; - } + this.e?.Invoke(this, new EventArgs()); } - """, + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_NotSuggestedOnInstance() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7587")] + [WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_OnBase() + { + await TestAsyncWithOption( + """ + using System; + + class Base + { + protected event EventHandler e; + } - class Class + class Derived : Base + { + void Handler(object sender, EventArgs args) { - event EventHandler e; + [|e|] += Handler; + } + } + """, + """ + using System; - void M(Class c) - { - c.[|e|] += Handler; - } + class Base + { + protected event EventHandler e; + } - void Handler(object sender, EventArgs args) - { - } + class Derived : Base + { + void Handler(object sender, EventArgs args) + { + this.e += Handler; } - """, + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] - public async Task QualifyEventAccess_NotSuggestedOnStatic() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_NotSuggestedOnInstance() + { + await TestMissingAsyncWithOption( + """ + using System; + + class Class + { + event EventHandler e; - class C + void M(Class c) { - static event EventHandler e; + c.[|e|] += Handler; } void Handler(object sender, EventArgs args) { - [|e|] += Handler; - } } - """, + } + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact] - public async Task QualifyMemberAccessOnNotificationOptionSilent() - { - await TestAsyncWithOptionAndNotificationOption( - """ - class Class - { - int Property { get; set; }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/7065")] + public async Task QualifyEventAccess_NotSuggestedOnStatic() + { + await TestMissingAsyncWithOption( + """ + using System; + + class C + { + static event EventHandler e; + } + + void Handler(object sender, EventArgs args) + { + [|e|] += Handler; + } } + """, +CodeStyleOptions2.QualifyEventAccess); + } - void M() - { - [|Property|] = 1; - } - } - """, - """ - class Class + [Fact] + public async Task QualifyMemberAccessOnNotificationOptionSilent() + { + await TestAsyncWithOptionAndNotificationOption( + """ + class Class + { + int Property { get; set; }; + + void M() { - int Property { get; set; }; + [|Property|] = 1; + } + } + """, + """ + class Class + { + int Property { get; set; }; - void M() - { - this.Property = 1; - } + void M() + { + this.Property = 1; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Silent); - } + } - [Fact] - public async Task QualifyMemberAccessOnNotificationOptionInfo() - { - await TestAsyncWithOptionAndNotificationOption( - """ - class Class - { - int Property { get; set; }; + [Fact] + public async Task QualifyMemberAccessOnNotificationOptionInfo() + { + await TestAsyncWithOptionAndNotificationOption( + """ + class Class + { + int Property { get; set; }; - void M() - { - [|Property|] = 1; - } - } - """, - """ - class Class + void M() { - int Property { get; set; }; - - void M() - { - this.Property = 1; - } + [|Property|] = 1; } - """, -CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Suggestion); - } + } + """, + """ + class Class + { + int Property { get; set; }; - [Fact] - public async Task QualifyMemberAccessOnNotificationOptionWarning() - { - await TestAsyncWithOptionAndNotificationOption( - """ - class Class + void M() { - int Property { get; set; }; - - void M() - { - [|Property|] = 1; - } + this.Property = 1; } - """, - """ - class Class - { - int Property { get; set; }; + } + """, +CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Suggestion); + } - void M() - { - this.Property = 1; - } - } - """, -CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Warning); - } + [Fact] + public async Task QualifyMemberAccessOnNotificationOptionWarning() + { + await TestAsyncWithOptionAndNotificationOption( + """ + class Class + { + int Property { get; set; }; - [Fact] - public async Task QualifyMemberAccessOnNotificationOptionError() - { - await TestAsyncWithOptionAndNotificationOption( - """ - class Class + void M() { - int Property { get; set; }; - - void M() - { - [|Property|] = 1; - } + [|Property|] = 1; } - """, - """ - class Class - { - int Property { get; set; }; + } + """, + """ + class Class + { + int Property { get; set; }; - void M() - { - this.Property = 1; - } + void M() + { + this.Property = 1; } - """, -CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Error); - } + } + """, +CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Warning); + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18839")] - [WorkItem("https://github.com/dotnet/roslyn/issues/15325")] - public async Task QualifyInstanceMethodInDelegateCreation() - { - await TestAsyncWithOption( - """ - using System; + [Fact] + public async Task QualifyMemberAccessOnNotificationOptionError() + { + await TestAsyncWithOptionAndNotificationOption( + """ + class Class + { + int Property { get; set; }; - class A + void M() { - int Function(int x) => x + x; - - void Error() - { - var func = new Func([|Function|]); - func(1); - } + [|Property|] = 1; } - """, - """ - using System; + } + """, + """ + class Class + { + int Property { get; set; }; - class A + void M() { - int Function(int x) => x + x; - - void Error() - { - var func = new Func(this.Function); - func(1); - } + this.Property = 1; } - """, + } + """, +CodeStyleOptions2.QualifyPropertyAccess, NotificationOption2.Error); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18839")] + [WorkItem("https://github.com/dotnet/roslyn/issues/15325")] + public async Task QualifyInstanceMethodInDelegateCreation() + { + await TestAsyncWithOption( + """ + using System; + + class A + { + int Function(int x) => x + x; + + void Error() + { + var func = new Func([|Function|]); + func(1); + } + } + """, + """ + using System; + + class A + { + int Function(int x) => x + x; + + void Error() + { + var func = new Func(this.Function); + func(1); + } + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15325")] - public async Task DoNotQualifyStaticMethodInDelegateCreation() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15325")] + public async Task DoNotQualifyStaticMethodInDelegateCreation() + { + await TestMissingAsyncWithOption( + """ + using System; - class A - { - static int Function(int x) => x + x; + class A + { + static int Function(int x) => x + x; - void Error() - { - var func = new Func([|Function|]); - func(1); - } + void Error() + { + var func = new Func([|Function|]); + func(1); } - """, + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] - public async Task DoNotReportToQualify_IfBaseQualificationOnField() - { - await TestMissingAsyncWithOption( - """ - class Base - { - protected int field; - } - class Derived : Base - { - void M() { [|base.field|] = 0; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] + public async Task DoNotReportToQualify_IfBaseQualificationOnField() + { + await TestMissingAsyncWithOption( + """ + class Base + { + protected int field; + } + class Derived : Base + { + void M() { [|base.field|] = 0; } + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] - public async Task DoNotReportToQualify_IfBaseQualificationOnProperty() - { - await TestMissingAsyncWithOption( - """ - class Base - { - protected virtual int Property { get; } - } - class Derived : Base - { - protected override int Property { get { return [|base.Property|]; } } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] + public async Task DoNotReportToQualify_IfBaseQualificationOnProperty() + { + await TestMissingAsyncWithOption( + """ + class Base + { + protected virtual int Property { get; } + } + class Derived : Base + { + protected override int Property { get { return [|base.Property|]; } } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] - public async Task DoNotReportToQualify_IfBaseQualificationOnMethod() - { - await TestMissingAsyncWithOption( - """ - class Base - { - protected virtual void M() { } - } - class Derived : Base - { - protected override void M() { [|base.M()|]; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] + public async Task DoNotReportToQualify_IfBaseQualificationOnMethod() + { + await TestMissingAsyncWithOption( + """ + class Base + { + protected virtual void M() { } + } + class Derived : Base + { + protected override void M() { [|base.M()|]; } + } + """, CodeStyleOptions2.QualifyMethodAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] - public async Task DoNotReportToQualify_IfBaseQualificationOnEvent() - { - await TestMissingAsyncWithOption( - """ - class Base - { - protected virtual event EventHandler Event; - } - class Derived : Base - { - protected override event EventHandler Event - { - add { [|base.Event|] += value; } - remove { } - } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17711")] + public async Task DoNotReportToQualify_IfBaseQualificationOnEvent() + { + await TestMissingAsyncWithOption( + """ + class Base + { + protected virtual event EventHandler Event; + } + class Derived : Base + { + protected override event EventHandler Event + { + add { [|base.Event|] += value; } + remove { } + } + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task DoNotReportToQualify_IfInStaticContext1() - { - await TestMissingAsyncWithOption( - """ - class Program - { - public int Foo { get; set; } - public static string Bar = nameof([|Foo|]); - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task DoNotReportToQualify_IfInStaticContext1() + { + await TestMissingAsyncWithOption( + """ + class Program + { + public int Foo { get; set; } + public static string Bar = nameof([|Foo|]); + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task DoNotReportToQualify_IfInStaticContext2() - { - await TestMissingAsyncWithOption( - """ - class Program - { - public int Foo { get; set; } - public string Bar = nameof([|Foo|]); - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task DoNotReportToQualify_IfInStaticContext2() + { + await TestMissingAsyncWithOption( + """ + class Program + { + public int Foo { get; set; } + public string Bar = nameof([|Foo|]); + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task DoNotReportToQualify_IfInStaticContext3() - { - await TestMissingAsyncWithOption( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task DoNotReportToQualify_IfInStaticContext3() + { + await TestMissingAsyncWithOption( + """ + class Program + { + public int Foo { get; set; } + static void Main(string[] args) { - public int Foo { get; set; } - static void Main(string[] args) - { - System.Console.WriteLine(nameof([|Foo|])); - } + System.Console.WriteLine(nameof([|Foo|])); } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task DoNotReportToQualify_IfInStaticContext4() - { - await TestMissingAsyncWithOption( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task DoNotReportToQualify_IfInStaticContext4() + { + await TestMissingAsyncWithOption( + """ + class Program + { + public int Foo; + static void Main(string[] args) { - public int Foo; - static void Main(string[] args) - { - System.Console.WriteLine(nameof([|Foo|])); - } + System.Console.WriteLine(nameof([|Foo|])); } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task DoNotReportToQualify_IfInStaticContext5() - { - await TestMissingAsyncWithOption( - """ - class Program - { - public int Foo { get; set; } - static string Bar { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task DoNotReportToQualify_IfInStaticContext5() + { + await TestMissingAsyncWithOption( + """ + class Program + { + public int Foo { get; set; } + static string Bar { get; set; } - static Program() - { - Bar = nameof([|Foo|]); - } + static Program() + { + Bar = nameof([|Foo|]); } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task DoNotReportToQualify_IfInStaticContext6() - { - await TestMissingAsyncWithOption( - """ - public class Foo - { - public event EventHandler Bar; + } - private string Field = nameof([|Bar|]); - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task DoNotReportToQualify_IfInStaticContext6() + { + await TestMissingAsyncWithOption( + """ + public class Foo + { + public event EventHandler Bar; + + private string Field = nameof([|Bar|]); + } + """, CodeStyleOptions2.QualifyEventAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32093")] - public async Task DoNotReportToQualify_IfInBaseConstructor() - { - await TestMissingAsyncWithOption( - """ - public class Base - { - public string Foo { get; } - public Base(string foo){} - } - public class Derived : Base - { - public Derived() - : base(nameof([|Foo|])) - {} - } - """, - CodeStyleOptions2.QualifyFieldAccess); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32093")] + public async Task DoNotReportToQualify_IfInBaseConstructor() + { + await TestMissingAsyncWithOption( + """ + public class Base + { + public string Foo { get; } + public Base(string foo){} + } + public class Derived : Base + { + public Derived() + : base(nameof([|Foo|])) + {} + } + """, + CodeStyleOptions2.QualifyFieldAccess); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task QualifyPropertyAccess_InAccessorExpressionBody() - { - await TestAsyncWithOption( - """ - public class C - { - public string Foo { get; set; } - public string Bar { get => [|Foo|]; } - } - """, - """ - public class C - { - public string Foo { get; set; } - public string Bar { get => this.Foo; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task QualifyPropertyAccess_InAccessorExpressionBody() + { + await TestAsyncWithOption( + """ + public class C + { + public string Foo { get; set; } + public string Bar { get => [|Foo|]; } + } + """, + """ + public class C + { + public string Foo { get; set; } + public string Bar { get => this.Foo; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task QualifyPropertyAccess_InAccessorWithBodyAndExpressionBody1() - { - await TestAsyncWithOption( - """ - public class C - { - public string Foo { get; set; } - public string Bar { get { return [|Foo|]; } => Foo; } - } - """, - """ - public class C - { - public string Foo { get; set; } - public string Bar { get { return this.Foo; } => Foo; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task QualifyPropertyAccess_InAccessorWithBodyAndExpressionBody1() + { + await TestAsyncWithOption( + """ + public class C + { + public string Foo { get; set; } + public string Bar { get { return [|Foo|]; } => Foo; } + } + """, + """ + public class C + { + public string Foo { get; set; } + public string Bar { get { return this.Foo; } => Foo; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] - public async Task QualifyPropertyAccess_InAccessorWithBodyAndExpressionBody2() - { - await TestAsyncWithOption( - """ - public class C - { - public string Foo { get; set; } - public string Bar { get { return Foo; } => [|Foo|]; } - } - """, - """ - public class C - { - public string Foo { get; set; } - public string Bar { get { return Foo; } => this.Foo; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21519")] + public async Task QualifyPropertyAccess_InAccessorWithBodyAndExpressionBody2() + { + await TestAsyncWithOption( + """ + public class C + { + public string Foo { get; set; } + public string Bar { get { return Foo; } => [|Foo|]; } + } + """, + """ + public class C + { + public string Foo { get; set; } + public string Bar { get { return Foo; } => this.Foo; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyPropertyAccess_InObjectInitializer() - { - await TestAsyncWithOption( - """ - class C - { - public int Foo { get; set } - void M() - { - var test = new System.Collections.Generic.List { [|Foo|] }; - } - } - """, - """ - class C - { - public int Foo { get; set } - void M() - { - var test = new System.Collections.Generic.List { this.Foo }; - } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyPropertyAccess_InObjectInitializer() + { + await TestAsyncWithOption( + """ + class C + { + public int Foo { get; set } + void M() + { + var test = new System.Collections.Generic.List { [|Foo|] }; + } + } + """, + """ + class C + { + public int Foo { get; set } + void M() + { + var test = new System.Collections.Generic.List { this.Foo }; + } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] - public async Task QualifyPropertyAccess_InCollectionInitializer() - { - await TestAsyncWithOption( - """ - class C - { - public int Foo { get; set } - void M() - { - var test = new System.Collections.Generic.List { [|Foo|] }; - } - } - """, - """ - class C - { - public int Foo { get; set } - void M() - { - var test = new System.Collections.Generic.List { this.Foo }; - } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28509")] + public async Task QualifyPropertyAccess_InCollectionInitializer() + { + await TestAsyncWithOption( + """ + class C + { + public int Foo { get; set } + void M() + { + var test = new System.Collections.Generic.List { [|Foo|] }; + } + } + """, + """ + class C + { + public int Foo { get; set } + void M() + { + var test = new System.Collections.Generic.List { this.Foo }; + } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22776")] - public async Task DoNotReportToQualify_InObjectInitializer1() - { - await TestMissingAsyncWithOption( - """ - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22776")] + public async Task DoNotReportToQualify_InObjectInitializer1() + { + await TestMissingAsyncWithOption( + """ + public class C + { + public string Foo { get; set; } + public void Bar() { - public string Foo { get; set; } - public void Bar() + var c = new C { - var c = new C - { - [|Foo|] = string.Empty - }; - } + [|Foo|] = string.Empty + }; } - """, + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22776")] - public async Task DoNotReportToQualify_InObjectInitializer2() - { - await TestMissingAsyncWithOption( - """ - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22776")] + public async Task DoNotReportToQualify_InObjectInitializer2() + { + await TestMissingAsyncWithOption( + """ + public class C + { + public string Foo; + public void Bar() { - public string Foo; - public void Bar() + var c = new C { - var c = new C - { - [|Foo|] = string.Empty - }; - } + [|Foo|] = string.Empty + }; } - """, + } + """, CodeStyleOptions2.QualifyFieldAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22776")] - [WorkItem("https://github.com/dotnet/roslyn/issues/64374")] - public async Task DoReportToQualify_InObjectInitializer2() - { - await TestAsyncWithOption( - """ - public class C - { - public string Foo; - public void Bar() - { - var c = new C - { - Foo = [|Foo|] - }; - } - } - """, - """ - public class C - { - public string Foo; - public void Bar() - { - var c = new C - { - Foo = this.Foo - }; - } - } - """, - CodeStyleOptions2.QualifyFieldAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] - public async Task DoNotReportToQualify_IfInAttribute1() - { - await TestMissingAsyncWithOption( - """ - using System; + } - class MyAttribute : Attribute - { - public MyAttribute(string name) { } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22776")] + [WorkItem("https://github.com/dotnet/roslyn/issues/64374")] + public async Task DoReportToQualify_InObjectInitializer2() + { + await TestAsyncWithOption( + """ + public class C + { + public string Foo; + public void Bar() + { + var c = new C + { + Foo = [|Foo|] + }; + } + } + """, + """ + public class C + { + public string Foo; + public void Bar() + { + var c = new C + { + Foo = this.Foo + }; + } + } + """, + CodeStyleOptions2.QualifyFieldAccess); + } - [My(nameof([|Goo|]))] - class Program - { - int Goo { get; set; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] + public async Task DoNotReportToQualify_IfInAttribute1() + { + await TestMissingAsyncWithOption( + """ + using System; + + class MyAttribute : Attribute + { + public MyAttribute(string name) { } + } + + [My(nameof([|Goo|]))] + class Program + { + int Goo { get; set; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] - public async Task DoNotReportToQualify_IfInAttribute2() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] + public async Task DoNotReportToQualify_IfInAttribute2() + { + await TestMissingAsyncWithOption( + """ + using System; - class MyAttribute : Attribute - { - public MyAttribute(string name) { } - } + class MyAttribute : Attribute + { + public MyAttribute(string name) { } + } - class Program - { - [My(nameof([|Goo|]))] - int Goo { get; set; } - } - """, + class Program + { + [My(nameof([|Goo|]))] + int Goo { get; set; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] - public async Task DoNotReportToQualify_IfInAttribute3() - { - await TestMissingAsyncWithOption( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] + public async Task DoNotReportToQualify_IfInAttribute3() + { + await TestMissingAsyncWithOption( + """ + using System; - class MyAttribute : Attribute - { - public MyAttribute(string name) { } - } + class MyAttribute : Attribute + { + public MyAttribute(string name) { } + } - class Program - { - [My(nameof([|Goo|]))] - public int Bar = 0 ; - public int Goo { get; set; } - } - """, + class Program + { + [My(nameof([|Goo|]))] + public int Bar = 0 ; + public int Goo { get; set; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] - public async Task DoNotReportToQualify_IfInAttribute4() - { - await TestMissingAsyncWithOption( - """ - using System; - - class MyAttribute : Attribute - { - public MyAttribute(string name) { } - } + } - class Program - { - int Goo { [My(nameof([|Goo|]))]get; set; } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] + public async Task DoNotReportToQualify_IfInAttribute4() + { + await TestMissingAsyncWithOption( + """ + using System; + + class MyAttribute : Attribute + { + public MyAttribute(string name) { } + } + + class Program + { + int Goo { [My(nameof([|Goo|]))]get; set; } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] - public async Task DoNotReportToQualify_IfInAttribute5() - { - await TestMissingAsyncWithOption( - """ - using System; - - class MyAttribute : Attribute - { - public MyAttribute(string name) { } - } + } - class Program - { - int Goo { get; set; } - void M([My(nameof([|Goo|]))]int i) { } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26893")] + public async Task DoNotReportToQualify_IfInAttribute5() + { + await TestMissingAsyncWithOption( + """ + using System; + + class MyAttribute : Attribute + { + public MyAttribute(string name) { } + } + + class Program + { + int Goo { get; set; } + void M([My(nameof([|Goo|]))]int i) { } + } + """, CodeStyleOptions2.QualifyPropertyAccess); - } } } diff --git a/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests_FixAllTests.cs index b796f7f7fa14d..e10214afc70e1 100644 --- a/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/QualifyMemberAccess/QualifyMemberAccessTests_FixAllTests.cs @@ -11,93 +11,92 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.QualifyMemberAccess +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.QualifyMemberAccess; + +public partial class QualifyMemberAccessTests { - public partial class QualifyMemberAccessTests + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsQualifyMemberAccess)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution_QualifyMemberAccess() { - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsQualifyMemberAccess)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution_QualifyMemberAccess() - { - var input = """ - - - - using System; + var input = """ + + + + using System; - class C - { - int Property { get; set; } - int OtherProperty { get; set; } + class C + { + int Property { get; set; } + int OtherProperty { get; set; } - void M() - { - {|FixAllInSolution:Property|} = 1; - var x = OtherProperty; - } + void M() + { + {|FixAllInSolution:Property|} = 1; + var x = OtherProperty; } - - - using System; + } + + + using System; - class D - { - string StringProperty { get; set; } - int field; + class D + { + string StringProperty { get; set; } + int field; - void N() - { - StringProperty = string.Empty; - field = 0; // ensure this doesn't get qualified - } + void N() + { + StringProperty = string.Empty; + field = 0; // ensure this doesn't get qualified } - - - - """; + } + + + + """; - var expected = """ - - - - using System; + var expected = """ + + + + using System; - class C - { - int Property { get; set; } - int OtherProperty { get; set; } + class C + { + int Property { get; set; } + int OtherProperty { get; set; } - void M() - { - this.Property = 1; - var x = this.OtherProperty; - } + void M() + { + this.Property = 1; + var x = this.OtherProperty; } - - - using System; + } + + + using System; - class D - { - string StringProperty { get; set; } - int field; + class D + { + string StringProperty { get; set; } + int field; - void N() - { - this.StringProperty = string.Empty; - field = 0; // ensure this doesn't get qualified - } + void N() + { + this.StringProperty = string.Empty; + field = 0; // ensure this doesn't get qualified } - - - - """; + } + + + + """; - await TestInRegularAndScriptAsync( - initialMarkup: input, - expectedMarkup: expected, - options: Option(CodeStyleOptions2.QualifyPropertyAccess, true, NotificationOption2.Suggestion)); - } + await TestInRegularAndScriptAsync( + initialMarkup: input, + expectedMarkup: expected, + options: Option(CodeStyleOptions2.QualifyPropertyAccess, true, NotificationOption2.Suggestion)); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveAsyncModifier/RemoveAsyncModifierTests.cs b/src/Analyzers/CSharp/Tests/RemoveAsyncModifier/RemoveAsyncModifierTests.cs index d059a959a662b..147d114808c47 100644 --- a/src/Analyzers/CSharp/Tests/RemoveAsyncModifier/RemoveAsyncModifierTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveAsyncModifier/RemoveAsyncModifierTests.cs @@ -10,1256 +10,1257 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveAsyncModifier -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpRemoveAsyncModifierCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveAsyncModifier; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpRemoveAsyncModifierCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveAsyncModifier)] - public class RemoveAsyncModifierTests : CodeAnalysis.CSharp.Test.Utilities.CSharpTestBase +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveAsyncModifier)] +public class RemoveAsyncModifierTests : CodeAnalysis.CSharp.Test.Utilities.CSharpTestBase +{ + [Fact] + public async Task Method_Task_MultipleAndNested() { - [Fact] - public async Task Method_Task_MultipleAndNested() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() + if (DateTime.Now.Ticks > 0) { - if (DateTime.Now.Ticks > 0) - { - return; - } + return; } + } - async Task {|CS1998:Foo|}() - { - Console.WriteLine(1); - } + async Task {|CS1998:Foo|}() + { + Console.WriteLine(1); + } - async Task {|CS1998:Bar|}() + async Task {|CS1998:Bar|}() + { + async Task {|CS1998:Baz|}() { - async Task {|CS1998:Baz|}() - { - Func> g = async () {|CS1998:=>|} 5; - } + Func> g = async () {|CS1998:=>|} 5; } + } - async Task {|CS1998:Tur|}() + async Task {|CS1998:Tur|}() + { + async Task {|CS1998:Duck|}() { - async Task {|CS1998:Duck|}() + async Task {|CS1998:En|}() { - async Task {|CS1998:En|}() - { - return "Developers!"; - } - - return "Developers! Developers!"; + return "Developers!"; } - return "Developers! Developers! Developers!"; + return "Developers! Developers!"; } - async Task {|CS1998:Nurk|}() - { - Func> f = async () {|CS1998:=>|} 4; - - if (DateTime.Now.Ticks > f().Result) - { - } - } + return "Developers! Developers! Developers!"; } - """, - """ - using System; - using System.Threading.Tasks; - class C + async Task {|CS1998:Nurk|}() { - Task Goo() - { - if (DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } + Func> f = async () {|CS1998:=>|} 4; - return Task.CompletedTask; + if (DateTime.Now.Ticks > f().Result) + { } + } + } + """, + """ + using System; + using System.Threading.Tasks; - Task Foo() + class C + { + Task Goo() + { + if (DateTime.Now.Ticks > 0) { - Console.WriteLine(1); return Task.CompletedTask; } - Task Bar() - { - Task Baz() - { - Func> g = () => Task.FromResult(5); - return Task.CompletedTask; - } + return Task.CompletedTask; + } + Task Foo() + { + Console.WriteLine(1); + return Task.CompletedTask; + } + + Task Bar() + { + Task Baz() + { + Func> g = () => Task.FromResult(5); return Task.CompletedTask; } - Task Tur() + return Task.CompletedTask; + } + + Task Tur() + { + Task Duck() { - Task Duck() + Task En() { - Task En() - { - return Task.FromResult("Developers!"); - } - - return Task.FromResult("Developers! Developers!"); + return Task.FromResult("Developers!"); } - return Task.FromResult("Developers! Developers! Developers!"); + return Task.FromResult("Developers! Developers!"); } - Task Nurk() - { - Func> f = () => Task.FromResult(4); + return Task.FromResult("Developers! Developers! Developers!"); + } - if (DateTime.Now.Ticks > f().Result) - { - } + Task Nurk() + { + Func> f = () => Task.FromResult(4); - return Task.CompletedTask; + if (DateTime.Now.Ticks > f().Result) + { } + + return Task.CompletedTask; } - """); - } + } + """); + } - [Fact] - public async Task Method_Task_EmptyBlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task Method_Task_EmptyBlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C - { - async Task {|CS1998:Goo|}(){} - } - """, - """ - using System.Threading.Tasks; + class C + { + async Task {|CS1998:Goo|}(){} + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - Task Goo() - { - return Task.CompletedTask; - } + return Task.CompletedTask; } - """); - } + } + """); + } - [Fact] - public async Task Method_Task_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task Method_Task_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return; - } + return; } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - Task Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } - return Task.CompletedTask; } + + return Task.CompletedTask; } - """); - } + } + """); + } - [Fact] - public async Task Method_ValueTask_BlockBody() - { - var source = """ - using System.Threading.Tasks; + [Fact] + public async Task Method_ValueTask_BlockBody() + { + var source = """ + using System.Threading.Tasks; - class C + class C + { + async ValueTask {|CS1998:Goo|}() { - async ValueTask {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return; - } + return; } } - """; + } + """; - var expected = """ - using System.Threading.Tasks; + var expected = """ + using System.Threading.Tasks; - class C + class C + { + ValueTask Goo() { - ValueTask Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return new ValueTask(); - } - return new ValueTask(); } - } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - FixedCode = expected, - }.RunAsync(); - } + return new ValueTask(); + } + } + """; - [Fact] - public async Task Method_ValueTaskOfT_BlockBody() + await new VerifyCS.Test { - var source = """ - using System.Threading.Tasks; + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + FixedCode = expected, + }.RunAsync(); + } - class C + [Fact] + public async Task Method_ValueTaskOfT_BlockBody() + { + var source = """ + using System.Threading.Tasks; + + class C + { + async ValueTask {|CS1998:Goo|}() { - async ValueTask {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return 2; - } - - return 3; + return 2; } + + return 3; } - """; - var expected = """ - using System.Threading.Tasks; + } + """; + var expected = """ + using System.Threading.Tasks; - class C + class C + { + ValueTask Goo() { - ValueTask Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return new ValueTask(2); - } - - return new ValueTask(3); + return new ValueTask(2); } - } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - FixedCode = expected, - }.RunAsync(); - } + return new ValueTask(3); + } + } + """; - [Fact] - public async Task Method_ValueTask_ExpressionBody() + await new VerifyCS.Test { - var source = """ - using System.Threading.Tasks; + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + FixedCode = expected, + }.RunAsync(); + } - class C - { - async ValueTask {|CS1998:Goo|}() => System.Console.WriteLine(1); - } - """; + [Fact] + public async Task Method_ValueTask_ExpressionBody() + { + var source = """ + using System.Threading.Tasks; - var expected = """ - using System.Threading.Tasks; + class C + { + async ValueTask {|CS1998:Goo|}() => System.Console.WriteLine(1); + } + """; - class C - { - ValueTask Goo() - { - System.Console.WriteLine(1); - return new ValueTask(); - } - } - """; + var expected = """ + using System.Threading.Tasks; - await new VerifyCS.Test + class C { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - FixedCode = expected, - }.RunAsync(); - } + ValueTask Goo() + { + System.Console.WriteLine(1); + return new ValueTask(); + } + } + """; - [Fact] - public async Task Method_ValueTaskOfT_ExpressionBody() + await new VerifyCS.Test { - var source = """ - using System.Threading.Tasks; + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + FixedCode = expected, + }.RunAsync(); + } - class C - { - async ValueTask {|CS1998:Goo|}() => 3; - } - """; + [Fact] + public async Task Method_ValueTaskOfT_ExpressionBody() + { + var source = """ + using System.Threading.Tasks; - var expected = """ - using System.Threading.Tasks; + class C + { + async ValueTask {|CS1998:Goo|}() => 3; + } + """; - class C - { - ValueTask Goo() => new ValueTask(3); - } - """; + var expected = """ + using System.Threading.Tasks; - await new VerifyCS.Test + class C { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - FixedCode = expected, - }.RunAsync(); - } + ValueTask Goo() => new ValueTask(3); + } + """; - [Fact] - public async Task Method_Task_BlockBody_Throws() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + FixedCode = expected, + }.RunAsync(); + } - class C + [Fact] + public async Task Method_Task_BlockBody_Throws() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; + + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return; - } - - throw new System.ApplicationException(); + return; } + + throw new System.ApplicationException(); } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - Task Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } - - throw new System.ApplicationException(); + return Task.CompletedTask; } + + throw new System.ApplicationException(); } - """); - } + } + """); + } - [Fact] - public async Task Method_Task_BlockBody_WithLocalFunction() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task Method_Task_BlockBody_WithLocalFunction() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() + if (GetTicks() > 0) { - if (GetTicks() > 0) - { - return; - } + return; + } - long GetTicks() - { - return System.DateTime.Now.Ticks; - } + long GetTicks() + { + return System.DateTime.Now.Ticks; } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - Task Goo() + if (GetTicks() > 0) { - if (GetTicks() > 0) - { - return Task.CompletedTask; - } - - long GetTicks() - { - return System.DateTime.Now.Ticks; - } - return Task.CompletedTask; } + + long GetTicks() + { + return System.DateTime.Now.Ticks; + } + + return Task.CompletedTask; } - """); - } + } + """); + } - [Fact] - public async Task Method_Task_BlockBody_WithLambda() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task Method_Task_BlockBody_WithLambda() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() - { - System.Func getTicks = () => { - return System.DateTime.Now.Ticks; - }; - - if (getTicks() > 0) - { - return; - } + System.Func getTicks = () => { + return System.DateTime.Now.Ticks; + }; + if (getTicks() > 0) + { + return; } + } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - Task Goo() - { - System.Func getTicks = () => { - return System.DateTime.Now.Ticks; - }; - - if (getTicks() > 0) - { - return Task.CompletedTask; - } + System.Func getTicks = () => { + return System.DateTime.Now.Ticks; + }; + if (getTicks() > 0) + { return Task.CompletedTask; } + + return Task.CompletedTask; } - """); - } + } + """); + } - [Fact] - public async Task Method_TaskOfT_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task Method_TaskOfT_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return 2; - } - - return 3; + return 2; } + + return 3; } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - Task Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return Task.FromResult(2); - } - - return Task.FromResult(3); + return Task.FromResult(2); } - } - """); - } - - [Fact] - public async Task Method_TaskOfT_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; - class C - { - async Task {|CS1998:Goo|}() => 2; + return Task.FromResult(3); } - """, - """ - using System.Threading.Tasks; + } + """); + } - class C - { - Task Goo() => Task.FromResult(2); - } - """); - } + [Fact] + public async Task Method_TaskOfT_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - [Fact] - public async Task Method_Task_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + class C + { + async Task {|CS1998:Goo|}() => 2; + } + """, + """ + using System.Threading.Tasks; - class C - { - async Task {|CS1998:Goo|}() => Console.WriteLine("Hello"); - } - """, - """ - using System; - using System.Threading.Tasks; + class C + { + Task Goo() => Task.FromResult(2); + } + """); + } + + [Fact] + public async Task Method_Task_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + async Task {|CS1998:Goo|}() => Console.WriteLine("Hello"); + } + """, + """ + using System; + using System.Threading.Tasks; + + class C + { + Task Goo() { - Task Goo() - { - Console.WriteLine("Hello"); - return Task.CompletedTask; - } + Console.WriteLine("Hello"); + return Task.CompletedTask; } - """); - } + } + """); + } - [Fact] - public async Task LocalFunction_Task_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task LocalFunction_Task_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return; - } + return; } } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Task Goo() { - Task Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } - return Task.CompletedTask; } + + return Task.CompletedTask; } } - """); - } + } + """); + } - [Fact] - public async Task LocalFunction_Task_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task LocalFunction_Task_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - async Task {|CS1998:Goo|}() => Console.WriteLine(1); - } + async Task {|CS1998:Goo|}() => Console.WriteLine(1); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Task Goo() { Console.WriteLine(1); return Task.CompletedTask; } - } + Task Goo() { Console.WriteLine(1); return Task.CompletedTask; } } - """); - } + } + """); + } - [Fact] - public async Task LocalFunction_TaskOfT_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task LocalFunction_TaskOfT_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + async Task {|CS1998:Goo|}() { - async Task {|CS1998:Goo|}() - { - return 1; - } + return 1; } } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Task Goo() { - Task Goo() - { - return Task.FromResult(1); - } + return Task.FromResult(1); } } - """); - } + } + """); + } - [Fact] - public async Task LocalFunction_TaskOfT_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System.Threading.Tasks; + [Fact] + public async Task LocalFunction_TaskOfT_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - async Task {|CS1998:Goo|}() => 1; - } + async Task {|CS1998:Goo|}() => 1; } - """, - """ - using System.Threading.Tasks; + } + """, + """ + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Task Goo() => Task.FromResult(1); - } + Task Goo() => Task.FromResult(1); } - """); - } + } + """); + } - [Fact] - public async Task AnonymousFunction_Task_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task AnonymousFunction_Task_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func foo = (Func)async {|CS1998:delegate|} { - if (System.DateTime.Now.Ticks > 0) - { - return; - } - }; - } + Func foo = (Func)async {|CS1998:delegate|} { + if (System.DateTime.Now.Ticks > 0) + { + return; + } + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func foo = (Func)delegate { - Func foo = (Func)delegate + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } - return Task.CompletedTask; - }; - } + } + + return Task.CompletedTask; + }; } - """); - } + } + """); + } - [Fact] - public async Task AnonymousFunction_TaskOfT_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task AnonymousFunction_TaskOfT_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func> foo = (Func>)async {|CS1998:delegate|} { - Func> foo = (Func>)async {|CS1998:delegate|} - { - return 1; - }; - } + return 1; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func> foo = (Func>)delegate { - Func> foo = (Func>)delegate - { - return Task.FromResult(1); - }; - } + return Task.FromResult(1); + }; } - """); - } + } + """); + } - [Fact] - public async Task SimpleLambda_TaskOfT_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task SimpleLambda_TaskOfT_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func> foo = async x {|CS1998:=>|} 1; - } + Func> foo = async x {|CS1998:=>|} 1; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func> foo = x => Task.FromResult(1); - } + Func> foo = x => Task.FromResult(1); } - """); - } + } + """); + } - [Fact] - public async Task SimpleLambda_TaskOfT_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task SimpleLambda_TaskOfT_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func> foo = async x {|CS1998:=>|} { - return 1; - }; - } + Func> foo = async x {|CS1998:=>|} { + return 1; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func> foo = x => { - Func> foo = x => - { - return Task.FromResult(1); - }; - } + return Task.FromResult(1); + }; } - """); - } + } + """); + } - [Fact] - public async Task SimpleLambda_Task_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task SimpleLambda_Task_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func foo = async x {|CS1998:=>|} Console.WriteLine(1); - } + Func foo = async x {|CS1998:=>|} Console.WriteLine(1); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func foo = x => { Console.WriteLine(1); return Task.CompletedTask; }; - } + Func foo = x => { Console.WriteLine(1); return Task.CompletedTask; }; } - """); - } + } + """); + } - [Fact] - public async Task SimpleLambda_Task_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task SimpleLambda_Task_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func foo = async x {|CS1998:=>|} { - Func foo = async x {|CS1998:=>|} + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return; - } - }; - } + return; + } + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func foo = x => { - Func foo = x => { - if (System.DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } - + if (System.DateTime.Now.Ticks > 0) + { return Task.CompletedTask; - }; - } - } - """); - } - - [Fact] - public async Task ParenthesisedLambda_TaskOfT_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; - - class C - { - public void M1() - { - Func> foo = async () {|CS1998:=>|} 1; - } - } - """, - """ - using System; - using System.Threading.Tasks; + } - class C - { - public void M1() - { - Func> foo = () => Task.FromResult(1); - } + return Task.CompletedTask; + }; } - """); - } + } + """); + } - [Fact] - public async Task ParenthesisedLambda_TaskOfT_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task ParenthesisedLambda_TaskOfT_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func> foo = async () {|CS1998:=>|} { - return 1; - }; - } + Func> foo = async () {|CS1998:=>|} 1; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func> foo = () => - { - return Task.FromResult(1); - }; - } + Func> foo = () => Task.FromResult(1); } - """); - } + } + """); + } - [Fact] - public async Task ParenthesisedLambda_Task_ExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task ParenthesisedLambda_TaskOfT_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func foo = async () {|CS1998:=>|} Console.WriteLine(1); - } + Func> foo = async () {|CS1998:=>|} { + return 1; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() + Func> foo = () => { - Func foo = () => { Console.WriteLine(1); return Task.CompletedTask; }; - } + return Task.FromResult(1); + }; } - """); - } + } + """); + } - [Fact] - public async Task ParenthesisedLambda_Task_BlockBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task ParenthesisedLambda_Task_ExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func foo = async () {|CS1998:=>|} - { - if (System.DateTime.Now.Ticks > 0) - { - return; - } - }; - } + Func foo = async () {|CS1998:=>|} Console.WriteLine(1); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public void M1() { - public void M1() - { - Func foo = () => { - if (System.DateTime.Now.Ticks > 0) - { - return Task.CompletedTask; - } - - return Task.CompletedTask; - }; - } + Func foo = () => { Console.WriteLine(1); return Task.CompletedTask; }; } - """); - } + } + """); + } - [Fact] - public async Task Method_Task_BlockBody_FullyQualified() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task ParenthesisedLambda_Task_BlockBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + public void M1() { - async System.Threading.Tasks.Task {|CS1998:Goo|}() + Func foo = async () {|CS1998:=>|} { if (System.DateTime.Now.Ticks > 0) { return; } - } + }; } - """, - """ - class C + } + """, + """ + using System; + using System.Threading.Tasks; + + class C + { + public void M1() { - System.Threading.Tasks.Task Goo() + Func foo = () => { if (System.DateTime.Now.Ticks > 0) { - return System.Threading.Tasks.Task.CompletedTask; + return Task.CompletedTask; } - return System.Threading.Tasks.Task.CompletedTask; - } + return Task.CompletedTask; + }; } - """); - } + } + """); + } - [Fact] - public async Task Method_TaskOfT_BlockBody_FullyQualified() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task Method_Task_BlockBody_FullyQualified() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + async System.Threading.Tasks.Task {|CS1998:Goo|}() { - async System.Threading.Tasks.Task {|CS1998:Goo|}() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return 1; - } - - return 2; + return; } } - """, - """ - class C + } + """, + """ + class C + { + System.Threading.Tasks.Task Goo() { - System.Threading.Tasks.Task Goo() + if (System.DateTime.Now.Ticks > 0) { - if (System.DateTime.Now.Ticks > 0) - { - return System.Threading.Tasks.Task.FromResult(1); - } - - return System.Threading.Tasks.Task.FromResult(2); + return System.Threading.Tasks.Task.CompletedTask; } - } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65536")] - public async Task Method_TaskOfT_BlockBody_QualifyTaskFromResultType() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Threading.Tasks; - using System.Collections.Generic; + return System.Threading.Tasks.Task.CompletedTask; + } + } + """); + } - class C + [Fact] + public async Task Method_TaskOfT_BlockBody_FullyQualified() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + async System.Threading.Tasks.Task {|CS1998:Goo|}() { - public async Task> {|CS1998:M|}() + if (System.DateTime.Now.Ticks > 0) { - return new int[0]; + return 1; } + + return 2; } - """, """ - using System.Threading.Tasks; - using System.Collections.Generic; - - class C + } + """, + """ + class C + { + System.Threading.Tasks.Task Goo() { - public Task> M() + if (System.DateTime.Now.Ticks > 0) { - return Task.FromResult>(new int[0]); + return System.Threading.Tasks.Task.FromResult(1); } + + return System.Threading.Tasks.Task.FromResult(2); } - """); - } + } + """); + } - [Fact] - public async Task IAsyncEnumerable_Missing() - { - var source = """ - using System.Threading.Tasks; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65536")] + public async Task Method_TaskOfT_BlockBody_QualifyTaskFromResultType() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Threading.Tasks; + using System.Collections.Generic; - class C + class C + { + public async Task> {|CS1998:M|}() { - async IAsyncEnumerable M() - { - yield return 1; - } + return new int[0]; } - """ + AsyncStreamsTypes; - - await new VerifyCS.Test + } + """, """ + using System.Threading.Tasks; + using System.Collections.Generic; + + class C { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - ExpectedDiagnostics = + public Task> M() { - // /0/Test0.cs(7,33): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. - DiagnosticResult.CompilerWarning("CS1998").WithSpan(6, 33, 6, 34), - }, - FixedCode = source, - }.RunAsync(); - } + return Task.FromResult>(new int[0]); + } + } + """); + } - [Fact] - public async Task Method_AsyncVoid_Missing() - { - var source = """ - using System.Threading.Tasks; + [Fact] + public async Task IAsyncEnumerable_Missing() + { + var source = """ + using System.Threading.Tasks; + using System.Collections.Generic; - class C + class C + { + async IAsyncEnumerable M() { - async void M() - { - System.Console.WriteLine(1); - } + yield return 1; } - """; + } + """ + AsyncStreamsTypes; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + ExpectedDiagnostics = { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - ExpectedDiagnostics = - { - // /0/Test0.cs(6,16): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. - DiagnosticResult.CompilerWarning("CS1998").WithSpan(5, 16, 5, 17), - }, - FixedCode = source, - }.RunAsync(); - } + // /0/Test0.cs(7,33): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + DiagnosticResult.CompilerWarning("CS1998").WithSpan(6, 33, 6, 34), + }, + FixedCode = source, + }.RunAsync(); + } - [Fact] - public async Task ParenthesisedLambda_AsyncVoid_Missing() - { - var source = """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task Method_AsyncVoid_Missing() + { + var source = """ + using System.Threading.Tasks; - class C + class C + { + async void M() { - void M() - { - Action a = async () => Console.WriteLine(1); - } + System.Console.WriteLine(1); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + ExpectedDiagnostics = { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - ExpectedDiagnostics = + // /0/Test0.cs(6,16): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + DiagnosticResult.CompilerWarning("CS1998").WithSpan(5, 16, 5, 17), + }, + FixedCode = source, + }.RunAsync(); + } + + [Fact] + public async Task ParenthesisedLambda_AsyncVoid_Missing() + { + var source = """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - // /0/Test0.cs(9,29): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. - DiagnosticResult.CompilerWarning("CS1998").WithSpan(8, 29, 8, 31), - }, - FixedCode = source, - }.RunAsync(); - } + Action a = async () => Console.WriteLine(1); + } + } + """; - [Fact] - public async Task SimpleLambda_AsyncVoid_Missing() + await new VerifyCS.Test { - var source = """ - using System; - using System.Threading.Tasks; + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + ExpectedDiagnostics = + { + // /0/Test0.cs(9,29): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + DiagnosticResult.CompilerWarning("CS1998").WithSpan(8, 29, 8, 31), + }, + FixedCode = source, + }.RunAsync(); + } - class C + [Fact] + public async Task SimpleLambda_AsyncVoid_Missing() + { + var source = """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() - { - Action a = async x => Console.WriteLine(x); - } + Action a = async x => Console.WriteLine(x); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, + TestCode = source, + ExpectedDiagnostics = { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard21, - TestCode = source, - ExpectedDiagnostics = - { - // /0/Test0.cs(9,33): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. - DiagnosticResult.CompilerWarning("CS1998").WithSpan(8, 33, 8, 35), - }, - FixedCode = source, - }.RunAsync(); - } + // /0/Test0.cs(9,33): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. + DiagnosticResult.CompilerWarning("CS1998").WithSpan(8, 33, 8, 35), + }, + FixedCode = source, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveConfusingSuppression/RemoveConfusingSuppressionTests.cs b/src/Analyzers/CSharp/Tests/RemoveConfusingSuppression/RemoveConfusingSuppressionTests.cs index db7676a6d0251..c13ff4ee715da 100644 --- a/src/Analyzers/CSharp/Tests/RemoveConfusingSuppression/RemoveConfusingSuppressionTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveConfusingSuppression/RemoveConfusingSuppressionTests.cs @@ -9,369 +9,368 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Confusing -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Confusing; + +using VerifyCS = CSharpCodeFixVerifier; - public class RemoveConfusingSuppressionTests +public class RemoveConfusingSuppressionTests +{ + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestRemoveWithIsExpression1() { - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestRemoveWithIsExpression1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(object o) { - void M(object o) + if (o [|!|]is string) { - if (o [|!|]is string) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) + if (o is string) { - if (o is string) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestRemoveWithIsPattern1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestRemoveWithIsPattern1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(object o) { - void M(object o) + if (o [|!|]is string s) { - if (o [|!|]is string s) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) + if (o is string s) { - if (o is string s) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestNegateWithIsExpression_CSharp8() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestNegateWithIsExpression_CSharp8() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string) { - if (o [|!|]is string) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (!(o is string)) { - if (!(o is string)) - { - } } } - """, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp8 - }.RunAsync(); - } + } + """, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp8 + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestNegateWithIsPattern_CSharp8() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestNegateWithIsPattern_CSharp8() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string s) { - if (o [|!|]is string s) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (!(o is string s)) { - if (!(o is string s)) - { - } } } - """, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + } + """, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestNegateWithIsExpression_CSharp9() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestNegateWithIsExpression_CSharp9() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string) { - if (o [|!|]is string) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (o is not string) { - if (o is not string) - { - } } } - """, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestNegateWithIsPattern_CSharp9() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestNegateWithIsPattern_CSharp9() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string s) { - if (o [|!|]is string s) - { - } } } - """, - FixedState = + } + """, + FixedState = + { + Sources = { - Sources = + """ + class C { - """ - class C + void M(object o) { - void M(object o) + if (o is not string s) { - if (o is not string s) - { - } } } - """ - }, + } + """ }, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + }, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestRemoveWithIsExpression_FixAll1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestRemoveWithIsExpression_FixAll1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string) + { + } + if (o [|!|]is string) { - if (o [|!|]is string) - { - } - if (o [|!|]is string) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (o is string) + { + } + if (o is string) { - if (o is string) - { - } - if (o is string) - { - } } } - """, - NumberOfFixAllIterations = 1, - CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.RemoveOperator, - }.RunAsync(); - } + } + """, + NumberOfFixAllIterations = 1, + CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.RemoveOperator, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestNegateWithIsExpression_FixAll1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestNegateWithIsExpression_FixAll1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string) + { + } + if (o [|!|]is string) { - if (o [|!|]is string) - { - } - if (o [|!|]is string) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (!(o is string)) + { + } + if (!(o is string)) { - if (!(o is string)) - { - } - if (!(o is string)) - { - } } } - """, - CodeActionIndex = 1, - CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.NegateExpression, - NumberOfFixAllIterations = 1, - }.RunAsync(); - } + } + """, + CodeActionIndex = 1, + CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.NegateExpression, + NumberOfFixAllIterations = 1, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestRemoveWithIsPatternExpression_FixAll1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestRemoveWithIsPatternExpression_FixAll1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string s) + { + } + if (o [|!|]is string t) { - if (o [|!|]is string s) - { - } - if (o [|!|]is string t) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (o is string s) + { + } + if (o is string t) { - if (o is string s) - { - } - if (o is string t) - { - } } } - """, - NumberOfFixAllIterations = 1, - CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.RemoveOperator, - }.RunAsync(); - } + } + """, + NumberOfFixAllIterations = 1, + CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.RemoveOperator, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] - public async Task TestNegateWithIsPatternExpression_FixAll1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44872")] + public async Task TestNegateWithIsPatternExpression_FixAll1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - """ - class C + void M(object o) { - void M(object o) + if (o [|!|]is string s) + { + } + if (o [|!|]is string t) { - if (o [|!|]is string s) - { - } - if (o [|!|]is string t) - { - } } } - """, - FixedCode = - """ - class C + } + """, + FixedCode = + """ + class C + { + void M(object o) { - void M(object o) + if (!(o is string s)) + { + } + if (!(o is string t)) { - if (!(o is string s)) - { - } - if (!(o is string t)) - { - } } } - """, - NumberOfFixAllIterations = 1, - CodeActionIndex = 1, - CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.NegateExpression, - }.RunAsync(); - } + } + """, + NumberOfFixAllIterations = 1, + CodeActionIndex = 1, + CodeActionEquivalenceKey = CSharpRemoveConfusingSuppressionCodeFixProvider.NegateExpression, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveInKeyword/RemoveInKeywordCodeFixProviderTests.cs b/src/Analyzers/CSharp/Tests/RemoveInKeyword/RemoveInKeywordCodeFixProviderTests.cs index c4c07a92a359a..e83fc259c0f81 100644 --- a/src/Analyzers/CSharp/Tests/RemoveInKeyword/RemoveInKeywordCodeFixProviderTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveInKeyword/RemoveInKeywordCodeFixProviderTests.cs @@ -11,285 +11,284 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveInKeyword +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveInKeyword; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveInKeyword)] +public class RemoveInKeywordCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveInKeyword)] - public class RemoveInKeywordCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveInKeywordCodeFixProviderTests(ITestOutputHelper logger) + : base(logger) { - public RemoveInKeywordCodeFixProviderTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new RemoveInKeywordCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new RemoveInKeywordCodeFixProvider()); - [Fact] - public async Task TestRemoveInKeyword() - { - await TestInRegularAndScript1Async( - """ - class Class + [Fact] + public async Task TestRemoveInKeyword() + { + await TestInRegularAndScript1Async( + """ + class Class + { + void M(int i) { } + void N(int i) { - void M(int i) { } - void N(int i) - { - M(in [|i|]); - } + M(in [|i|]); } - """, - """ - class Class + } + """, + """ + class Class + { + void M(int i) { } + void N(int i) { - void M(int i) { } - void N(int i) - { - M(i); - } + M(i); } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveInKeywordMultipleArguments1() - { - await TestInRegularAndScript1Async( - """ - class Class + [Fact] + public async Task TestRemoveInKeywordMultipleArguments1() + { + await TestInRegularAndScript1Async( + """ + class Class + { + void M(int i, string s) { } + void N(int i, string s) { - void M(int i, string s) { } - void N(int i, string s) - { - M(in [|i|], s); - } + M(in [|i|], s); } - """, - """ - class Class + } + """, + """ + class Class + { + void M(int i, string s) { } + void N(int i, string s) { - void M(int i, string s) { } - void N(int i, string s) - { - M(i, s); - } + M(i, s); } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveInKeywordMultipleArguments2() - { - await TestInRegularAndScript1Async( - """ - class Class + [Fact] + public async Task TestRemoveInKeywordMultipleArguments2() + { + await TestInRegularAndScript1Async( + """ + class Class + { + void M(int i, int j) { } + void N(int i, int j) { - void M(int i, int j) { } - void N(int i, int j) - { - M(in [|i|], in j); - } + M(in [|i|], in j); } - """, - """ - class Class + } + """, + """ + class Class + { + void M(int i, int j) { } + void N(int i, int j) { - void M(int i, int j) { } - void N(int i, int j) - { - M(i, in j); - } + M(i, in j); } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveInKeywordMultipleArgumentsWithDifferentRefKinds() - { - await TestInRegularAndScript1Async( - """ - class Class + [Fact] + public async Task TestRemoveInKeywordMultipleArgumentsWithDifferentRefKinds() + { + await TestInRegularAndScript1Async( + """ + class Class + { + void M(in int i, string s) { } + void N(int i, string s) { - void M(in int i, string s) { } - void N(int i, string s) - { - M(in i, in [|s|]); - } + M(in i, in [|s|]); } - """, - """ - class Class + } + """, + """ + class Class + { + void M(in int i, string s) { } + void N(int i, string s) { - void M(in int i, string s) { } - void N(int i, string s) - { - M(in i, s); - } + M(in i, s); } - """); - } + } + """); + } - [Fact] - public async Task TestDoNotRemoveInKeyword() - { - await TestMissingInRegularAndScriptAsync( - """ - class Class + [Fact] + public async Task TestDoNotRemoveInKeyword() + { + await TestMissingInRegularAndScriptAsync( + """ + class Class + { + void M(in int i) { } + void N(int i) { - void M(in int i) { } - void N(int i) - { - M(in [|i|]); - } + M(in [|i|]); } - """); - } - - [Theory] - [InlineData("in [|i|]", "i")] - [InlineData(" in [|i|]", " i")] - [InlineData("/* start */in [|i|]", "/* start */i")] - [InlineData("/* start */ in [|i|]", "/* start */ i")] - [InlineData( - "/* start */ in [|i|] /* end */", - "/* start */ i /* end */")] - [InlineData( - "/* start */ in /* middle */ [|i|] /* end */", - "/* start */ i /* end */")] - [InlineData( - "/* start */ in /* middle */ [|i|] /* end */", - "/* start */ i /* end */")] - [InlineData( - "/* start */in /* middle */ [|i|] /* end */", - "/* start */i /* end */")] - public async Task TestRemoveInKeywordWithTrivia(string original, string expected) - { - await TestInRegularAndScript1Async( - $$""" - class App - { - void M(int i) { } - void N(int i) - { - M({{original}}); - } + } + """); + } - } - """, - $$""" - class App + [Theory] + [InlineData("in [|i|]", "i")] + [InlineData(" in [|i|]", " i")] + [InlineData("/* start */in [|i|]", "/* start */i")] + [InlineData("/* start */ in [|i|]", "/* start */ i")] + [InlineData( + "/* start */ in [|i|] /* end */", + "/* start */ i /* end */")] + [InlineData( + "/* start */ in /* middle */ [|i|] /* end */", + "/* start */ i /* end */")] + [InlineData( + "/* start */ in /* middle */ [|i|] /* end */", + "/* start */ i /* end */")] + [InlineData( + "/* start */in /* middle */ [|i|] /* end */", + "/* start */i /* end */")] + public async Task TestRemoveInKeywordWithTrivia(string original, string expected) + { + await TestInRegularAndScript1Async( + $$""" + class App + { + void M(int i) { } + void N(int i) { - void M(int i) { } - void N(int i) - { - M({{expected}}); - } - + M({{original}}); } - """); - } - [Fact] - public async Task TestRemoveInKeywordFixAllInDocument1() - { - await TestInRegularAndScript1Async( - """ - class Class + } + """, + $$""" + class App + { + void M(int i) { } + void N(int i) { - void M1(int i) { } - void M2(int i, string s) { } + M({{expected}}); + } - void N1(int i) - { - M1(in {|FixAllInDocument:i|}); - } + } + """); + } - void N2(int i, string s) - { - M2(in i, in s); - } + [Fact] + public async Task TestRemoveInKeywordFixAllInDocument1() + { + await TestInRegularAndScript1Async( + """ + class Class + { + void M1(int i) { } + void M2(int i, string s) { } - void N3(int i, string s) - { - M1(in i); - M2(in i, in s); - } + void N1(int i) + { + M1(in {|FixAllInDocument:i|}); } - """, - """ - class Class + + void N2(int i, string s) { - void M1(int i) { } - void M2(int i, string s) { } + M2(in i, in s); + } - void N1(int i) - { - M1(i); - } + void N3(int i, string s) + { + M1(in i); + M2(in i, in s); + } + } + """, + """ + class Class + { + void M1(int i) { } + void M2(int i, string s) { } - void N2(int i, string s) - { - M2(i, s); - } + void N1(int i) + { + M1(i); + } - void N3(int i, string s) - { - M1(i); - M2(i, s); - } + void N2(int i, string s) + { + M2(i, s); } - """); - } - [Fact] - public async Task TestRemoveInKeywordFixAllInDocument2() - { - await TestInRegularAndScript1Async( - """ - class Class + void N3(int i, string s) { - void M1(int i) { } - void M2(in int i, string s) { } + M1(i); + M2(i, s); + } + } + """); + } - void N1(int i) - { - M1(in {|FixAllInDocument:i|}); - } + [Fact] + public async Task TestRemoveInKeywordFixAllInDocument2() + { + await TestInRegularAndScript1Async( + """ + class Class + { + void M1(int i) { } + void M2(in int i, string s) { } - void N2(int i, string s) - { - M2(in i, in s); - } + void N1(int i) + { + M1(in {|FixAllInDocument:i|}); + } - void N3(int i, string s) - { - M1(in i); - M2(in i, in s); - } + void N2(int i, string s) + { + M2(in i, in s); } - """, - """ - class Class + + void N3(int i, string s) { - void M1(int i) { } - void M2(in int i, string s) { } + M1(in i); + M2(in i, in s); + } + } + """, + """ + class Class + { + void M1(int i) { } + void M2(in int i, string s) { } - void N1(int i) - { - M1(i); - } + void N1(int i) + { + M1(i); + } - void N2(int i, string s) - { - M2(in i, s); - } + void N2(int i, string s) + { + M2(in i, s); + } - void N3(int i, string s) - { - M1(i); - M2(in i, s); - } + void N3(int i, string s) + { + M1(i); + M2(in i, s); } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs b/src/Analyzers/CSharp/Tests/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs index fce023cb0738a..d394a9a1b0a18 100644 --- a/src/Analyzers/CSharp/Tests/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs @@ -11,147 +11,146 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveNewModifier +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveNewModifier; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNewModifier)] +public class RemoveNewModifierCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNewModifier)] - public class RemoveNewModifierCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveNewModifierCodeFixProviderTests(ITestOutputHelper logger) + : base(logger) { - public RemoveNewModifierCodeFixProviderTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new RemoveNewModifierCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new RemoveNewModifierCodeFixProvider()); - [Theory] - [InlineData( - @"public static new void [|Method()|] { }", - @"public static void [|Method()|] { }")] - [InlineData( - "public new int [|Test|];", - "public int [|Test|];")] - [InlineData( - "public new int [|Test|] { get; set; }", - "public int [|Test|] { get; set; }")] - [InlineData( - "public new const int [|test|] = 1;", - "public const int test = 1;")] - [InlineData( - "public new event Action [|Test|];", - "public event Action Test;")] - [InlineData( - "public new int [|this[int p]|] => p;", - "public int this[int p] => p;")] - [InlineData( - "new class [|Test|] { }", - "class Test { }")] - [InlineData( - "new struct [|Test|] { }", - "struct Test { }")] - [InlineData( - "new interface [|Test|] { }", - "interface Test { }")] - [InlineData( - "new delegate [|Test|]()", - "delegate Test()")] - [InlineData( - "new enum [|Test|] { }", - "enum Test { }")] - [InlineData( - "new(int a, int b) [|test|];", - "(int a, int b) test;")] - public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string original, string expected) - => TestRemoveNewModifierCodeFixAsync(original, expected); + [Theory] + [InlineData( + @"public static new void [|Method()|] { }", + @"public static void [|Method()|] { }")] + [InlineData( + "public new int [|Test|];", + "public int [|Test|];")] + [InlineData( + "public new int [|Test|] { get; set; }", + "public int [|Test|] { get; set; }")] + [InlineData( + "public new const int [|test|] = 1;", + "public const int test = 1;")] + [InlineData( + "public new event Action [|Test|];", + "public event Action Test;")] + [InlineData( + "public new int [|this[int p]|] => p;", + "public int this[int p] => p;")] + [InlineData( + "new class [|Test|] { }", + "class Test { }")] + [InlineData( + "new struct [|Test|] { }", + "struct Test { }")] + [InlineData( + "new interface [|Test|] { }", + "interface Test { }")] + [InlineData( + "new delegate [|Test|]()", + "delegate Test()")] + [InlineData( + "new enum [|Test|] { }", + "enum Test { }")] + [InlineData( + "new(int a, int b) [|test|];", + "(int a, int b) test;")] + public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string original, string expected) + => TestRemoveNewModifierCodeFixAsync(original, expected); - [Theory] - [InlineData( - "/* start */ public /* middle */ new /* end */ int [|Test|];", - "/* start */ public /* middle */ int Test;")] - [InlineData( - "/* start */ public /* middle */ new /* end */ int [|Test|];", - "/* start */ public /* middle */ int Test;")] - [InlineData( - "/* start */ public /* middle */new /* end */ int [|Test|];", - "/* start */ public /* middle */int Test;")] - [InlineData( - "/* start */ public /* middle */ new/* end */ int [|Test|];", - "/* start */ public /* middle */ int Test;")] - [InlineData( - "/* start */ public /* middle */new/* end */ int [|Test|];", - "/* start */ public /* middle */int Test;")] - [InlineData( - "new /* end */ int [|Test|];", - "int Test;")] - [InlineData( - "new int [|Test|];", - "int Test;")] - [InlineData( - "/* start */ new /* end */ int [|Test|];", - "/* start */ int [|Test|];")] - public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) - => TestRemoveNewModifierCodeFixAsync(original, expected); + [Theory] + [InlineData( + "/* start */ public /* middle */ new /* end */ int [|Test|];", + "/* start */ public /* middle */ int Test;")] + [InlineData( + "/* start */ public /* middle */ new /* end */ int [|Test|];", + "/* start */ public /* middle */ int Test;")] + [InlineData( + "/* start */ public /* middle */new /* end */ int [|Test|];", + "/* start */ public /* middle */int Test;")] + [InlineData( + "/* start */ public /* middle */ new/* end */ int [|Test|];", + "/* start */ public /* middle */ int Test;")] + [InlineData( + "/* start */ public /* middle */new/* end */ int [|Test|];", + "/* start */ public /* middle */int Test;")] + [InlineData( + "new /* end */ int [|Test|];", + "int Test;")] + [InlineData( + "new int [|Test|];", + "int Test;")] + [InlineData( + "/* start */ new /* end */ int [|Test|];", + "/* start */ int [|Test|];")] + public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) + => TestRemoveNewModifierCodeFixAsync(original, expected); - [Fact] - public Task TestRemoveNewFromModifiersFixAll() - => TestInRegularAndScriptAsync(""" - using System; - class B - { - public int ValidNew; - } - class C : B - { - public new int ValidNew; - public new void {|FixAllInDocument:M|}() { } - public new int F; - public new event Action E; - public new int P { get; } - public new int this[int p] => p; - new class C2 { } - new struct S2 { } - new interface I2 { } - new delegate void D2(); - new enum E2 { } - } - """, - """ - using System; - class B - { - public int ValidNew; - } - class C : B - { - public new int ValidNew; - public void M() { } - public int F; - public event Action E; - public int P { get; } - public int this[int p] => p; - class C2 { } - struct S2 { } - interface I2 { } - delegate void D2(); - enum E2 { } - } - """); + [Fact] + public Task TestRemoveNewFromModifiersFixAll() + => TestInRegularAndScriptAsync(""" + using System; + class B + { + public int ValidNew; + } + class C : B + { + public new int ValidNew; + public new void {|FixAllInDocument:M|}() { } + public new int F; + public new event Action E; + public new int P { get; } + public new int this[int p] => p; + new class C2 { } + new struct S2 { } + new interface I2 { } + new delegate void D2(); + new enum E2 { } + } + """, + """ + using System; + class B + { + public int ValidNew; + } + class C : B + { + public new int ValidNew; + public void M() { } + public int F; + public event Action E; + public int P { get; } + public int this[int p] => p; + class C2 { } + struct S2 { } + interface I2 { } + delegate void D2(); + enum E2 { } + } + """); - private Task TestRemoveNewModifierCodeFixAsync(string original, string expected) - { - return TestInRegularAndScript1Async( - $$""" - class App - { - {{original}} - } - """, - $$""" - class App - { - {{expected}} - } - """); - } + private Task TestRemoveNewModifierCodeFixAsync(string original, string expected) + { + return TestInRegularAndScript1Async( + $$""" + class App + { + {{original}} + } + """, + $$""" + class App + { + {{expected}} + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveRedundantEquality/RemoveRedundantEqualityTests.cs b/src/Analyzers/CSharp/Tests/RemoveRedundantEquality/RemoveRedundantEqualityTests.cs index 5f432749c27ee..88aeee52301c9 100644 --- a/src/Analyzers/CSharp/Tests/RemoveRedundantEquality/RemoveRedundantEqualityTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveRedundantEquality/RemoveRedundantEqualityTests.cs @@ -9,261 +9,260 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveRedundantEquality -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveRedundantEqualityDiagnosticAnalyzer, - RemoveRedundantEqualityCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveRedundantEquality; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveRedundantEqualityDiagnosticAnalyzer, + RemoveRedundantEqualityCodeFixProvider>; - public class RemoveRedundantEqualityTests +public class RemoveRedundantEqualityTests +{ + [Fact] + public async Task TestSimpleCaseForEqualsTrue() { - [Fact] - public async Task TestSimpleCaseForEqualsTrue() - { - var code = """ - public class C + var code = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x [|==|] true; - } + return x [|==|] true; } - """; - var fixedCode = """ - public class C + } + """; + var fixedCode = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x; - } + return x; } - """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact] - public async Task TestSimpleCaseForEqualsFalse_NoDiagnostics() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestSimpleCaseForEqualsFalse_NoDiagnostics() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x [|==|] false; - } + return x [|==|] false; } - """, """ - public class C + } + """, """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return !x; - } + return !x; } - """); - } + } + """); + } - [Fact] - public async Task TestSimpleCaseForNotEqualsFalse() - { - var code = """ - public class C + [Fact] + public async Task TestSimpleCaseForNotEqualsFalse() + { + var code = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x [|!=|] false; - } + return x [|!=|] false; } - """; - var fixedCode = """ - public class C + } + """; + var fixedCode = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x; - } + return x; } - """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact] - public async Task TestSimpleCaseForNotEqualsTrue_NoDiagnostics() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestSimpleCaseForNotEqualsTrue_NoDiagnostics() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x [|!=|] true; - } + return x [|!=|] true; } - """, """ - public class C + } + """, """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return !x; - } + return !x; } - """); - } + } + """); + } - [Fact] - public async Task TestNullable_NoDiagnostics() - { - var code = """ - public class C + [Fact] + public async Task TestNullable_NoDiagnostics() + { + var code = """ + public class C + { + public bool M1(bool? x) { - public bool M1(bool? x) - { - return x == true; - } + return x == true; } - """; - await VerifyCS.VerifyAnalyzerAsync(code); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(code); + } - [Fact] - public async Task TestWhenConstant_NoDiagnostics() - { - var code = """ - public class C - { - public const bool MyTrueConstant = true; + [Fact] + public async Task TestWhenConstant_NoDiagnostics() + { + var code = """ + public class C + { + public const bool MyTrueConstant = true; - public bool M1(bool x) - { - return x == MyTrueConstant; - } + public bool M1(bool x) + { + return x == MyTrueConstant; } - """; - await VerifyCS.VerifyAnalyzerAsync(code); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(code); + } - [Fact] - public async Task TestOverloadedOperator_NoDiagnostics() - { - var code = """ - public class C - { - public static bool operator ==(C a, bool b) => false; - public static bool operator !=(C a, bool b) => true; + [Fact] + public async Task TestOverloadedOperator_NoDiagnostics() + { + var code = """ + public class C + { + public static bool operator ==(C a, bool b) => false; + public static bool operator !=(C a, bool b) => true; - public bool M1(C x) - { - return x == true; - } + public bool M1(C x) + { + return x == true; } - """; - await VerifyCS.VerifyAnalyzerAsync(code); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(code); + } - [Fact] - public async Task TestOnLeftHandSide() - { - var code = """ - public class C + [Fact] + public async Task TestOnLeftHandSide() + { + var code = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return true [|==|] x; - } + return true [|==|] x; } - """; - var fixedCode = """ - public class C + } + """; + var fixedCode = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x; - } + return x; } - """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact] - public async Task TestInArgument() - { - var code = """ - public class C + [Fact] + public async Task TestInArgument() + { + var code = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return M1(x [|==|] true); - } + return M1(x [|==|] true); } - """; - var fixedCode = """ - public class C + } + """; + var fixedCode = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return M1(x); - } + return M1(x); } - """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact] - public async Task TestFixAll() - { - var code = """ - public class C + [Fact] + public async Task TestFixAll() + { + var code = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return true [|==|] x; - } + return true [|==|] x; + } - public bool M2(bool x) - { - return x [|!=|] false; - } + public bool M2(bool x) + { + return x [|!=|] false; + } - public bool M3(bool x) - { - return x [|==|] true [|==|] true; - } + public bool M3(bool x) + { + return x [|==|] true [|==|] true; } - """; - var fixedCode = """ - public class C + } + """; + var fixedCode = """ + public class C + { + public bool M1(bool x) { - public bool M1(bool x) - { - return x; - } + return x; + } - public bool M2(bool x) - { - return x; - } + public bool M2(bool x) + { + return x; + } - public bool M3(bool x) - { - return x; - } + public bool M3(bool x) + { + return x; } - """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48236")] - public async Task TestNullableValueTypes_DoesntCrash() - { - var code = """ - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48236")] + public async Task TestNullableValueTypes_DoesntCrash() + { + var code = """ + public class C + { + public bool M1(int? x) { - public bool M1(int? x) - { - return x == null; - } + return x == null; } - """; - await VerifyCS.VerifyAnalyzerAsync(code); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(code); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests_FixAllTests.cs index f47e31b7beaf2..e020b509d9b26 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryCast/RemoveUnnecessaryCastTests_FixAllTests.cs @@ -11,481 +11,480 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryCast +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryCast; + +public class RemoveUnnecessaryCastTests_FixAllTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - public class RemoveUnnecessaryCastTests_FixAllTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveUnnecessaryCastTests_FixAllTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpRemoveUnnecessaryCastDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryCastCodeFixProvider()); + + #region "Fix all occurrences tests" + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() { - public RemoveUnnecessaryCastTests_FixAllTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpRemoveUnnecessaryCastDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryCastCodeFixProvider()); - - #region "Fix all occurrences tests" - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument() - { - var input = """ - - - - class Program + var input = """ + + + + class Program + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = {|FixAllInDocument:(int)0|}; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - - // cast removal that leads to parenthesis removal - var prog = new Program(); - ((Program)prog).F(); - } + // unnecessary casts + int y = {|FixAllInDocument:(int)0|}; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; + + // cast removal that leads to parenthesis removal + var prog = new Program(); + ((Program)prog).F(); } - - - class Program2 + } + + + class Program2 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - - // cast removal that leads to parenthesis removal - var prog = new Program(); - ((Program)prog).F(); - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; + + // cast removal that leads to parenthesis removal + var prog = new Program(); + ((Program)prog).F(); } - - - - - class Program3 + } + + + + + class Program3 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - - // cast removal that leads to parenthesis removal - var prog = new Program(); - ((Program)prog).F(); - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; + + // cast removal that leads to parenthesis removal + var prog = new Program(); + ((Program)prog).F(); } - - - - """; - - var expected = """ - - - - class Program + } + + + + """; + + var expected = """ + + + + class Program + { + private char f = 'c'; + public void F(int x = 0) { - private char f = 'c'; - public void F(int x = 0) - { - // unnecessary casts - int y = 0; - bool z = true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? s1 : (object)s2; - - // cast removal that leads to parenthesis removal - var prog = new Program(); - prog.F(); - } + // unnecessary casts + int y = 0; + bool z = true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? s1 : (object)s2; + + // cast removal that leads to parenthesis removal + var prog = new Program(); + prog.F(); } - - - class Program2 + } + + + class Program2 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - - // cast removal that leads to parenthesis removal - var prog = new Program(); - ((Program)prog).F(); - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; + + // cast removal that leads to parenthesis removal + var prog = new Program(); + ((Program)prog).F(); } - - - - - class Program3 + } + + + + + class Program3 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - - // cast removal that leads to parenthesis removal - var prog = new Program(); - ((Program)prog).F(); - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; + + // cast removal that leads to parenthesis removal + var prog = new Program(); + ((Program)prog).F(); } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject() - { - var input = """ - - - - class Program + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var input = """ + + + + class Program + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = {|FixAllInProject:(int)0|}; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = {|FixAllInProject:(int)0|}; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - class Program2 + } + + + class Program2 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - - - class Program3 + } + + + + + class Program3 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - - """; - - var expected = """ - - - - class Program + } + + + + """; + + var expected = """ + + + + class Program + { + private char f = 'c'; + public void F(int x = 0) { - private char f = 'c'; - public void F(int x = 0) - { - // unnecessary casts - int y = 0; - bool z = true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? s1 : (object)s2; - } + // unnecessary casts + int y = 0; + bool z = true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? s1 : (object)s2; } - - - class Program2 + } + + + class Program2 + { + private char f = 'c'; + public void F(int x = 0) { - private char f = 'c'; - public void F(int x = 0) - { - // unnecessary casts - int y = 0; - bool z = true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? s1 : (object)s2; - } + // unnecessary casts + int y = 0; + bool z = true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? s1 : (object)s2; } - - - - - class Program3 + } + + + + + class Program3 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution() - { - var input = """ - - - - class Program + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() + { + var input = """ + + + + class Program + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = {|FixAllInSolution:(int)0|}; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = {|FixAllInSolution:(int)0|}; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - class Program2 + } + + + class Program2 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - - - class Program3 + } + + + + + class Program3 + { + private char f = (char)'c'; + public void F(int x = (int)0) { - private char f = (char)'c'; - public void F(int x = (int)0) - { - // unnecessary casts - int y = (int)0; - bool z = (bool)true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? (object)s1 : (object)s2; - } + // unnecessary casts + int y = (int)0; + bool z = (bool)true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? (object)s1 : (object)s2; } - - - - """; - - var expected = """ - - - - class Program + } + + + + """; + + var expected = """ + + + + class Program + { + private char f = 'c'; + public void F(int x = 0) { - private char f = 'c'; - public void F(int x = 0) - { - // unnecessary casts - int y = 0; - bool z = true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? s1 : (object)s2; - } + // unnecessary casts + int y = 0; + bool z = true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? s1 : (object)s2; } - - - class Program2 + } + + + class Program2 + { + private char f = 'c'; + public void F(int x = 0) { - private char f = 'c'; - public void F(int x = 0) - { - // unnecessary casts - int y = 0; - bool z = true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? s1 : (object)s2; - } + // unnecessary casts + int y = 0; + bool z = true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? s1 : (object)s2; } - - - - - class Program3 + } + + + + + class Program3 + { + private char f = 'c'; + public void F(int x = 0) { - private char f = 'c'; - public void F(int x = 0) - { - // unnecessary casts - int y = 0; - bool z = true; - - // required cast - long l = 1; - int y = (int)l; - - // required cast after cast removal in same statement - string s1 = null, s2 = null; - var s3 = z ? s1 : (object)s2; - } + // unnecessary casts + int y = 0; + bool z = true; + + // required cast + long l = 1; + int y = (int)l; + + // required cast after cast removal in same statement + string s1 = null, s2 = null; + var s3 = z ? s1 : (object)s2; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - #endregion + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); } + #endregion } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryDiscardDesignation/RemoveUnnecessaryDiscardDesignationTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryDiscardDesignation/RemoveUnnecessaryDiscardDesignationTests.cs index ad98517a33133..801ad59bda8f7 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryDiscardDesignation/RemoveUnnecessaryDiscardDesignationTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryDiscardDesignation/RemoveUnnecessaryDiscardDesignationTests.cs @@ -11,596 +11,595 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryDiscardDesignation -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveUnnecessaryDiscardDesignationDiagnosticAnalyzer, - CSharpRemoveUnnecessaryDiscardDesignationCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryDiscardDesignation; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnnecessaryDiscardDesignationDiagnosticAnalyzer, + CSharpRemoveUnnecessaryDiscardDesignationCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryDiscardDesignation)] - public class RemoveUnnecessaryDiscardDesignationTests +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryDiscardDesignation)] +public class RemoveUnnecessaryDiscardDesignationTests +{ + [Fact] + public async Task TestDeclarationPatternInSwitchStatement() { - [Fact] - public async Task TestDeclarationPatternInSwitchStatement() + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + switch (o) { - switch (o) - { - case int [|_|]: - break; - } + case int [|_|]: + break; } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + switch (o) { - switch (o) - { - case int: - break; - } + case int: + break; } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestNotInCSharp8() + [Fact] + public async Task TestNotInCSharp8() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + switch (o) { - switch (o) - { - case int _: - break; - } + case int _: + break; } } - """, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - [Fact] - public async Task TestDeclarationPatternInSwitchExpression() + [Fact] + public async Task TestDeclarationPatternInSwitchExpression() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - int [|_|] => 0, - }; - } + int [|_|] => 0, + }; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - int => 0, - }; - } + int => 0, + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestDeclarationPatternInIfStatement() + [Fact] + public async Task TestDeclarationPatternInIfStatement() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - void M(object o) - { - if (o is int [|_|]) { } - } - } - """, - FixedCode = """ - class C - { - void M(object o) - { - if (o is int) { } - } - } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + TestCode = """ + class C + { + void M(object o) + { + if (o is int [|_|]) { } + } + } + """, + FixedCode = """ + class C + { + void M(object o) + { + if (o is int) { } + } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestRecursivePropertyPattern() + [Fact] + public async Task TestRecursivePropertyPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - { } [|_|] => 0, - }; - } + { } [|_|] => 0, + }; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - { } => 0, - }; - } + { } => 0, + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestEmptyRecursiveParameterPattern() + [Fact] + public async Task TestEmptyRecursiveParameterPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - () [|_|] => 0, - }; - } + () [|_|] => 0, + }; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - () => 0, - }; - } + () => 0, + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestTwoElementRecursiveParameterPattern() + [Fact] + public async Task TestTwoElementRecursiveParameterPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - (int i, int j) [|_|] => 0, - }; - } + (int i, int j) [|_|] => 0, + }; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - (int i, int j) => 0, - }; - } + (int i, int j) => 0, + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestNotWithOneElementRecursiveParameterPattern() + [Fact] + public async Task TestNotWithOneElementRecursiveParameterPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + var v = o switch { - var v = o switch - { - (int i) _ => 0, - }; - } + (int i) _ => 0, + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestNestedFixAll() + [Fact] + public async Task TestNestedFixAll() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(string o) { - void M(string o) + var v = o switch { - var v = o switch - { - { Length: int [|_|] } [|_|] => 1, - }; - } + { Length: int [|_|] } [|_|] => 1, + }; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(string o) { - void M(string o) + var v = o switch { - var v = o switch - { - { Length: int } => 1, - }; - } + { Length: int } => 1, + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestPropertyWithTheSameNameAsType() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestPropertyWithTheSameNameAsType() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class C - { - string String { get; } + class C + { + string String { get; } - void M(object o) + void M(object o) + { + if (o is String [|_|]) { - if (o is String [|_|]) - { - } } } - """, - FixedCode = """ - using System; - - class C + } + """, + FixedCode = """ + using System; + + class C + { + string String { get; } + + void M(object o) { - string String { get; } - - void M(object o) + if (o is String) { - if (o is String) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestNotWhenRemovingDiscardChangesMeaning1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestNotWhenRemovingDiscardChangesMeaning1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class C - { - string String { get; } + class C + { + string String { get; } - void M(object o) + void M(object o) + { + if (o is not String _) { - if (o is not String _) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestNotWhenRemovingDiscardChangesMeaning2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestNotWhenRemovingDiscardChangesMeaning2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class C - { - string String { get; } + class C + { + string String { get; } - void M(object o) + void M(object o) + { + var v = o switch { - var v = o switch - { - String _ => 0 - }; - } + String _ => 0 + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestNestedPropertyWithTheSameNameAsNestedType() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestNestedPropertyWithTheSameNameAsNestedType() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class D + class D + { + public class Length { - public class Length - { - } } + } - class C - { - string D { get; } + class C + { + string D { get; } - void M(object o) + void M(object o) + { + if (o is D.Length [|_|]) { - if (o is D.Length [|_|]) - { - } } } - """, - FixedCode = """ - using System; - - class D + } + """, + FixedCode = """ + using System; + + class D + { + public class Length { - public class Length - { - } } - - class C + } + + class C + { + string D { get; } + + void M(object o) { - string D { get; } - - void M(object o) + if (o is D.Length) { - if (o is D.Length) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestNotWhenRemovingDiscardChangesMeaning3() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestNotWhenRemovingDiscardChangesMeaning3() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - - class D - { - public class Length - { - } + TestCode = """ + using System; + + class D + { + public class Length + { } - - class C + } + + class C + { + string D { get; } + + void M(object o) { - string D { get; } - - void M(object o) + if (o is not D.Length _) { - if (o is not D.Length _) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestNotWhenRemovingDiscardChangesMeaning4() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestNotWhenRemovingDiscardChangesMeaning4() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class D + class D + { + public class Length { - public class Length - { - } } + } - class C - { - string D { get; } + class C + { + string D { get; } - void M(object o) + void M(object o) + { + var v = o switch { - var v = o switch - { - D.Length _ => 0 - }; - } + D.Length _ => 0 + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestPropertyNamedGlobalAndAliasQualifiedName1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestPropertyNamedGlobalAndAliasQualifiedName1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - string global { get; } + TestCode = """ + class C + { + string global { get; } - void M(object o) + void M(object o) + { + if (o is global::System.String [|_|]) { - if (o is global::System.String [|_|]) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + string global { get; } + + void M(object o) { - string global { get; } - - void M(object o) + if (o is global::System.String) { - if (o is global::System.String) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestPropertyNamedGlobalAndAliasQualifiedName2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestPropertyNamedGlobalAndAliasQualifiedName2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - string global { get; } + TestCode = """ + class C + { + string global { get; } - void M(object o) + void M(object o) + { + if (o is not global::System.String [|_|]) { - if (o is not global::System.String [|_|]) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + string global { get; } + + void M(object o) { - string global { get; } - - void M(object o) + if (o is not global::System.String) { - if (o is not global::System.String) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - CodeActionValidationMode = CodeActionValidationMode.None, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + CodeActionValidationMode = CodeActionValidationMode.None, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] - public async Task TestPropertyNamedGlobalAndAliasQualifiedName3() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66841")] + public async Task TestPropertyNamedGlobalAndAliasQualifiedName3() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - string global { get; } + TestCode = """ + class C + { + string global { get; } - void M(object o) + void M(object o) + { + var v = o switch { - var v = o switch - { - global::System.String [|_|] => 0 - }; - } + global::System.String [|_|] => 0 + }; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + string global { get; } + + void M(object o) { - string global { get; } - - void M(object o) + var v = o switch { - var v = o switch - { - global::System.String => 0 - }; - } + global::System.String => 0 + }; } - """, - LanguageVersion = LanguageVersion.CSharp9, - CodeActionValidationMode = CodeActionValidationMode.None, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + CodeActionValidationMode = CodeActionValidationMode.None, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests.cs index f80d131dbf51e..d06499cad9610 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests.cs @@ -12,467 +12,427 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryImports -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer, - CSharpRemoveUnnecessaryImportsCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryImports; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer, + CSharpRemoveUnnecessaryImportsCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - public class RemoveUnnecessaryImportsTests +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] +public class RemoveUnnecessaryImportsTests +{ + [Fact] + public async Task TestNoReferences() { - [Fact] - public async Task TestNoReferences() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestNoReferencesWithCopyright() - { - await VerifyCS.VerifyCodeFixAsync( - """ - // Copyright (c) Somebody. + [Fact] + public async Task TestNoReferencesWithCopyright() + { + await VerifyCS.VerifyCodeFixAsync( + """ + // Copyright (c) Somebody. - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """, - """ - // Copyright (c) Somebody. + } + """, + """ + // Copyright (c) Somebody. - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27006")] - public async Task TestReferencesWithCopyrightAndPreservableTrivia() - { - await VerifyCS.VerifyCodeFixAsync( - """ - // Copyright (c) Somebody. + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27006")] + public async Task TestReferencesWithCopyrightAndPreservableTrivia() + { + await VerifyCS.VerifyCodeFixAsync( + """ + // Copyright (c) Somebody. - [|using System; + [|using System; - {|IDE0005:using System.Collections.Generic; - // This is important - using System.Linq;|}|] + {|IDE0005:using System.Collections.Generic; + // This is important + using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a; - } + Action a; } - """, - """ - // Copyright (c) Somebody. + } + """, + """ + // Copyright (c) Somebody. - using System; - // This is important + using System; + // This is important - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a; - } + Action a; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27006")] - public async Task TestReferencesWithCopyrightAndGroupings() - { - await VerifyCS.VerifyCodeFixAsync( - """ - // Copyright (c) Somebody. + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27006")] + public async Task TestReferencesWithCopyrightAndGroupings() + { + await VerifyCS.VerifyCodeFixAsync( + """ + // Copyright (c) Somebody. - [|using System; + [|using System; - {|IDE0005:using System.Collections.Generic; + {|IDE0005:using System.Collections.Generic; - using System.Linq;|}|] + using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a; - } + Action a; } - """, - """ - // Copyright (c) Somebody. + } + """, + """ + // Copyright (c) Somebody. - using System; + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Action a; - } + Action a; } - """); - } + } + """); + } - [Fact] - public async Task TestIdentifierReferenceInTypeContext() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|using System; - {|IDE0005:using System.Collections.Generic; - using System.Linq;|}|] + [Fact] + public async Task TestIdentifierReferenceInTypeContext() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|using System; + {|IDE0005:using System.Collections.Generic; + using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - DateTime d; - } + DateTime d; } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - DateTime d; - } + DateTime d; } - """); - } + } + """); + } - [Fact] - public async Task TestGeneratedCode() - { - var source = """ - // + [Fact] + public async Task TestGeneratedCode() + { + var source = """ + // - [|{|IDE0005_gen:using System;|} - using System.Collections.Generic; - {|IDE0005_gen:using System.Linq;|}|] + [|{|IDE0005_gen:using System;|} + using System.Collections.Generic; + {|IDE0005_gen:using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - List d; - } + List d; } - """; - var fixedSource = """ - // + } + """; + var fixedSource = """ + // - using System.Collections.Generic; + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - List d; - } + List d; } - """; + } + """; - // Fix All operations in generated code do not apply changes - var batchFixedSource = source; + // Fix All operations in generated code do not apply changes + var batchFixedSource = source; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + BatchFixedState = { - TestCode = source, - FixedCode = fixedSource, - BatchFixedState = - { - Sources = { batchFixedSource }, - MarkupHandling = MarkupMode.Allow, - }, - }.RunAsync(); - } + Sources = { batchFixedSource }, + MarkupHandling = MarkupMode.Allow, + }, + }.RunAsync(); + } - [Fact] - public async Task TestGenericReferenceInTypeContext() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System;|} - using System.Collections.Generic; - {|IDE0005:using System.Linq;|}|] + [Fact] + public async Task TestGenericReferenceInTypeContext() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System;|} + using System.Collections.Generic; + {|IDE0005:using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - List list; - } + List list; } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - List list; - } + List list; } - """); - } + } + """); + } - [Fact] - public async Task TestMultipleReferences() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|using System; - using System.Collections.Generic; - {|IDE0005:using System.Linq;|}|] + [Fact] + public async Task TestMultipleReferences() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|using System; + using System.Collections.Generic; + {|IDE0005:using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - List list; - DateTime d; - } + List list; + DateTime d; } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - List list; - DateTime d; - } + List list; + DateTime d; } - """); - } + } + """); + } - [Fact] - public async Task TestExtensionMethodReference() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System; - using System.Collections.Generic;|} - using System.Linq;|] + [Fact] + public async Task TestExtensionMethodReference() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System; + using System.Collections.Generic;|} + using System.Linq;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - args.Where(a => a.Length > 10); - } + args.Where(a => a.Length > 10); } - """, - """ - using System.Linq; + } + """, + """ + using System.Linq; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - args.Where(a => a.Length > 10); - } + args.Where(a => a.Length > 10); } - """); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541827")] - public async Task TestExtensionMethodLinq() - { - // NOTE: Intentionally not running this test with Script options, because in Script, - // NOTE: class "Goo" is placed inside the script class, and can't be seen by the extension - // NOTE: method Select, which is not inside the script class. - var code = """ - using System; - using System.Collections; - using SomeNS; + } + """); + } - class Program + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541827")] + public async Task TestExtensionMethodLinq() + { + // NOTE: Intentionally not running this test with Script options, because in Script, + // NOTE: class "Goo" is placed inside the script class, and can't be seen by the extension + // NOTE: method Select, which is not inside the script class. + var code = """ + using System; + using System.Collections; + using SomeNS; + + class Program + { + static void Main() { - static void Main() - { - Goo qq = new Goo(); - IEnumerable x = from q in qq - select q; - } + Goo qq = new Goo(); + IEnumerable x = from q in qq + select q; } + } - public class Goo + public class Goo + { + public Goo() { - public Goo() - { - } } + } - namespace SomeNS + namespace SomeNS + { + public static class SomeClass { - public static class SomeClass + public static IEnumerable Select(this Goo o, Func f) { - public static IEnumerable Select(this Goo o, Func f) - { - return null; - } + return null; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestAliasQualifiedAliasReference() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System;|} - using G = System.Collections.Generic; - {|IDE0005:using System.Linq;|}|] + [Fact] + public async Task TestAliasQualifiedAliasReference() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System;|} + using G = System.Collections.Generic; + {|IDE0005:using System.Linq;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - G::List list; - } + G::List list; } - """, - """ - using G = System.Collections.Generic; + } + """, + """ + using G = System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - G::List list; - } + G::List list; } - """); - } - - [Fact] - public async Task TestQualifiedAliasReference() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System;|} - using G = System.Collections.Generic;|] + } + """); + } - class Program - { - static void Main(string[] args) - { - G.List list; - } - } - """, - """ - using G = System.Collections.Generic; + [Fact] + public async Task TestQualifiedAliasReference() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System;|} + using G = System.Collections.Generic;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - G.List list; - } + G.List list; } - """); - } + } + """, + """ + using G = System.Collections.Generic; - [Fact] - public async Task TestNestedUnusedUsings() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] - - namespace N + class Program + { + static void Main(string[] args) { - using System; - - class Program - { - static void Main(string[] args) - { - DateTime d; - } - } + G.List list; } - """, - """ - namespace N - { - using System; + } + """); + } - class Program - { - static void Main(string[] args) - { - DateTime d; - } - } - } - """); - } + [Fact] + public async Task TestNestedUnusedUsings() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] - [Fact] - public async Task TestNestedUnusedUsings_FileScopedNamespace() - { - await new VerifyCS.Test + namespace N { - TestCode = - """ - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] - - namespace N; - using System; class Program @@ -482,11 +442,11 @@ static void Main(string[] args) DateTime d; } } - """, - FixedCode = - """ - namespace N; - + } + """, + """ + namespace N + { using System; class Program @@ -496,125 +456,112 @@ static void Main(string[] args) DateTime d; } } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + """); + } - [Fact] - public async Task TestNestedUsedUsings() + [Fact] + public async Task TestNestedUnusedUsings_FileScopedNamespace() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - [|using System; - {|IDE0005:using System.Collections.Generic; - using System.Linq;|}|] + TestCode = + """ + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] - namespace N - { - using System; + namespace N; - class Program - { - static void Main(string[] args) - { - DateTime d; - } - } - } + using System; - class F + class Program + { + static void Main(string[] args) { DateTime d; } - """, - """ - using System; - - namespace N - { - using System; + } + """, + FixedCode = + """ + namespace N; - class Program - { - static void Main(string[] args) - { - DateTime d; - } - } - } + using System; - class F + class Program + { + static void Main(string[] args) { DateTime d; } - """); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/712656")] - public async Task TestNestedUsedUsings2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|using System; - {|IDE0005:using System.Collections.Generic; - using System.Linq;|}|] + [Fact] + public async Task TestNestedUsedUsings() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|using System; + {|IDE0005:using System.Collections.Generic; + using System.Linq;|}|] - namespace N - { - [|using System; - {|IDE0005:using System.Collections.Generic;|}|] + namespace N + { + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - DateTime d; - } + DateTime d; } } + } - class F - { - DateTime d; - } - """, - """ + class F + { + DateTime d; + } + """, + """ + using System; + + namespace N + { using System; - namespace N + class Program { - using System; - - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - DateTime d; - } + DateTime d; } } + } - class F - { - DateTime d; - } - """); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/712656")] - public async Task TestNestedUsedUsings2_FileScopedNamespace() - { - await new VerifyCS.Test + class F { - TestCode = - """ - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] + DateTime d; + } + """); + } - namespace N; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/712656")] + public async Task TestNestedUsedUsings2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|using System; + {|IDE0005:using System.Collections.Generic; + using System.Linq;|}|] + namespace N + { [|using System; {|IDE0005:using System.Collections.Generic;|}|] @@ -625,16 +572,18 @@ static void Main(string[] args) DateTime d; } } + } - class F - { - DateTime d; - } - """, - FixedCode = - """ - namespace N; + class F + { + DateTime d; + } + """, + """ + using System; + namespace N + { using System; class Program @@ -644,690 +593,771 @@ static void Main(string[] args) DateTime d; } } + } - class F - { - DateTime d; - } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + class F + { + DateTime d; + } + """); + } - [Fact] - public async Task TestAttribute() + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/712656")] + public async Task TestNestedUsedUsings2_FileScopedNamespace() + { + await new VerifyCS.Test { - var code = """ - using SomeNamespace; + TestCode = + """ + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] - [SomeAttr] - class Goo - { - } + namespace N; - namespace SomeNamespace - { - public class SomeAttrAttribute : System.Attribute - { - } - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [|using System; + {|IDE0005:using System.Collections.Generic;|}|] - [Fact] - public async Task TestAttributeArgument() - { - var code = """ - using goo; - - [SomeAttribute(typeof(SomeClass))] - class Program + class Program + { + static void Main(string[] args) { - static void Main() - { - } + DateTime d; } + } - public class SomeAttribute : System.Attribute - { - public SomeAttribute(object f) - { - } - } + class F + { + DateTime d; + } + """, + FixedCode = + """ + namespace N; + + using System; - namespace goo + class Program + { + static void Main(string[] args) { - public class SomeClass - { - } + DateTime d; } - """; + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task TestRemoveAllWithSurroundingPreprocessor() - { - await VerifyCS.VerifyCodeFixAsync( - """ - #if true + class F + { + DateTime d; + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } - [|{|IDE0005:using System; - using System.Collections.Generic;|}|] + [Fact] + public async Task TestAttribute() + { + var code = """ + using SomeNamespace; - #endif + [SomeAttr] + class Goo + { + } - class Program + namespace SomeNamespace + { + public class SomeAttrAttribute : System.Attribute { - static void Main(string[] args) - { - } } - """, - """ - #if true + } + """; - #endif + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class Program + [Fact] + public async Task TestAttributeArgument() + { + var code = """ + using goo; + + [SomeAttribute(typeof(SomeClass))] + class Program + { + static void Main() { - static void Main(string[] args) - { - } } - """); - } - - [Fact] - public async Task TestRemoveFirstWithSurroundingPreprocessor() - { - await VerifyCS.VerifyCodeFixAsync( - """ - #if true - - [|{|IDE0005:using System;|} - using System.Collections.Generic;|] + } - #endif - - class Program + public class SomeAttribute : System.Attribute + { + public SomeAttribute(object f) { - static void Main(string[] args) - { - List list; - } } - """, - """ - #if true - - using System.Collections.Generic; + } - #endif - - class Program + namespace goo + { + public class SomeClass { - static void Main(string[] args) - { - List list; - } } - """); - } + } + """; - [Fact] - public async Task TestRemoveAllWithSurroundingPreprocessor2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - namespace N - { - #if true + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [|{|IDE0005:using System; - using System.Collections.Generic;|}|] + [Fact] + public async Task TestRemoveAllWithSurroundingPreprocessor() + { + await VerifyCS.VerifyCodeFixAsync( + """ + #if true - #endif + [|{|IDE0005:using System; + using System.Collections.Generic;|}|] - class Program - { - static void Main(string[] args) - { - } - } - } - """, - """ - namespace N + #endif + + class Program + { + static void Main(string[] args) { - #if true + } + } + """, + """ + #if true - #endif + #endif - class Program - { - static void Main(string[] args) - { - } - } + class Program + { + static void Main(string[] args) + { } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveOneWithSurroundingPreprocessor2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - namespace N - { - #if true + [Fact] + public async Task TestRemoveFirstWithSurroundingPreprocessor() + { + await VerifyCS.VerifyCodeFixAsync( + """ + #if true - [|{|IDE0005:using System;|} - using System.Collections.Generic;|] + [|{|IDE0005:using System;|} + using System.Collections.Generic;|] - #endif + #endif - class Program - { - static void Main(string[] args) - { - List list; - } - } - } - """, - """ - namespace N + class Program + { + static void Main(string[] args) { - #if true + List list; + } + } + """, + """ + #if true - using System.Collections.Generic; + using System.Collections.Generic; - #endif + #endif - class Program - { - static void Main(string[] args) - { - List list; - } - } + class Program + { + static void Main(string[] args) + { + List list; } - """); - } + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541817")] - public async Task TestComments8718() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|using Goo; {|IDE0005:using System.Collections.Generic; /*comment*/|} using Goo2;|] + [Fact] + public async Task TestRemoveAllWithSurroundingPreprocessor2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + namespace N + { + #if true + + [|{|IDE0005:using System; + using System.Collections.Generic;|}|] + + #endif class Program { static void Main(string[] args) { - Bar q; - Bar2 qq; } } + } + """, + """ + namespace N + { + #if true + + #endif - namespace Goo + class Program { - public class Bar + static void Main(string[] args) { } } + } + """); + } + + [Fact] + public async Task TestRemoveOneWithSurroundingPreprocessor2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + namespace N + { + #if true + + [|{|IDE0005:using System;|} + using System.Collections.Generic;|] + + #endif - namespace Goo2 + class Program { - public class Bar2 + static void Main(string[] args) { + List list; } } - """, - """ - using Goo; - using Goo2; + } + """, + """ + namespace N + { + #if true + + using System.Collections.Generic; + + #endif class Program { static void Main(string[] args) { - Bar q; - Bar2 qq; + List list; } } + } + """); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541817")] + public async Task TestComments8718() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|using Goo; {|IDE0005:using System.Collections.Generic; /*comment*/|} using Goo2;|] - namespace Goo + class Program + { + static void Main(string[] args) { - public class Bar - { - } + Bar q; + Bar2 qq; } + } - namespace Goo2 + namespace Goo + { + public class Bar { - public class Bar2 - { - } } - """); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528609")] - public async Task TestComments() - { - await VerifyCS.VerifyCodeFixAsync( - """ - //c1 - /*c2*/ - {|IDE0005:[|using/*c3*/ System/*c4*/;|] //c5|} - //c6 + namespace Goo2 + { + public class Bar2 + { + } + } + """, + """ + using Goo; + using Goo2; - class Program + class Program + { + static void Main(string[] args) { + Bar q; + Bar2 qq; } - """, - """ - //c1 - /*c2*/ - //c6 + } - class Program + namespace Goo + { + public class Bar { } - """); - } + } - [Fact] - public async Task TestUnusedUsing() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System.Collections.Generic;|}|] + namespace Goo2 + { + public class Bar2 + { + } + } + """); + } - class Program + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528609")] + public async Task TestComments() + { + await VerifyCS.VerifyCodeFixAsync( + """ + //c1 + /*c2*/ + {|IDE0005:[|using/*c3*/ System/*c4*/;|] //c5|} + //c6 + + class Program + { + } + """, + """ + //c1 + /*c2*/ + //c6 + + class Program + { + } + """); + } + + [Fact] + public async Task TestUnusedUsing() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System.Collections.Generic;|}|] + + class Program + { + static void Main() { - static void Main() - { - } } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main() { - static void Main() - { - } } - """); - } + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541827")] - public async Task TestSimpleQuery() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using System; - using System.Collections.Generic;|} - using System.Linq;|] + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541827")] + public async Task TestSimpleQuery() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System; + using System.Collections.Generic;|} + using System.Linq;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var q = from a in args - where a.Length > 21 - select a; - } + var q = from a in args + where a.Length > 21 + select a; } - """, - """ - using System.Linq; + } + """, + """ + using System.Linq; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var q = from a in args - where a.Length > 21 - select a; - } + var q = from a in args + where a.Length > 21 + select a; } - """); - } + } + """); + } - [Fact] - public async Task TestUsingStaticClassAccessField1() - { - // Test intentionally uses 'using' instead of 'using static' - var testCode = """ - [|{|IDE0005:using {|CS0138:SomeNS.Goo|};|}|] + [Fact] + public async Task TestUsingStaticClassAccessField1() + { + // Test intentionally uses 'using' instead of 'using static' + var testCode = """ + [|{|IDE0005:using {|CS0138:SomeNS.Goo|};|}|] - class Program + class Program + { + static void Main() { - static void Main() - { - var q = {|CS0103:x|}; - } + var q = {|CS0103:x|}; } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - public static int x; - } + public static int x; } - """; - var fixedCode = """ - class Program + } + """; + var fixedCode = """ + class Program + { + static void Main() { - static void Main() - { - var q = {|CS0103:x|}; - } + var q = {|CS0103:x|}; } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - public static int x; - } + public static int x; } - """; - - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp5, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestUsingStaticClassAccessField2() + await new VerifyCS.Test { - var code = """ - using static SomeNS.Goo; + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp5, + }.RunAsync(); + } - class Program + [Fact] + public async Task TestUsingStaticClassAccessField2() + { + var code = """ + using static SomeNS.Goo; + + class Program + { + static void Main() { - static void Main() - { - var q = x; - } + var q = x; } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - public static int x; - } + public static int x; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestUsingStaticClassAccessMethod1() - { - // Test intentionally uses 'using' instead of 'using static' - var testCode = """ - [|{|IDE0005:using {|CS0138:SomeNS.Goo|};|}|] + [Fact] + public async Task TestUsingStaticClassAccessMethod1() + { + // Test intentionally uses 'using' instead of 'using static' + var testCode = """ + [|{|IDE0005:using {|CS0138:SomeNS.Goo|};|}|] - class Program + class Program + { + static void Main() { - static void Main() - { - var q = {|CS0103:X|}(); - } + var q = {|CS0103:X|}(); } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo + public static int X() { - public static int X() - { - return 42; - } + return 42; } } - """; - var fixedCode = """ - [|class Program + } + """; + var fixedCode = """ + [|class Program + { + static void Main() { - static void Main() - { - var q = {|CS0103:X|}(); - } + var q = {|CS0103:X|}(); } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo + public static int X() { - public static int X() - { - return 42; - } + return 42; } - }|] - """; - - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp5, - }.RunAsync(); - } + } + }|] + """; - [Fact] - public async Task TestUsingStaticClassAccessMethod2() + await new VerifyCS.Test { - var code = """ - using static SomeNS.Goo; + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp5, + }.RunAsync(); + } - class Program + [Fact] + public async Task TestUsingStaticClassAccessMethod2() + { + var code = """ + using static SomeNS.Goo; + + class Program + { + static void Main() { - static void Main() - { - var q = X(); - } + var q = X(); } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo + public static int X() { - public static int X() - { - return 42; - } + return 42; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem(8846, "DevDiv_Projects/Roslyn")] - public async Task TestUnusedTypeImportIsRemoved1() - { - // Test intentionally uses 'using' instead of 'using static' - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using {|CS0138:SomeNS.Goo|};|}|] + [Fact, WorkItem(8846, "DevDiv_Projects/Roslyn")] + public async Task TestUnusedTypeImportIsRemoved1() + { + // Test intentionally uses 'using' instead of 'using static' + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using {|CS0138:SomeNS.Goo|};|}|] - class Program + class Program + { + static void Main() { - static void Main() - { - } } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - } } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main() { - static void Main() - { - } } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestUnusedTypeImportIsRemoved2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using static SomeNS.Goo;|}|] + [Fact] + public async Task TestUnusedTypeImportIsRemoved2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using static SomeNS.Goo;|}|] - class Program + class Program + { + static void Main() { - static void Main() - { - } } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - } } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main() { - static void Main() - { - } } + } - namespace SomeNS + namespace SomeNS + { + static class Goo { - static class Goo - { - } } - """); - } + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541817")] - public async Task TestRemoveTrailingComment() - { - await VerifyCS.VerifyCodeFixAsync( - """ - {|IDE0005:[|using System.Collections.Generic;|] // comment|} + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541817")] + public async Task TestRemoveTrailingComment() + { + await VerifyCS.VerifyCodeFixAsync( + """ + {|IDE0005:[|using System.Collections.Generic;|] // comment|} - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """); - } + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541914")] - public async Task TestRemovingUnbindableUsing() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using {|CS0246:gibberish|};|}|] + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541914")] + public async Task TestRemovingUnbindableUsing() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using {|CS0246:gibberish|};|}|] - public static class Program - { - } - """, - """ - public static class Program - { - } - """); - } + public static class Program + { + } + """, + """ + public static class Program + { + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541937")] - public async Task TestAliasInUse() - { - var code = """ - using GIBBERISH = Goo.Bar; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541937")] + public async Task TestAliasInUse() + { + var code = """ + using GIBBERISH = Goo.Bar; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - GIBBERISH x; - } + GIBBERISH x; } + } - namespace Goo + namespace Goo + { + public class Bar { - public class Bar - { - } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541914")] - public async Task TestRemoveUnboundUsing() - { - await VerifyCS.VerifyCodeFixAsync( - """ - [|{|IDE0005:using {|CS0246:gibberish|};|}|] + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541914")] + public async Task TestRemoveUnboundUsing() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using {|CS0246:gibberish|};|}|] + + public static class Program + { + } + """, + """ + public static class Program + { + } + """); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542016")] + public async Task TestLeadingNewlines1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] - public static class Program + class Program + { + static void Main(string[] args) { + } - """, - """ - public static class Program + } + """, + """ + class Program + { + static void Main(string[] args) { + } - """); - } + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542016")] - public async Task TestLeadingNewlines1() - { - await VerifyCS.VerifyCodeFixAsync( - """ + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542016")] + public async Task TestRemoveLeadingNewLines2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + namespace N + { [|{|IDE0005:using System; using System.Collections.Generic; using System.Linq;|}|] @@ -1339,8 +1369,11 @@ static void Main(string[] args) } } - """, - """ + } + """, + """ + namespace N + { class Program { static void Main(string[] args) @@ -1348,925 +1381,891 @@ static void Main(string[] args) } } - """); - } + } + """); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542016")] - public async Task TestRemoveLeadingNewLines2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - namespace N - { - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542134")] + public async Task TestImportedTypeUsedAsGenericTypeArgument() + { + var code = """ + using GenericThingie; - class Program - { - static void Main(string[] args) - { + public class GenericType + { + } - } - } - } - """, - """ - namespace N + namespace GenericThingie + { + public class Something { - class Program - { - static void Main(string[] args) - { - - } - } } - """); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542134")] - public async Task TestImportedTypeUsedAsGenericTypeArgument() - { - var code = """ - using GenericThingie; + } - public class GenericType + public class Program + { + void goo() { + GenericType type; } + } + """; - namespace GenericThingie - { - public class Something - { - } - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - public class Program - { - void goo() - { - GenericType type; - } - } - """; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542723")] + public async Task TestRemoveCorrectUsing1() + { + var source = """ + using System.Collections.Generic; + + namespace Goo + { + [|{|IDE0005:using Bar = Dictionary;|}|] + } + """; + var fixedSource = """ + namespace Goo + { + } + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, - await VerifyCS.VerifyCodeFixAsync(code, code); - } + // Fixing the first diagnostic introduces a second diagnostic to fix. + NumberOfIncrementalIterations = 2, + NumberOfFixAllIterations = 2, + }.RunAsync(); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542723")] - public async Task TestRemoveCorrectUsing1() - { - var source = """ - using System.Collections.Generic; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542723")] + public async Task TestRemoveCorrectUsing2() + { + var code = """ + using System.Collections.Generic; - namespace Goo - { - [|{|IDE0005:using Bar = Dictionary;|}|] - } - """; - var fixedSource = """ - namespace Goo + namespace Goo + { + using Bar = Dictionary; + + class C { + Bar b; } - """; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await new VerifyCS.Test + [Fact] + public async Task TestSpan() + { + var code = """ + namespace N { - TestCode = source, - FixedCode = fixedSource, + [|{|IDE0005:using System;|}|] + } + """; + var fixedCode = """ + namespace N + { + } + """; - // Fixing the first diagnostic introduces a second diagnostic to fix. - NumberOfIncrementalIterations = 2, - NumberOfFixAllIterations = 2, - }.RunAsync(); - } + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542723")] - public async Task TestRemoveCorrectUsing2() - { - var code = """ - using System.Collections.Generic; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543000")] + public async Task TestMissingWhenErrorsWouldBeGenerated() + { + var code = """ + using System; + using X; + using Y; - namespace Goo + class B + { + static void Main() { - using Bar = Dictionary; - - class C - { - Bar b; - } + Bar(x => x.Goo()); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task TestSpan() - { - var code = """ - namespace N + static void Bar(Action x) { - [|{|IDE0005:using System;|}|] } - """; - var fixedCode = """ - namespace N + + static void Bar(Action x) { } - """; - - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543000")] - public async Task TestMissingWhenErrorsWouldBeGenerated() - { - var code = """ - using System; - using X; - using Y; + } - class B + namespace X + { + public static class A { - static void Main() - { - Bar(x => x.Goo()); - } - - static void Bar(Action x) + public static void Goo(this int x) { } - static void Bar(Action x) + public static void Goo(this string x) { } } + } - namespace X + namespace Y + { + public static class B { - public static class A + public static void Goo(this int x) { - public static void Goo(this int x) - { - } - - public static void Goo(this string x) - { - } } } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544976")] + public async Task TestMissingWhenMeaningWouldChangeInLambda() + { + var code = """ + using System; + using X; + using Y; - namespace Y + class B + { + static void Main() { - public static class B - { - public static void Goo(this int x) - { - } - } + Bar(x => x.Goo(), null); // Prints 1 } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544976")] - public async Task TestMissingWhenMeaningWouldChangeInLambda() - { - var code = """ - using System; - using X; - using Y; + static void Bar(Action x, object y) + { + Console.WriteLine(1); + } - class B + static void Bar(Action x, string y) { - static void Main() - { - Bar(x => x.Goo(), null); // Prints 1 - } + Console.WriteLine(2); + } + } - static void Bar(Action x, object y) + namespace X + { + public static class A + { + public static void Goo(this int x) { - Console.WriteLine(1); } - static void Bar(Action x, string y) + public static void Goo(this string x) { - Console.WriteLine(2); } } + } - namespace X + namespace Y + { + public static class B { - public static class A + public static void Goo(this int x) { - public static void Goo(this int x) - { - } - - public static void Goo(this string x) - { - } } } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } - namespace Y + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544976")] + public async Task TestCasesWithLambdas1() + { + // NOTE: Y is used when speculatively binding "x => x.Goo()". As such, it is marked as + // used even though it isn't in the final bind, and could be removed. However, as we do + // not know if it was necessary to eliminate a speculative lambda bind, we must leave + // it. + var code = """ + using System; + using X; + using Y; + + class B + { + static void Main() { - public static class B - { - public static void Goo(this int x) - { - } - } + Bar(x => x.Goo(), null); // Prints 1 } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544976")] - public async Task TestCasesWithLambdas1() - { - // NOTE: Y is used when speculatively binding "x => x.Goo()". As such, it is marked as - // used even though it isn't in the final bind, and could be removed. However, as we do - // not know if it was necessary to eliminate a speculative lambda bind, we must leave - // it. - var code = """ - using System; - using X; - using Y; - class B + static void Bar(Action x, object y) { - static void Main() - { - Bar(x => x.Goo(), null); // Prints 1 - } - - static void Bar(Action x, object y) - { - } } + } - namespace X + namespace X + { + public static class A { - public static class A + public static void Goo(this string x) { - public static void Goo(this string x) - { - } } } + } - namespace Y + namespace Y + { + public static class B { - public static class B + public static void Goo(this int x) { - public static void Goo(this int x) - { - } } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545646")] - public async Task TestCasesWithLambdas2() - { - var code = """ - using System; - using N; // Falsely claimed as unnecessary + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545646")] + public async Task TestCasesWithLambdas2() + { + var code = """ + using System; + using N; // Falsely claimed as unnecessary - static class C + static class C + { + static void Ex(this string x) { - static void Ex(this string x) - { - } + } - static void Inner(Action x, string y) - { - } + static void Inner(Action x, string y) + { + } - static void Inner(Action x, int y) - { - } + static void Inner(Action x, int y) + { + } - static void Inner(Action x, int y) - { - } + static void Inner(Action x, int y) + { + } - static void Outer(Action x, object y) - { - Console.WriteLine(1); - } + static void Outer(Action x, object y) + { + Console.WriteLine(1); + } - static void Outer(Action x, string y) - { - Console.WriteLine(2); - } + static void Outer(Action x, string y) + { + Console.WriteLine(2); + } - static void Main() - { - Outer(y => Inner(x => x.Ex(), y), null); - } + static void Main() + { + Outer(y => Inner(x => x.Ex(), y), null); } + } - namespace N + namespace N + { + static class E { - static class E + public static void Ex(this int x) { - public static void Ex(this int x) - { - } } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545741")] - public async Task TestMissingOnAliasedVar() - { - var code = """ - using var = var; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545741")] + public async Task TestMissingOnAliasedVar() + { + var code = """ + using var = var; - class var - { - } + class var + { + } - class B + class B + { + static void Main() { - static void Main() - { - var a = 1; - } + var a = 1; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546115")] - public async Task TestBrokenCode() - { - var code = """ - using System.Linq; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546115")] + public async Task TestBrokenCode() + { + var code = """ + using System.Linq; - public class QueryExpressionTest + public class QueryExpressionTest + { + public static void Main() { - public static void Main() - { - var expr1 = new[] { }; - var expr2 = new[] { }; - var query8 = from int i in expr1 - join int fixed in expr2 on i equals fixed select new { i, fixed }; - - var query9 = from object i in expr1 - join object fixed in expr2 on i equals fixed select new { i, fixed }; - } - } - """; - - await new VerifyCS.Test - { - TestCode = code, - ExpectedDiagnostics = - { - // Test0.cs(7,21): error CS0826: No best type found for implicitly-typed array - DiagnosticResult.CompilerError("CS0826").WithSpan(7, 21, 7, 30), - // Test0.cs(8,21): error CS0826: No best type found for implicitly-typed array - DiagnosticResult.CompilerError("CS0826").WithSpan(8, 21, 8, 30), - // Test0.cs(10,31): error CS0742: A query body must end with a select clause or a group clause - DiagnosticResult.CompilerError("CS0742").WithSpan(10, 31, 10, 36), - // Test0.cs(10,31): error CS0743: Expected contextual keyword 'on' - DiagnosticResult.CompilerError("CS0743").WithSpan(10, 31, 10, 36), - // Test0.cs(10,31): error CS0744: Expected contextual keyword 'equals' - DiagnosticResult.CompilerError("CS0744").WithSpan(10, 31, 10, 36), - // Test0.cs(10,31): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(10, 31, 10, 36), - // Test0.cs(10,31): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(10, 31, 10, 36), - // Test0.cs(10,31): error CS1003: Syntax error, 'in' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(10, 31, 10, 36).WithArguments("in"), - // Test0.cs(10,31): error CS1525: Invalid expression term 'fixed' - DiagnosticResult.CompilerError("CS1525").WithSpan(10, 31, 10, 36).WithArguments("fixed"), - // Test0.cs(10,31): error CS1525: Invalid expression term 'fixed' - DiagnosticResult.CompilerError("CS1525").WithSpan(10, 31, 10, 36).WithArguments("fixed"), - // Test0.cs(10,31): error CS1525: Invalid expression term 'fixed' - DiagnosticResult.CompilerError("CS1525").WithSpan(10, 31, 10, 36).WithArguments("fixed"), - // Test0.cs(10,31): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context - DiagnosticResult.CompilerError("CS0214").WithSpan(10, 31, 10, 49), - // Test0.cs(10,37): error CS0209: The type of a local declared in a fixed statement must be a pointer type - DiagnosticResult.CompilerError("CS0209").WithSpan(10, 37, 10, 37), - // Test0.cs(10,37): error CS0210: You must provide an initializer in a fixed or using statement declaration - DiagnosticResult.CompilerError("CS0210").WithSpan(10, 37, 10, 37), - // Test0.cs(10,37): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(10, 37, 10, 39), - // Test0.cs(10,37): error CS1003: Syntax error, '(' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(10, 37, 10, 39).WithArguments("("), - // Test0.cs(10,37): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(10, 37, 10, 39).WithArguments(","), - // Test0.cs(10,37): error CS1031: Type expected - DiagnosticResult.CompilerError("CS1031").WithSpan(10, 37, 10, 39), - // Test0.cs(10,40): error CS0118: 'expr2' is a variable but is used like a type - DiagnosticResult.CompilerError("CS0118").WithSpan(10, 40, 10, 45).WithMessage(null), - // Test0.cs(10,40): error CS1026: ) expected - DiagnosticResult.CompilerError("CS1026").WithSpan(10, 40, 10, 45), - // Test0.cs(10,40): error CS1023: Embedded statement cannot be a declaration or labeled statement - DiagnosticResult.CompilerError("CS1023").WithSpan(10, 40, 10, 49), - // Test0.cs(10,49): error CS0246: The type or namespace name 'i' could not be found (are you missing a using directive or an assembly reference?) - DiagnosticResult.CompilerError("CS0246").WithSpan(10, 49, 10, 50).WithArguments("i"), - // Test0.cs(10,49): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(10, 49, 10, 50), - // Test0.cs(10,58): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(10, 58, 10, 63), - // Test0.cs(10,58): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context - DiagnosticResult.CompilerError("CS0214").WithSpan(10, 58, 10, 80), - // Test0.cs(10,64): error CS0246: The type or namespace name 'select' could not be found (are you missing a using directive or an assembly reference?) - DiagnosticResult.CompilerError("CS0246").WithSpan(10, 64, 10, 70).WithArguments("select"), - // Test0.cs(10,64): error CS1003: Syntax error, '(' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(10, 64, 10, 70).WithArguments("("), - // Test0.cs(10,71): error CS0209: The type of a local declared in a fixed statement must be a pointer type - DiagnosticResult.CompilerError("CS0209").WithSpan(10, 71, 10, 71), - // Test0.cs(10,71): error CS0210: You must provide an initializer in a fixed or using statement declaration - DiagnosticResult.CompilerError("CS0210").WithSpan(10, 71, 10, 71), - // Test0.cs(10,71): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(10, 71, 10, 74), - // Test0.cs(10,71): error CS1026: ) expected - DiagnosticResult.CompilerError("CS1026").WithSpan(10, 71, 10, 74), - // Test0.cs(10,77): error CS0103: The name 'i' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(10, 77, 10, 78).WithArguments("i"), - // Test0.cs(10,80): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(10, 80, 10, 85), - // Test0.cs(10,80): error CS1513: } expected - DiagnosticResult.CompilerError("CS1513").WithSpan(10, 80, 10, 85), - // Test0.cs(10,80): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context - DiagnosticResult.CompilerError("CS0214").WithSpan(10, 80, 10, 86), - // Test0.cs(10,86): error CS0209: The type of a local declared in a fixed statement must be a pointer type - DiagnosticResult.CompilerError("CS0209").WithSpan(10, 86, 10, 86), - // Test0.cs(10,86): error CS0210: You must provide an initializer in a fixed or using statement declaration - DiagnosticResult.CompilerError("CS0210").WithSpan(10, 86, 10, 86), - // Test0.cs(10,86): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(10, 86, 10, 87), - // Test0.cs(10,86): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(10, 86, 10, 87), - // Test0.cs(10,86): error CS1003: Syntax error, '(' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(10, 86, 10, 87).WithArguments("("), - // Test0.cs(10,86): error CS1026: ) expected - DiagnosticResult.CompilerError("CS1026").WithSpan(10, 86, 10, 87), - // Test0.cs(10,86): error CS1031: Type expected - DiagnosticResult.CompilerError("CS1031").WithSpan(10, 86, 10, 87), - // Test0.cs(10,86): error CS1525: Invalid expression term '}' - DiagnosticResult.CompilerError("CS1525").WithSpan(10, 86, 10, 87).WithArguments("}"), - // Test0.cs(10,87): error CS1597: Semicolon after method or accessor block is not valid - DiagnosticResult.CompilerError("CS1597").WithSpan(10, 87, 10, 88), - // Test0.cs(12,5): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code - DiagnosticResult.CompilerError("CS0825").WithSpan(12, 5, 12, 8), - // Test0.cs(12,35): error CS0103: The name 'expr1' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(12, 35, 12, 40).WithArguments("expr1"), - // Test0.cs(13,30): error CS0742: A query body must end with a select clause or a group clause - DiagnosticResult.CompilerError("CS0742").WithSpan(13, 30, 13, 35), - // Test0.cs(13,30): error CS0743: Expected contextual keyword 'on' - DiagnosticResult.CompilerError("CS0743").WithSpan(13, 30, 13, 35), - // Test0.cs(13,30): error CS0744: Expected contextual keyword 'equals' - DiagnosticResult.CompilerError("CS0744").WithSpan(13, 30, 13, 35), - // Test0.cs(13,30): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(13, 30, 13, 35), - // Test0.cs(13,30): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(13, 30, 13, 35), - // Test0.cs(13,30): error CS1003: Syntax error, 'in' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 30, 13, 35).WithArguments("in"), - // Test0.cs(13,30): error CS1525: Invalid expression term 'fixed' - DiagnosticResult.CompilerError("CS1525").WithSpan(13, 30, 13, 35).WithArguments("fixed"), - // Test0.cs(13,30): error CS1525: Invalid expression term 'fixed' - DiagnosticResult.CompilerError("CS1525").WithSpan(13, 30, 13, 35).WithArguments("fixed"), - // Test0.cs(13,30): error CS1525: Invalid expression term 'fixed' - DiagnosticResult.CompilerError("CS1525").WithSpan(13, 30, 13, 35).WithArguments("fixed"), - // Test0.cs(13,36): error CS1642: Fixed size buffer fields may only be members of structs - DiagnosticResult.CompilerError("CS1642").WithSpan(13, 36, 13, 36), - // Test0.cs(13,36): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double - DiagnosticResult.CompilerError("CS1663").WithSpan(13, 36, 13, 36), - // Test0.cs(13,36): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(13, 36, 13, 38), - // Test0.cs(13,36): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 36, 13, 38).WithArguments(","), - // Test0.cs(13,36): error CS1003: Syntax error, '[' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 36, 13, 38).WithArguments("["), - // Test0.cs(13,36): error CS1031: Type expected - DiagnosticResult.CompilerError("CS1031").WithSpan(13, 36, 13, 38), - // Test0.cs(13,36): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context - DiagnosticResult.CompilerError("CS0214").WithSpan(13, 36, 13, 57), - // Test0.cs(13,36): error CS7092: A fixed buffer may only have one dimension. - DiagnosticResult.CompilerError("CS7092").WithSpan(13, 36, 13, 57), - // Test0.cs(13,39): error CS0103: The name 'expr2' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(13, 39, 13, 44).WithArguments("expr2"), - // Test0.cs(13,45): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 45, 13, 47).WithArguments(","), - // Test0.cs(13,48): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 48, 13, 49).WithArguments(","), - // Test0.cs(13,50): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 50, 13, 56).WithArguments(","), - // Test0.cs(13,57): error CS0443: Syntax error; value expected - DiagnosticResult.CompilerError("CS0443").WithSpan(13, 57, 13, 57), - // Test0.cs(13,57): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(13, 57, 13, 62), - // Test0.cs(13,57): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 57, 13, 62).WithArguments(","), - // Test0.cs(13,57): error CS1003: Syntax error, ']' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 57, 13, 62).WithArguments("]"), - // Test0.cs(13,63): error CS0246: The type or namespace name 'select' could not be found (are you missing a using directive or an assembly reference?) - DiagnosticResult.CompilerError("CS0246").WithSpan(13, 63, 13, 69).WithArguments("select"), - // Test0.cs(13,63): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double - DiagnosticResult.CompilerError("CS1663").WithSpan(13, 63, 13, 69), - // Test0.cs(13,70): error CS0102: The type 'QueryExpressionTest' already contains a definition for '' - DiagnosticResult.CompilerError("CS0102").WithSpan(13, 70, 13, 70).WithArguments("QueryExpressionTest", ""), - // Test0.cs(13,70): error CS1642: Fixed size buffer fields may only be members of structs - DiagnosticResult.CompilerError("CS1642").WithSpan(13, 70, 13, 70), - // Test0.cs(13,70): error CS0836: Cannot use anonymous type in a constant expression - DiagnosticResult.CompilerError("CS0836").WithSpan(13, 70, 13, 73), - // Test0.cs(13,70): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(13, 70, 13, 73), - // Test0.cs(13,70): error CS1003: Syntax error, '[' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 70, 13, 73).WithArguments("["), - // Test0.cs(13,70): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context - DiagnosticResult.CompilerError("CS0214").WithSpan(13, 70, 13, 79), - // Test0.cs(13,70): error CS7092: A fixed buffer may only have one dimension. - DiagnosticResult.CompilerError("CS7092").WithSpan(13, 70, 13, 79), - // Test0.cs(13,76): error CS0103: The name 'i' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(13, 76, 13, 77).WithArguments("i"), - // Test0.cs(13,79): error CS0443: Syntax error; value expected - DiagnosticResult.CompilerError("CS0443").WithSpan(13, 79, 13, 79), - // Test0.cs(13,79): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(13, 79, 13, 84), - // Test0.cs(13,79): error CS1003: Syntax error, ',' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 79, 13, 84).WithArguments(","), - // Test0.cs(13,79): error CS1003: Syntax error, ']' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 79, 13, 84).WithArguments("]"), - // Test0.cs(13,79): error CS1513: } expected - DiagnosticResult.CompilerError("CS1513").WithSpan(13, 79, 13, 84), - // Test0.cs(13,85): error CS0102: The type 'QueryExpressionTest' already contains a definition for '' - DiagnosticResult.CompilerError("CS0102").WithSpan(13, 85, 13, 85).WithArguments("QueryExpressionTest", ""), - // Test0.cs(13,85): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context - DiagnosticResult.CompilerError("CS0214").WithSpan(13, 85, 13, 85), - // Test0.cs(13,85): error CS1642: Fixed size buffer fields may only be members of structs - DiagnosticResult.CompilerError("CS1642").WithSpan(13, 85, 13, 85), - // Test0.cs(13,85): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double - DiagnosticResult.CompilerError("CS1663").WithSpan(13, 85, 13, 85), - // Test0.cs(13,85): error CS0443: Syntax error; value expected - DiagnosticResult.CompilerError("CS0443").WithSpan(13, 85, 13, 86), - // Test0.cs(13,85): error CS1001: Identifier expected - DiagnosticResult.CompilerError("CS1001").WithSpan(13, 85, 13, 86), - // Test0.cs(13,85): error CS1002: ; expected - DiagnosticResult.CompilerError("CS1002").WithSpan(13, 85, 13, 86), - // Test0.cs(13,85): error CS1003: Syntax error, '[' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 85, 13, 86).WithArguments("["), - // Test0.cs(13,85): error CS1003: Syntax error, ']' expected - DiagnosticResult.CompilerError("CS1003").WithSpan(13, 85, 13, 86).WithArguments("]"), - // Test0.cs(13,85): error CS1031: Type expected - DiagnosticResult.CompilerError("CS1031").WithSpan(13, 85, 13, 86), - // Test0.cs(14,3): error CS1022: Type or namespace definition, or end-of-file expected - DiagnosticResult.CompilerError("CS1022").WithSpan(14, 3, 14, 4), - // Test0.cs(15,1): error CS1022: Type or namespace definition, or end-of-file expected - DiagnosticResult.CompilerError("CS1022").WithSpan(15, 1, 15, 2), - }, - FixedCode = code, - }.RunAsync(); - } + var expr1 = new[] { }; + var expr2 = new[] { }; + var query8 = from int i in expr1 + join int fixed in expr2 on i equals fixed select new { i, fixed }; - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530980")] - public async Task TestReferenceInCref() + var query9 = from object i in expr1 + join object fixed in expr2 on i equals fixed select new { i, fixed }; + } + } + """; + + await new VerifyCS.Test { - // Parsing doc comments as simple trivia; we don't know System is unnecessary, but CS8019 is disabled so - // no diagnostics are reported. - var code = """ - using System; - /// - class C - { - } - """; - await new VerifyCS.Test + TestCode = code, + ExpectedDiagnostics = { - TestState = - { - Sources = { code }, - DocumentationMode = DocumentationMode.None, - }, - }.RunAsync(); + // Test0.cs(7,21): error CS0826: No best type found for implicitly-typed array + DiagnosticResult.CompilerError("CS0826").WithSpan(7, 21, 7, 30), + // Test0.cs(8,21): error CS0826: No best type found for implicitly-typed array + DiagnosticResult.CompilerError("CS0826").WithSpan(8, 21, 8, 30), + // Test0.cs(10,31): error CS0742: A query body must end with a select clause or a group clause + DiagnosticResult.CompilerError("CS0742").WithSpan(10, 31, 10, 36), + // Test0.cs(10,31): error CS0743: Expected contextual keyword 'on' + DiagnosticResult.CompilerError("CS0743").WithSpan(10, 31, 10, 36), + // Test0.cs(10,31): error CS0744: Expected contextual keyword 'equals' + DiagnosticResult.CompilerError("CS0744").WithSpan(10, 31, 10, 36), + // Test0.cs(10,31): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(10, 31, 10, 36), + // Test0.cs(10,31): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(10, 31, 10, 36), + // Test0.cs(10,31): error CS1003: Syntax error, 'in' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(10, 31, 10, 36).WithArguments("in"), + // Test0.cs(10,31): error CS1525: Invalid expression term 'fixed' + DiagnosticResult.CompilerError("CS1525").WithSpan(10, 31, 10, 36).WithArguments("fixed"), + // Test0.cs(10,31): error CS1525: Invalid expression term 'fixed' + DiagnosticResult.CompilerError("CS1525").WithSpan(10, 31, 10, 36).WithArguments("fixed"), + // Test0.cs(10,31): error CS1525: Invalid expression term 'fixed' + DiagnosticResult.CompilerError("CS1525").WithSpan(10, 31, 10, 36).WithArguments("fixed"), + // Test0.cs(10,31): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + DiagnosticResult.CompilerError("CS0214").WithSpan(10, 31, 10, 49), + // Test0.cs(10,37): error CS0209: The type of a local declared in a fixed statement must be a pointer type + DiagnosticResult.CompilerError("CS0209").WithSpan(10, 37, 10, 37), + // Test0.cs(10,37): error CS0210: You must provide an initializer in a fixed or using statement declaration + DiagnosticResult.CompilerError("CS0210").WithSpan(10, 37, 10, 37), + // Test0.cs(10,37): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(10, 37, 10, 39), + // Test0.cs(10,37): error CS1003: Syntax error, '(' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(10, 37, 10, 39).WithArguments("("), + // Test0.cs(10,37): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(10, 37, 10, 39).WithArguments(","), + // Test0.cs(10,37): error CS1031: Type expected + DiagnosticResult.CompilerError("CS1031").WithSpan(10, 37, 10, 39), + // Test0.cs(10,40): error CS0118: 'expr2' is a variable but is used like a type + DiagnosticResult.CompilerError("CS0118").WithSpan(10, 40, 10, 45).WithMessage(null), + // Test0.cs(10,40): error CS1026: ) expected + DiagnosticResult.CompilerError("CS1026").WithSpan(10, 40, 10, 45), + // Test0.cs(10,40): error CS1023: Embedded statement cannot be a declaration or labeled statement + DiagnosticResult.CompilerError("CS1023").WithSpan(10, 40, 10, 49), + // Test0.cs(10,49): error CS0246: The type or namespace name 'i' could not be found (are you missing a using directive or an assembly reference?) + DiagnosticResult.CompilerError("CS0246").WithSpan(10, 49, 10, 50).WithArguments("i"), + // Test0.cs(10,49): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(10, 49, 10, 50), + // Test0.cs(10,58): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(10, 58, 10, 63), + // Test0.cs(10,58): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + DiagnosticResult.CompilerError("CS0214").WithSpan(10, 58, 10, 80), + // Test0.cs(10,64): error CS0246: The type or namespace name 'select' could not be found (are you missing a using directive or an assembly reference?) + DiagnosticResult.CompilerError("CS0246").WithSpan(10, 64, 10, 70).WithArguments("select"), + // Test0.cs(10,64): error CS1003: Syntax error, '(' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(10, 64, 10, 70).WithArguments("("), + // Test0.cs(10,71): error CS0209: The type of a local declared in a fixed statement must be a pointer type + DiagnosticResult.CompilerError("CS0209").WithSpan(10, 71, 10, 71), + // Test0.cs(10,71): error CS0210: You must provide an initializer in a fixed or using statement declaration + DiagnosticResult.CompilerError("CS0210").WithSpan(10, 71, 10, 71), + // Test0.cs(10,71): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(10, 71, 10, 74), + // Test0.cs(10,71): error CS1026: ) expected + DiagnosticResult.CompilerError("CS1026").WithSpan(10, 71, 10, 74), + // Test0.cs(10,77): error CS0103: The name 'i' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(10, 77, 10, 78).WithArguments("i"), + // Test0.cs(10,80): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(10, 80, 10, 85), + // Test0.cs(10,80): error CS1513: } expected + DiagnosticResult.CompilerError("CS1513").WithSpan(10, 80, 10, 85), + // Test0.cs(10,80): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + DiagnosticResult.CompilerError("CS0214").WithSpan(10, 80, 10, 86), + // Test0.cs(10,86): error CS0209: The type of a local declared in a fixed statement must be a pointer type + DiagnosticResult.CompilerError("CS0209").WithSpan(10, 86, 10, 86), + // Test0.cs(10,86): error CS0210: You must provide an initializer in a fixed or using statement declaration + DiagnosticResult.CompilerError("CS0210").WithSpan(10, 86, 10, 86), + // Test0.cs(10,86): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(10, 86, 10, 87), + // Test0.cs(10,86): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(10, 86, 10, 87), + // Test0.cs(10,86): error CS1003: Syntax error, '(' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(10, 86, 10, 87).WithArguments("("), + // Test0.cs(10,86): error CS1026: ) expected + DiagnosticResult.CompilerError("CS1026").WithSpan(10, 86, 10, 87), + // Test0.cs(10,86): error CS1031: Type expected + DiagnosticResult.CompilerError("CS1031").WithSpan(10, 86, 10, 87), + // Test0.cs(10,86): error CS1525: Invalid expression term '}' + DiagnosticResult.CompilerError("CS1525").WithSpan(10, 86, 10, 87).WithArguments("}"), + // Test0.cs(10,87): error CS1597: Semicolon after method or accessor block is not valid + DiagnosticResult.CompilerError("CS1597").WithSpan(10, 87, 10, 88), + // Test0.cs(12,5): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + DiagnosticResult.CompilerError("CS0825").WithSpan(12, 5, 12, 8), + // Test0.cs(12,35): error CS0103: The name 'expr1' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(12, 35, 12, 40).WithArguments("expr1"), + // Test0.cs(13,30): error CS0742: A query body must end with a select clause or a group clause + DiagnosticResult.CompilerError("CS0742").WithSpan(13, 30, 13, 35), + // Test0.cs(13,30): error CS0743: Expected contextual keyword 'on' + DiagnosticResult.CompilerError("CS0743").WithSpan(13, 30, 13, 35), + // Test0.cs(13,30): error CS0744: Expected contextual keyword 'equals' + DiagnosticResult.CompilerError("CS0744").WithSpan(13, 30, 13, 35), + // Test0.cs(13,30): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(13, 30, 13, 35), + // Test0.cs(13,30): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(13, 30, 13, 35), + // Test0.cs(13,30): error CS1003: Syntax error, 'in' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 30, 13, 35).WithArguments("in"), + // Test0.cs(13,30): error CS1525: Invalid expression term 'fixed' + DiagnosticResult.CompilerError("CS1525").WithSpan(13, 30, 13, 35).WithArguments("fixed"), + // Test0.cs(13,30): error CS1525: Invalid expression term 'fixed' + DiagnosticResult.CompilerError("CS1525").WithSpan(13, 30, 13, 35).WithArguments("fixed"), + // Test0.cs(13,30): error CS1525: Invalid expression term 'fixed' + DiagnosticResult.CompilerError("CS1525").WithSpan(13, 30, 13, 35).WithArguments("fixed"), + // Test0.cs(13,36): error CS1642: Fixed size buffer fields may only be members of structs + DiagnosticResult.CompilerError("CS1642").WithSpan(13, 36, 13, 36), + // Test0.cs(13,36): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double + DiagnosticResult.CompilerError("CS1663").WithSpan(13, 36, 13, 36), + // Test0.cs(13,36): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(13, 36, 13, 38), + // Test0.cs(13,36): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 36, 13, 38).WithArguments(","), + // Test0.cs(13,36): error CS1003: Syntax error, '[' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 36, 13, 38).WithArguments("["), + // Test0.cs(13,36): error CS1031: Type expected + DiagnosticResult.CompilerError("CS1031").WithSpan(13, 36, 13, 38), + // Test0.cs(13,36): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + DiagnosticResult.CompilerError("CS0214").WithSpan(13, 36, 13, 57), + // Test0.cs(13,36): error CS7092: A fixed buffer may only have one dimension. + DiagnosticResult.CompilerError("CS7092").WithSpan(13, 36, 13, 57), + // Test0.cs(13,39): error CS0103: The name 'expr2' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(13, 39, 13, 44).WithArguments("expr2"), + // Test0.cs(13,45): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 45, 13, 47).WithArguments(","), + // Test0.cs(13,48): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 48, 13, 49).WithArguments(","), + // Test0.cs(13,50): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 50, 13, 56).WithArguments(","), + // Test0.cs(13,57): error CS0443: Syntax error; value expected + DiagnosticResult.CompilerError("CS0443").WithSpan(13, 57, 13, 57), + // Test0.cs(13,57): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(13, 57, 13, 62), + // Test0.cs(13,57): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 57, 13, 62).WithArguments(","), + // Test0.cs(13,57): error CS1003: Syntax error, ']' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 57, 13, 62).WithArguments("]"), + // Test0.cs(13,63): error CS0246: The type or namespace name 'select' could not be found (are you missing a using directive or an assembly reference?) + DiagnosticResult.CompilerError("CS0246").WithSpan(13, 63, 13, 69).WithArguments("select"), + // Test0.cs(13,63): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double + DiagnosticResult.CompilerError("CS1663").WithSpan(13, 63, 13, 69), + // Test0.cs(13,70): error CS0102: The type 'QueryExpressionTest' already contains a definition for '' + DiagnosticResult.CompilerError("CS0102").WithSpan(13, 70, 13, 70).WithArguments("QueryExpressionTest", ""), + // Test0.cs(13,70): error CS1642: Fixed size buffer fields may only be members of structs + DiagnosticResult.CompilerError("CS1642").WithSpan(13, 70, 13, 70), + // Test0.cs(13,70): error CS0836: Cannot use anonymous type in a constant expression + DiagnosticResult.CompilerError("CS0836").WithSpan(13, 70, 13, 73), + // Test0.cs(13,70): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(13, 70, 13, 73), + // Test0.cs(13,70): error CS1003: Syntax error, '[' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 70, 13, 73).WithArguments("["), + // Test0.cs(13,70): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + DiagnosticResult.CompilerError("CS0214").WithSpan(13, 70, 13, 79), + // Test0.cs(13,70): error CS7092: A fixed buffer may only have one dimension. + DiagnosticResult.CompilerError("CS7092").WithSpan(13, 70, 13, 79), + // Test0.cs(13,76): error CS0103: The name 'i' does not exist in the current context + DiagnosticResult.CompilerError("CS0103").WithSpan(13, 76, 13, 77).WithArguments("i"), + // Test0.cs(13,79): error CS0443: Syntax error; value expected + DiagnosticResult.CompilerError("CS0443").WithSpan(13, 79, 13, 79), + // Test0.cs(13,79): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(13, 79, 13, 84), + // Test0.cs(13,79): error CS1003: Syntax error, ',' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 79, 13, 84).WithArguments(","), + // Test0.cs(13,79): error CS1003: Syntax error, ']' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 79, 13, 84).WithArguments("]"), + // Test0.cs(13,79): error CS1513: } expected + DiagnosticResult.CompilerError("CS1513").WithSpan(13, 79, 13, 84), + // Test0.cs(13,85): error CS0102: The type 'QueryExpressionTest' already contains a definition for '' + DiagnosticResult.CompilerError("CS0102").WithSpan(13, 85, 13, 85).WithArguments("QueryExpressionTest", ""), + // Test0.cs(13,85): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + DiagnosticResult.CompilerError("CS0214").WithSpan(13, 85, 13, 85), + // Test0.cs(13,85): error CS1642: Fixed size buffer fields may only be members of structs + DiagnosticResult.CompilerError("CS1642").WithSpan(13, 85, 13, 85), + // Test0.cs(13,85): error CS1663: Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double + DiagnosticResult.CompilerError("CS1663").WithSpan(13, 85, 13, 85), + // Test0.cs(13,85): error CS0443: Syntax error; value expected + DiagnosticResult.CompilerError("CS0443").WithSpan(13, 85, 13, 86), + // Test0.cs(13,85): error CS1001: Identifier expected + DiagnosticResult.CompilerError("CS1001").WithSpan(13, 85, 13, 86), + // Test0.cs(13,85): error CS1002: ; expected + DiagnosticResult.CompilerError("CS1002").WithSpan(13, 85, 13, 86), + // Test0.cs(13,85): error CS1003: Syntax error, '[' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 85, 13, 86).WithArguments("["), + // Test0.cs(13,85): error CS1003: Syntax error, ']' expected + DiagnosticResult.CompilerError("CS1003").WithSpan(13, 85, 13, 86).WithArguments("]"), + // Test0.cs(13,85): error CS1031: Type expected + DiagnosticResult.CompilerError("CS1031").WithSpan(13, 85, 13, 86), + // Test0.cs(14,3): error CS1022: Type or namespace definition, or end-of-file expected + DiagnosticResult.CompilerError("CS1022").WithSpan(14, 3, 14, 4), + // Test0.cs(15,1): error CS1022: Type or namespace definition, or end-of-file expected + DiagnosticResult.CompilerError("CS1022").WithSpan(15, 1, 15, 2), + }, + FixedCode = code, + }.RunAsync(); + } - // fully parsing doc comments; System is necessary - await new VerifyCS.Test + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530980")] + public async Task TestReferenceInCref() + { + // Parsing doc comments as simple trivia; we don't know System is unnecessary, but CS8019 is disabled so + // no diagnostics are reported. + var code = """ + using System; + /// + class C { - TestState = - { - Sources = { code }, - DocumentationMode = DocumentationMode.Parse, - }, - }.RunAsync(); + } + """; + await new VerifyCS.Test + { + TestState = + { + Sources = { code }, + DocumentationMode = DocumentationMode.None, + }, + }.RunAsync(); - // fully parsing and diagnosing doc comments; System is necessary - await new VerifyCS.Test + // fully parsing doc comments; System is necessary + await new VerifyCS.Test + { + TestState = { - TestState = - { - Sources = { code }, - DocumentationMode = DocumentationMode.Diagnose, - }, - }.RunAsync(); - } + Sources = { code }, + DocumentationMode = DocumentationMode.Parse, + }, + }.RunAsync(); - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/751283")] - public async Task TestUnusedUsingOverLinq() + // fully parsing and diagnosing doc comments; System is necessary + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - [|using System; - {|IDE0005:using System.Linq; - using System.Threading.Tasks;|}|] + TestState = + { + Sources = { code }, + DocumentationMode = DocumentationMode.Diagnose, + }, + }.RunAsync(); + } - class Program + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/751283")] + public async Task TestUnusedUsingOverLinq() + { + await VerifyCS.VerifyCodeFixAsync( + """ + [|using System; + {|IDE0005:using System.Linq; + using System.Threading.Tasks;|}|] + + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine(); - } + Console.WriteLine(); } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine(); - } + Console.WriteLine(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1323")] - public async Task TestUsingsInPPRegionWithoutOtherMembers() - { - await VerifyCS.VerifyCodeFixAsync( - """ - #if true - [|{|IDE0005:using System;|}|] - #endif - """, - """ - #if true - #endif - """); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(2)] - [InlineData(3)] - [InlineData(4)] - [InlineData(5)] - [WorkItem("https://github.com/dotnet/roslyn/issues/20377")] - public async Task TestWarningLevel(int warningLevel) - { - var code = """ - [|{|IDE0005:using System; - using System.Collections.Generic; - using System.Linq;|}|] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1323")] + public async Task TestUsingsInPPRegionWithoutOtherMembers() + { + await VerifyCS.VerifyCodeFixAsync( + """ + #if true + [|{|IDE0005:using System;|}|] + #endif + """, + """ + #if true + #endif + """); + } - class Program + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(2)] + [InlineData(3)] + [InlineData(4)] + [InlineData(5)] + [WorkItem("https://github.com/dotnet/roslyn/issues/20377")] + public async Task TestWarningLevel(int warningLevel) + { + var code = """ + [|{|IDE0005:using System; + using System.Collections.Generic; + using System.Linq;|}|] + + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """; - var fixedCode = warningLevel switch + } + """; + var fixedCode = warningLevel switch + { + 0 => code, + _ => """ + class Program { - 0 => code, - _ => """ - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - } } - """, - }; + } + """, + }; - var markupMode = warningLevel switch - { - // Hidden diagnostics are not reported for warning level 0 - 0 => MarkupMode.Ignore, + var markupMode = warningLevel switch + { + // Hidden diagnostics are not reported for warning level 0 + 0 => MarkupMode.Ignore, - // But are reported for all other warning levels - _ => MarkupMode.Allow, - }; + // But are reported for all other warning levels + _ => MarkupMode.Allow, + }; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestState = { - TestState = - { - Sources = { code }, - MarkupHandling = markupMode, - }, - FixedCode = fixedCode, - SolutionTransforms = + Sources = { code }, + MarkupHandling = markupMode, + }, + FixedCode = fixedCode, + SolutionTransforms = + { + (solution, projectId) => { - (solution, projectId) => - { - var compilationOptions = (CSharpCompilationOptions)solution.GetRequiredProject(projectId).CompilationOptions!; - return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithWarningLevel(warningLevel)); - }, + var compilationOptions = (CSharpCompilationOptions)solution.GetRequiredProject(projectId).CompilationOptions!; + return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithWarningLevel(warningLevel)); }, - }.RunAsync(); - } + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58972")] - public async Task TestWhitespaceBeforeUnusedUsings_FileScopedNamespace() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58972")] + public async Task TestWhitespaceBeforeUnusedUsings_FileScopedNamespace() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - namespace N; + TestCode = + """ + namespace N; - [|{|IDE0005:using System;|} - using System.Collections.Generic;|] + [|{|IDE0005:using System;|} + using System.Collections.Generic;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """, - FixedCode = - """ - namespace N; + } + """, + FixedCode = + """ + namespace N; - using System.Collections.Generic; + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] - public async Task TestUsingGroups_DeleteLeadingBlankLinesIfFirstGroupWasDeleted_SingleUsing() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] + public async Task TestUsingGroups_DeleteLeadingBlankLinesIfFirstGroupWasDeleted_SingleUsing() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - [|{|IDE0005:using System;|} + TestCode = + """ + [|{|IDE0005:using System;|} - using System.Collections.Generic;|] + using System.Collections.Generic;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """, - FixedCode = - """ - using System.Collections.Generic; + } + """, + FixedCode = + """ + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """ - }.RunAsync(); - } + } + """ + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] - public async Task TestUsingGroups_DeleteLeadingBlankLinesIfFirstGroupWasDeleted_MultipleUsings() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] + public async Task TestUsingGroups_DeleteLeadingBlankLinesIfFirstGroupWasDeleted_MultipleUsings() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - [|{|IDE0005:using System; - using System.Threading.Tasks;|} + TestCode = + """ + [|{|IDE0005:using System; + using System.Threading.Tasks;|} - using System.Collections.Generic;|] + using System.Collections.Generic;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """, - FixedCode = - """ - using System.Collections.Generic; + } + """, + FixedCode = + """ + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """ - }.RunAsync(); - } + } + """ + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] - public async Task TestUsingGroups_NotAllFirstGroupIsDeleted() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] + public async Task TestUsingGroups_NotAllFirstGroupIsDeleted() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - [|{|IDE0005:using System;|} - using System.Threading.Tasks; + TestCode = + """ + [|{|IDE0005:using System;|} + using System.Threading.Tasks; - using System.Collections.Generic;|] + using System.Collections.Generic;|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - Task task = null; - } + var argList = new List(args); + Task task = null; } - """, - FixedCode = - """ - using System.Threading.Tasks; + } + """, + FixedCode = + """ + using System.Threading.Tasks; - using System.Collections.Generic; + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - Task task = null; - } + var argList = new List(args); + Task task = null; } - """ - }.RunAsync(); - } + } + """ + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] - public async Task TestUsingGroups_AllLastGroupIsDeleted() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45866")] + public async Task TestUsingGroups_AllLastGroupIsDeleted() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - [|using System.Collections.Generic; + TestCode = + """ + [|using System.Collections.Generic; - {|IDE0005:using System; - using System.Threading.Tasks;|}|] + {|IDE0005:using System; + using System.Threading.Tasks;|}|] - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """, - FixedCode = - """ - using System.Collections.Generic; + } + """, + FixedCode = + """ + using System.Collections.Generic; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var argList = new List(args); - } + var argList = new List(args); } - """ - }.RunAsync(); - } + } + """ + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests_FixAllTests.cs index 822d28691c047..4c148f0630425 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryImports/RemoveUnnecessaryImportsTests_FixAllTests.cs @@ -13,420 +13,419 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryImports +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryImports; + +public class RemoveUnnecessaryImportsTests_FixAllTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - public class RemoveUnnecessaryImportsTests_FixAllTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveUnnecessaryImportsTests_FixAllTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryImportsCodeFixProvider()); + + #region "Fix all occurrences tests" + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() + { + var input = """ + + + + {|FixAllInDocument:using System; + using System.Collections.Generic;|} + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var input = """ + + + + {|FixAllInProject:using System; + using System.Collections.Generic;|} + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + public Int32 x; + } + + + using System; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProjectSkipsGeneratedCode() + { + var input = """ + + + + {|FixAllInProject:using System; + using System.Collections.Generic;|} + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() + { + var input = """ + + + + {|FixAllInSolution:using System; + using System.Collections.Generic;|} + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + public Int32 x; + } + + + using System; + + class Program2 + { + public Int32 x; + } + + + + + using System; + + class Program3 + { + public Int32 x; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingMember_NotApplicable() + { + var input = """ + + + + {|FixAllInContainingMember:using System; + using System.Collections.Generic;|} + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + await TestMissingInRegularAndScriptAsync(input); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInContainingType_NotApplicable() { - public RemoveUnnecessaryImportsTests_FixAllTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpRemoveUnnecessaryImportsDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryImportsCodeFixProvider()); - - #region "Fix all occurrences tests" - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocument() - { - var input = """ - - - - {|FixAllInDocument:using System; - using System.Collections.Generic;|} - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - var expected = """ - - - - using System; - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject() - { - var input = """ - - - - {|FixAllInProject:using System; - using System.Collections.Generic;|} - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - var expected = """ - - - - using System; - - class Program - { - public Int32 x; - } - - - using System; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProjectSkipsGeneratedCode() - { - var input = """ - - - - {|FixAllInProject:using System; - using System.Collections.Generic;|} - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - var expected = """ - - - - using System; - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution() - { - var input = """ - - - - {|FixAllInSolution:using System; - using System.Collections.Generic;|} - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - var expected = """ - - - - using System; - - class Program - { - public Int32 x; - } - - - using System; - - class Program2 - { - public Int32 x; - } - - - - - using System; - - class Program3 - { - public Int32 x; - } - - - - """; - - await TestInRegularAndScriptAsync(input, expected); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingMember_NotApplicable() - { - var input = """ - - - - {|FixAllInContainingMember:using System; - using System.Collections.Generic;|} - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - await TestMissingInRegularAndScriptAsync(input); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryImports)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInContainingType_NotApplicable() - { - var input = """ - - - - {|FixAllInContainingType:using System; - using System.Collections.Generic;|} - - class Program - { - public Int32 x; - } - - - using System; - using System.Collections.Generic; - - class Program2 - { - public Int32 x; - } - - - - - using System; - using System.Collections.Generic; - - class Program3 - { - public Int32 x; - } - - - - """; - - await TestMissingInRegularAndScriptAsync(input); - } - #endregion + var input = """ + + + + {|FixAllInContainingType:using System; + using System.Collections.Generic;|} + + class Program + { + public Int32 x; + } + + + using System; + using System.Collections.Generic; + + class Program2 + { + public Int32 x; + } + + + + + using System; + using System.Collections.Generic; + + class Program3 + { + public Int32 x; + } + + + + """; + + await TestMissingInRegularAndScriptAsync(input); } + #endregion } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryLambdaExpression/RemoveUnnecessaryLambdaExpressionTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryLambdaExpression/RemoveUnnecessaryLambdaExpressionTests.cs index 9dcb73eea28e9..7bdc80f506142 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryLambdaExpression/RemoveUnnecessaryLambdaExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryLambdaExpression/RemoveUnnecessaryLambdaExpressionTests.cs @@ -12,2028 +12,2027 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryLambdaExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveUnnecessaryLambdaExpressionDiagnosticAnalyzer, - CSharpRemoveUnnecessaryLambdaExpressionCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryLambdaExpression; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnnecessaryLambdaExpressionDiagnosticAnalyzer, + CSharpRemoveUnnecessaryLambdaExpressionCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryLambdaExpression)] - public class RemoveUnnecessaryLambdaExpressionTests +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryLambdaExpression)] +public class RemoveUnnecessaryLambdaExpressionTests +{ + private static async Task TestInRegularAndScriptAsync( + string testCode, + string fixedCode, + LanguageVersion version = LanguageVersion.CSharp12, + OutputKind? outputKind = null) { - private static async Task TestInRegularAndScriptAsync( - string testCode, - string fixedCode, - LanguageVersion version = LanguageVersion.CSharp12, - OutputKind? outputKind = null) + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = version, + TestState = { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = version, - TestState = - { - OutputKind = outputKind, - } - }.RunAsync(); - } + OutputKind = outputKind, + } + }.RunAsync(); + } - private static Task TestMissingInRegularAndScriptAsync( - string testCode, - LanguageVersion version = LanguageVersion.CSharp12, - OutputKind? outputKind = null) - => TestInRegularAndScriptAsync(testCode, testCode, version, outputKind); + private static Task TestMissingInRegularAndScriptAsync( + string testCode, + LanguageVersion version = LanguageVersion.CSharp12, + OutputKind? outputKind = null) + => TestInRegularAndScriptAsync(testCode, testCode, version, outputKind); - [Fact] - public async Task TestMissingInCSharp10() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestMissingInCSharp10() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar(s => Quux(s)); - } - - void Bar(Func f) { } - string Quux(int i) => default; + Bar(s => Quux(s)); } - """, LanguageVersion.CSharp10); - } - [Fact] - public async Task TestBasicCase() - { - await TestInRegularAndScriptAsync( - """ - using System; - - class C - { - void Goo() - { - Bar([|s => |]Quux(s)); - } + void Bar(Func f) { } + string Quux(int i) => default; + } + """, LanguageVersion.CSharp10); + } - void Bar(Func f) { } - string Quux(int i) => default; - } - """, - """ - using System; + [Fact] + public async Task TestBasicCase() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar(Quux); - } - - void Bar(Func f) { } - string Quux(int i) => default; + Bar([|s => |]Quux(s)); } - """); - } - [Fact] - public async Task TestWithOptionOff() - { - var code = """ - using System; + void Bar(Func f) { } + string Quux(int i) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar(s => Quux(s)); - } - - void Bar(Func f) { } - string Quux(int i) => default; + Bar(Quux); } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp12, - Options = { { CSharpCodeStyleOptions.PreferMethodGroupConversion, new CodeStyleOption2(false, NotificationOption2.None) } } - }.RunAsync(); - } - [Fact] - public async Task TestNotOnStaticLambda() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar(static s => Quux(s)); - } + [Fact] + public async Task TestWithOptionOff() + { + var code = """ + using System; - void Bar(Func f) { } - static string Quux(int i) => default; + class C + { + void Goo() + { + Bar(s => Quux(s)); } - """); - } - [Fact] - public async Task TestNotWithOptionalParameter() + void Bar(Func f) { } + string Quux(int i) => default; + } + """; + await new VerifyCS.Test { - await TestMissingInRegularAndScriptAsync( - """ - using System; + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp12, + Options = { { CSharpCodeStyleOptions.PreferMethodGroupConversion, new CodeStyleOption2(false, NotificationOption2.None) } } + }.RunAsync(); + } - class C - { - void Goo() - { - Bar(s => Quux(s)); - } + [Fact] + public async Task TestNotOnStaticLambda() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - static string Quux(int i, int j = 0) => default; + class C + { + void Goo() + { + Bar(static s => Quux(s)); } - """); - } - [Fact] - public async Task TestNotWithParams1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + static string Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar(s => Quux(s)); - } + [Fact] + public async Task TestNotWithOptionalParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - static string Quux(int i, params int[] j) => default; + class C + { + void Goo() + { + Bar(s => Quux(s)); } - """); - } - [Fact] - public async Task TestNotWithParams2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + static string Quux(int i, int j = 0) => default; + } + """); + } - class C - { - void Goo() - { - Bar(s => Quux(s)); - } + [Fact] + public async Task TestNotWithParams1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - static string Quux(params object[] j) => default; + class C + { + void Goo() + { + Bar(s => Quux(s)); } - """); - } - - [Fact] - public async Task TestWithParams1() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C - { - void Goo() - { - Bar([|s => |]Quux(s)); - } + void Bar(Func f) { } + static string Quux(int i, params int[] j) => default; + } + """); + } - void Bar(Func f) { } - string Quux(params object[] o) => default; - } - """, - """ - using System; + [Fact] + public async Task TestNotWithParams2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar(Quux); - } - - void Bar(Func f) { } - string Quux(params object[] o) => default; + Bar(s => Quux(s)); } - """); - } - [Fact] - public async Task TestNotWithRefChange1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + static string Quux(params object[] j) => default; + } + """); + } - class C - { - void Goo() - { - Bar(s => Quux(ref s)); - } + [Fact] + public async Task TestWithParams1() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - static string Quux(ref int i) => default; + class C + { + void Goo() + { + Bar([|s => |]Quux(s)); } - """); - } - - [Fact] - public async Task TestNotWithRefChange2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - delegate string X(ref int i); + void Bar(Func f) { } + string Quux(params object[] o) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar((ref int s) => Quux(s)); - } - - void Bar(X x) { } - static string Quux(int i) => default; + Bar(Quux); } - """); - } - [Fact] - public async Task TestWithSameRef() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(params object[] o) => default; + } + """); + } - delegate string X(ref int i); + [Fact] + public async Task TestNotWithRefChange1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|(ref int s) => |]Quux(ref s)); - } - - void Bar(X x) { } - static string Quux(ref int i) => default; + Bar(s => Quux(ref s)); } - """, - """ - using System; + void Bar(Func f) { } + static string Quux(ref int i) => default; + } + """); + } - delegate string X(ref int i); + [Fact] + public async Task TestNotWithRefChange2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C - { - void Goo() - { - Bar(Quux); - } + delegate string X(ref int i); - void Bar(X x) { } - static string Quux(ref int i) => default; + class C + { + void Goo() + { + Bar((ref int s) => Quux(s)); } - """); - } - [Fact] - public async Task TestNotOnConversionToObject() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(X x) { } + static string Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - object o = (int s) => Quux(s); - } + [Fact] + public async Task TestWithSameRef() + { + await TestInRegularAndScriptAsync( + """ + using System; + + delegate string X(ref int i); - void Bar(Func f) { } - static string Quux(int i) => default; + class C + { + void Goo() + { + Bar([|(ref int s) => |]Quux(ref s)); } - """); - } - [Fact] - public async Task TestWithParenthesizedLambda() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(X x) { } + static string Quux(ref int i) => default; + } + """, - class C - { - void Goo() - { - Bar([|(int s) => |]Quux(s)); - } + """ + using System; - void Bar(Func f) { } - string Quux(int i) => default; - } - """, - """ - using System; + delegate string X(ref int i); - class C + class C + { + void Goo() { - void Goo() - { - Bar(Quux); - } - - void Bar(Func f) { } - string Quux(int i) => default; + Bar(Quux); } - """); - } - [Fact] - public async Task TestWithAnonymousMethod() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(X x) { } + static string Quux(ref int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar([|delegate (int s) { return |]Quux(s); }); - } + [Fact] + public async Task TestNotOnConversionToObject() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i) => default; + class C + { + void Goo() + { + object o = (int s) => Quux(s); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + static string Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestWithParenthesizedLambda() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i) => default; + class C + { + void Goo() + { + Bar([|(int s) => |]Quux(s)); } - """); - } - [Fact] - public async Task TestWithAnonymousMethodNoParameterList() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|delegate { return |]Quux(); }); - } - - void Bar(Func f) { } - string Quux() => default; + Bar(Quux); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + string Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestWithAnonymousMethod() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux() => default; + class C + { + void Goo() + { + Bar([|delegate (int s) { return |]Quux(s); }); } - """); - } - [Fact] - public async Task TestFixCoContravariance1() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|s => |]Quux(s)); - } - - void Bar(Func f) { } - string Quux(object o) => default; + Bar(Quux); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + string Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestWithAnonymousMethodNoParameterList() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(object o) => default; + class C + { + void Goo() + { + Bar([|delegate { return |]Quux(); }); } - """); - } - [Fact] - public async Task TestFixCoContravariance2() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux() => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|s => |]Quux(s)); - } - - void Bar(Func f) { } - string Quux(object o) => default; + Bar(Quux); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + string Quux() => default; + } + """); + } + + [Fact] + public async Task TestFixCoContravariance1() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(object o) => default; + class C + { + void Goo() + { + Bar([|s => |]Quux(s)); } - """); - } - [Fact] - public async Task TestFixCoContravariance3() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(object o) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar(s => {|CS1662:{|CS0266:Quux(s)|}|}); - } - - void Bar(Func f) { } - object Quux(object o) => default; + Bar(Quux); } - """); - } - [Fact] - public async Task TestFixCoContravariance4() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(object o) => default; + } + """); + } - class C - { - void Goo() - { - Bar(s => Quux({|CS1503:s|})); - } + [Fact] + public async Task TestFixCoContravariance2() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(string o) => default; + class C + { + void Goo() + { + Bar([|s => |]Quux(s)); } - """); - } - [Fact] - public async Task TestFixCoContravariance5() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(object o) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar(s => Quux({|CS1503:s|})); - } - - void Bar(Func f) { } - object Quux(string o) => default; + Bar(Quux); } - """); - } - [Fact] - public async Task TestTwoArgs() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(object o) => default; + } + """); + } - class C - { - void Goo() - { - Bar([|(s1, s2) => |]Quux(s1, s2)); - } + [Fact] + public async Task TestFixCoContravariance3() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i, bool b) => default; + class C + { + void Goo() + { + Bar(s => {|CS1662:{|CS0266:Quux(s)|}|}); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + object Quux(object o) => default; + } + """); + } + + [Fact] + public async Task TestFixCoContravariance4() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i, bool b) => default; + class C + { + void Goo() + { + Bar(s => Quux({|CS1503:s|})); } - """); - } - [Fact] - public async Task TestMultipleArgIncorrectPassing1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(string o) => default; + } + """); + } - class C - { - void Goo() - { - Bar((s1, s2) => Quux(s2, s1)); - } + [Fact] + public async Task TestFixCoContravariance5() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i, int b) => default; + class C + { + void Goo() + { + Bar(s => Quux({|CS1503:s|})); } - """); - } - [Fact] - public async Task TestMultipleArgIncorrectPassing2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + object Quux(string o) => default; + } + """); + } - class C - { - void Goo() - { - Bar((s1, s2) => Quux(s1, s1)); - } + [Fact] + public async Task TestTwoArgs() + { + await TestInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i, int b) => default; + class C + { + void Goo() + { + Bar([|(s1, s2) => |]Quux(s1, s2)); } - """); - } - [Fact] - public async Task TestMultipleArgIncorrectPassing3() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Bar((s1, s2) => Quux(s1, true)); - } - - void Bar(Func f) { } - string Quux(int i, bool b) => default; + Bar(Quux); } - """); - } - [Fact] - public async Task TestReturnStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """); + } - class C - { - void Goo() - { - Bar([|(s1, s2) => { - return |]Quux(s1, s2); - }); - } + [Fact] + public async Task TestMultipleArgIncorrectPassing1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i, bool b) => default; + class C + { + void Goo() + { + Bar((s1, s2) => Quux(s2, s1)); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + string Quux(int i, int b) => default; + } + """); + } - void Bar(Func f) { } - string Quux(int i, bool b) => default; + [Fact] + public async Task TestMultipleArgIncorrectPassing2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void Goo() + { + Bar((s1, s2) => Quux(s1, s1)); } - """); - } - [Fact] - public async Task TestReturnStatement2() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i, int b) => default; + } + """); + } - class C - { - void Goo() - { - Bar([|(s1, s2) => { - return |]this.Quux(s1, s2); - }); - } + [Fact] + public async Task TestMultipleArgIncorrectPassing3() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i, bool b) => default; + class C + { + void Goo() + { + Bar((s1, s2) => Quux(s1, true)); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(this.Quux); - } + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """); + } - void Bar(Func f) { } - string Quux(int i, bool b) => default; + [Fact] + public async Task TestReturnStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + void Goo() + { + Bar([|(s1, s2) => { + return |]Quux(s1, s2); + }); } - """); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542562")] - public async Task TestMissingOnAmbiguity1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """, + """ + using System; - class A + class C + { + void Goo() { - static void Goo(T x) - { - } + Bar(Quux); + } - static void Bar(Action x) - { - } + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """); + } - static void Bar(Action x) - { - } + [Fact] + public async Task TestReturnStatement2() + { + await TestInRegularAndScriptAsync( + """ + using System; - static void Main() - { - {|CS0121:Bar|}(x => Goo(x)); - } + class C + { + void Goo() + { + Bar([|(s1, s2) => { + return |]this.Quux(s1, s2); + }); } - """); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542562")] - public async Task TestWithConstraint1() - { - var code = """ - using System; - class A + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """, + """ + using System; + + class C + { + void Goo() { - static void Goo(T x) where T : class - { - } + Bar(this.Quux); + } - static void Bar(Action x) - { - } + void Bar(Func f) { } + string Quux(int i, bool b) => default; + } + """); + } - static void Bar(Action x) - { - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542562")] + public async Task TestMissingOnAmbiguity1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - static void Main() - { - Bar([|x => |]Goo(x)); - } + class A + { + static void Goo(T x) + { } - """; - var expected = """ - using System; - class A + static void Bar(Action x) { - static void Goo(T x) where T : class - { - } - - static void Bar(Action x) - { - } - - static void Bar(Action x) - { - } + } - static void Main() - { - Bar(Goo); - } + static void Bar(Action x) + { } - """; - await TestInRegularAndScriptAsync(code, expected); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542562")] - public async Task TestWithConstraint2() - { - var code = """ - using System; - class A + static void Main() { - static void Goo(T x) where T : class - { - } + {|CS0121:Bar|}(x => Goo(x)); + } + } + """); + } - static void Bar(Action x) - { - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542562")] + public async Task TestWithConstraint1() + { + var code = """ + using System; + class A + { + static void Goo(T x) where T : class + { + } - static void Bar(Action x) - { - } + static void Bar(Action x) + { + } - static void Main() - { - Bar(x => Goo(x)); - } + static void Bar(Action x) + { } - """; - await TestMissingInRegularAndScriptAsync(code); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/627092")] - public async Task TestMissingOnLambdaWithDynamic_1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + static void Main() + { + Bar([|x => |]Goo(x)); + } + } + """; - class Program + var expected = """ + using System; + class A + { + static void Goo(T x) where T : class { - static void Main() - { - C.InvokeGoo(); - } } - class C + static void Bar(Action x) { - public static void InvokeGoo() - { - Action goo = (x, y) => C.Goo(x, y); // Simplify lambda expression - goo(1, ""); - } + } - static void Goo(object x, object y) - { - Console.WriteLine("Goo(object x, object y)"); - } + static void Bar(Action x) + { + } - static void Goo(object x, T y) - { - Console.WriteLine("Goo(object x, T y)"); - } + static void Main() + { + Bar(Goo); } - """); - } + } + """; + await TestInRegularAndScriptAsync(code, expected); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/627092")] - public async Task TestWithLambdaWithDynamic() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542562")] + public async Task TestWithConstraint2() + { + var code = """ + using System; + class A + { + static void Goo(T x) where T : class + { + } - class Program + static void Bar(Action x) { - static void Main() - { - C.InvokeGoo(); - } } - class C + static void Bar(Action x) { - public static void InvokeGoo() - { - Action goo = [|x => |]C.Goo(x); // Simplify lambda expression - goo(1); - } + } - private static void Goo(dynamic x) - { - throw new NotImplementedException(); - } + static void Main() + { + Bar(x => Goo(x)); + } + } + """; + await TestMissingInRegularAndScriptAsync(code); + } - static void Goo(object x, object y) - { - Console.WriteLine("Goo(object x, object y)"); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/627092")] + public async Task TestMissingOnLambdaWithDynamic_1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - static void Goo(object x, T y) - { - Console.WriteLine("Goo(object x, T y)"); - } + class Program + { + static void Main() + { + C.InvokeGoo(); } - """, - """ - using System; + } - class Program + class C + { + public static void InvokeGoo() { - static void Main() - { - C.InvokeGoo(); - } + Action goo = (x, y) => C.Goo(x, y); // Simplify lambda expression + goo(1, ""); } - class C + static void Goo(object x, object y) { - public static void InvokeGoo() - { - Action goo = C.Goo; // Simplify lambda expression - goo(1); - } + Console.WriteLine("Goo(object x, object y)"); + } - private static void Goo(dynamic x) - { - throw new NotImplementedException(); - } + static void Goo(object x, T y) + { + Console.WriteLine("Goo(object x, T y)"); + } + } + """); + } - static void Goo(object x, object y) - { - Console.WriteLine("Goo(object x, object y)"); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/627092")] + public async Task TestWithLambdaWithDynamic() + { + await TestInRegularAndScriptAsync( + """ + using System; - static void Goo(object x, T y) - { - Console.WriteLine("Goo(object x, T y)"); - } + class Program + { + static void Main() + { + C.InvokeGoo(); } - """); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544625")] - public async Task ParenthesizeIfParseChanges() - { - var code = """ - using System; - class C + class C + { + public static void InvokeGoo() { - static void M() - { - C x = new C(); - int y = 1; - Bar([|() => { return |]Console.ReadLine(); } < x, y > (1 + 2)); - } + Action goo = [|x => |]C.Goo(x); // Simplify lambda expression + goo(1); + } - static void Bar(object a, object b) { } - public static bool operator <(Func y, C x) { return true; } - public static bool operator >(Func y, C x) { return true; } + private static void Goo(dynamic x) + { + throw new NotImplementedException(); } - """; - var expected = """ - using System; - class C + static void Goo(object x, object y) { - static void M() - { - C x = new C(); - int y = 1; - Bar((Console.ReadLine) < x, y > (1 + 2)); - } + Console.WriteLine("Goo(object x, object y)"); + } - static void Bar(object a, object b) { } - public static bool operator <(Func y, C x) { return true; } - public static bool operator >(Func y, C x) { return true; } + static void Goo(object x, T y) + { + Console.WriteLine("Goo(object x, T y)"); } - """; + } + """, + """ + using System; - await TestInRegularAndScriptAsync(code, expected); - } + class Program + { + static void Main() + { + C.InvokeGoo(); + } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545856")] - public async Task TestNotWithSideEffects() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + class C + { + public static void InvokeGoo() + { + Action goo = C.Goo; // Simplify lambda expression + goo(1); + } - class C + private static void Goo(dynamic x) { - void Main() - { - Func a = () => new C().ToString(); - } + throw new NotImplementedException(); } - """); - } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545994")] - public async Task TestExpressionStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; + static void Goo(object x, object y) + { + Console.WriteLine("Goo(object x, object y)"); + } - class Program + static void Goo(object x, T y) { - static void Main() - { - Action a = [|() => { - |]Console.WriteLine(); - }; - } + Console.WriteLine("Goo(object x, T y)"); } - """, - """ - using System; + } + """); + } - class Program + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544625")] + public async Task ParenthesizeIfParseChanges() + { + var code = """ + using System; + class C + { + static void M() { - static void Main() - { - Action a = Console.WriteLine; - } + C x = new C(); + int y = 1; + Bar([|() => { return |]Console.ReadLine(); } < x, y > (1 + 2)); } - """); - } - [Fact] - public async Task TestTaskOfT1() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + static void Bar(object a, object b) { } + public static bool operator <(Func y, C x) { return true; } + public static bool operator >(Func y, C x) { return true; } + } + """; - class C + var expected = """ + using System; + class C + { + static void M() { - void Goo() - { - Bar([|s => |]Quux(s)); - } - - void Bar(Func> f) { } - Task Quux(int i) => default; + C x = new C(); + int y = 1; + Bar((Console.ReadLine) < x, y > (1 + 2)); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + static void Bar(object a, object b) { } + public static bool operator <(Func y, C x) { return true; } + public static bool operator >(Func y, C x) { return true; } + } + """; - void Bar(Func> f) { } - Task Quux(int i) => default; - } - """); - } + await TestInRegularAndScriptAsync(code, expected); + } - [Fact] - public async Task TestAsyncTaskOfT1() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545856")] + public async Task TestNotWithSideEffects() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Main() { - void Goo() - { - Bar([|async s => await |]Quux(s)); - } - - void Bar(Func> f) { } - Task Quux(int i) => default; + Func a = () => new C().ToString(); } - """, - """ - using System; - using System.Threading.Tasks; + } + """); + } - class C + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545994")] + public async Task TestExpressionStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; + + class Program + { + static void Main() { - void Goo() - { - Bar(Quux); - } + Action a = [|() => { + |]Console.WriteLine(); + }; + } + } + """, + """ + using System; - void Bar(Func> f) { } - Task Quux(int i) => default; + class Program + { + static void Main() + { + Action a = Console.WriteLine; } - """); - } + } + """); + } - [Fact] - public async Task TestAsyncTaskOfT2() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task TestTaskOfT1() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|async s => await |]Quux(s).ConfigureAwait(false)); - } - - void Bar(Func> f) { } - Task Quux(int i) => default; + Bar([|s => |]Quux(s)); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - void Bar(Func> f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar(Quux); } - """); - } - [Fact] - public async Task TestAsyncNoAwait1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar(async s => Quux(s)); - } + [Fact] + public async Task TestAsyncTaskOfT1() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func> f) { } - string Quux(int i) => default; + class C + { + void Goo() + { + Bar([|async s => await |]Quux(s)); } - """); - } - [Fact] - public async Task TestTaskOfT1_Return() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|s => { return |]Quux(s); }); - } - - void Bar(Func> f) { } - Task Quux(int i) => default; + Bar(Quux); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestAsyncTaskOfT2() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func> f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar([|async s => await |]Quux(s).ConfigureAwait(false)); } - """); - } - [Fact] - public async Task TestAsyncTaskOfT1_Return() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|async s => { return await |]Quux(s); }); - } - - void Bar(Func> f) { } - Task Quux(int i) => default; + Bar(Quux); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """); + } - void Bar(Func> f) { } - Task Quux(int i) => default; + [Fact] + public async Task TestAsyncNoAwait1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() + { + Bar(async s => Quux(s)); } - """); - } - [Fact] - public async Task TestAsyncTaskOfT2_Return() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + string Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar([|async s => { return await |]Quux(s).ConfigureAwait(false); }); - } + [Fact] + public async Task TestTaskOfT1_Return() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func> f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar([|s => { return |]Quux(s); }); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - void Bar(Func> f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar(Quux); } - """); - } - [Fact] - public async Task TestAsyncNoAwait1_Return() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar(async s => { return Quux(s); }); - } + [Fact] + public async Task TestAsyncTaskOfT1_Return() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func> f) { } - string Quux(int i) => default; + class C + { + void Goo() + { + Bar([|async s => { return await |]Quux(s); }); } - """); - } - [Fact] - public async Task TestTask1() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|s => |]Quux(s)); - } - - void Bar(Func f) { } - Task Quux(int i) => default; + Bar(Quux); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestAsyncTaskOfT2_Return() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar([|async s => { return await |]Quux(s).ConfigureAwait(false); }); } - """); - } - [Fact] - public async Task TestAsyncTask1() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|async s => await |]Quux(s)); - } - - void Bar(Func f) { } - Task Quux(int i) => default; + Bar(Quux); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func> f) { } + Task Quux(int i) => default; + } + """); + } - void Bar(Func f) { } - Task Quux(int i) => default; + [Fact] + public async Task TestAsyncNoAwait1_Return() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() + { + Bar(async s => { return Quux(s); }); } - """); - } - [Fact] - public async Task TestAsyncTask2() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func> f) { } + string Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar([|async s => await |]Quux(s).ConfigureAwait(false)); - } + [Fact] + public async Task TestTask1() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar([|s => |]Quux(s)); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar(Quux); } - """); - } - [Fact] - public async Task TestTask1_ExpressionStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func f) { } + Task Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar(s {|CS1643:=>|} { Quux(s); }); - } + [Fact] + public async Task TestAsyncTask1() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar([|async s => await |]Quux(s)); } - """); - } - [Fact] - public async Task TestAsyncTask1_ExpressionStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|async s => { await |]Quux(s); }); - } - - void Bar(Func f) { } - Task Quux(int i) => default; + Bar(Quux); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + Task Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestAsyncTask2() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar([|async s => await |]Quux(s).ConfigureAwait(false)); } - """); - } - [Fact] - public async Task TestAsyncTask2_ExpressionStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Bar([|async s => { await |]Quux(s).ConfigureAwait(false); }); - } - - void Bar(Func f) { } - Task Quux(int i) => default; + Bar(Quux); } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Bar(Quux); - } + void Bar(Func f) { } + Task Quux(int i) => default; + } + """); + } + + [Fact] + public async Task TestTask1_ExpressionStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - Task Quux(int i) => default; + class C + { + void Goo() + { + Bar(s {|CS1643:=>|} { Quux(s); }); } - """); - } - [Fact] - public async Task TestAsyncNoAwait1_ExpressionStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + void Bar(Func f) { } + Task Quux(int i) => default; + } + """); + } - class C - { - void Goo() - { - Bar(async s => { Quux(s); }); - } + [Fact] + public async Task TestAsyncTask1_ExpressionStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - void Bar(Func f) { } - void Quux(int i) { } + class C + { + void Goo() + { + Bar([|async s => { await |]Quux(s); }); } - """); - } - [Fact] - public async Task TestExplicitGenericCall() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Action a = [|() => |]Quux(); - } - - void Quux() { } + Bar(Quux); } - """, - """ - using System; - class C - { - void Goo() - { - Action a = Quux; - } + void Bar(Func f) { } + Task Quux(int i) => default; + } + """); + } - void Quux() { } + [Fact] + public async Task TestAsyncTask2_ExpressionStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; + + class C + { + void Goo() + { + Bar([|async s => { await |]Quux(s).ConfigureAwait(false); }); } - """); - } - [Fact] - public async Task TestImplicitGenericCall() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void Bar(Func f) { } + Task Quux(int i) => default; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Action a = b => Quux(b); - } - - void Quux(T t) { } + Bar(Quux); } - """); - } - [Fact] - public async Task TestNullabilityChanges() - { - await TestMissingInRegularAndScriptAsync( - """ - #nullable enable + void Bar(Func f) { } + Task Quux(int i) => default; + } + """); + } - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; + [Fact] + public async Task TestAsyncNoAwait1_ExpressionStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo(List assemblies, HashSet usedProjectFileNames) - { - var projectAssemblyFileNames = Select(assemblies, a => GetFileName(a)); - var v = Any(projectAssemblyFileNames, usedProjectFileNames.Contains); - } + Bar(async s => { Quux(s); }); + } - static List Select(List items, Func map) => new(); + void Bar(Func f) { } + void Quux(int i) { } + } + """); + } - [return: NotNullIfNotNull("path")] - static string? GetFileName(string? path) => path; + [Fact] + public async Task TestExplicitGenericCall() + { + await TestInRegularAndScriptAsync( + """ + using System; - static bool Any(List immutableArray, Func predicate) => true; + class C + { + void Goo() + { + Action a = [|() => |]Quux(); } - namespace System.Diagnostics.CodeAnalysis - { - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] - public sealed class NotNullIfNotNullAttribute : Attribute - { - public string ParameterName => ""; + void Quux() { } + } + """, + """ + using System; - public NotNullIfNotNullAttribute(string parameterName) - { - } - } + class C + { + void Goo() + { + Action a = Quux; } - """); - } - [Fact] - public async Task TestTrivia1() - { - await TestInRegularAndScriptAsync( - """ - using System; + void Quux() { } + } + """); + } - class C - { - void Goo() - { - Bar(/*before*/[|s => |]Quux(s)/*after*/); - } + [Fact] + public async Task TestImplicitGenericCall() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void Bar(Func f) { } - string Quux(int i) => default; + class C + { + void Goo() + { + Action a = b => Quux(b); } - """, - """ - using System; - class C - { - void Goo() - { - Bar(/*before*/Quux/*after*/); - } + void Quux(T t) { } + } + """); + } - void Bar(Func f) { } - string Quux(int i) => default; - } - """); - } + [Fact] + public async Task TestNullabilityChanges() + { + await TestMissingInRegularAndScriptAsync( + """ + #nullable enable - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63465")] - public async Task TestNotWithPartialDefinition() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Diagnostics; + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; - public partial class C + class C + { + void Goo(List assemblies, HashSet usedProjectFileNames) { - internal void M1() - { - M2(x => M3(x)); - } + var projectAssemblyFileNames = Select(assemblies, a => GetFileName(a)); + var v = Any(projectAssemblyFileNames, usedProjectFileNames.Contains); + } - partial void M3(string s); + static List Select(List items, Func map) => new(); - private static void M2(Action a) { } - } - """); - } + [return: NotNullIfNotNull("path")] + static string? GetFileName(string? path) => path; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63465")] - public async Task TestWithPartialDefinitionAndImplementation() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Diagnostics; + static bool Any(List immutableArray, Func predicate) => true; + } - public partial class C + namespace System.Diagnostics.CodeAnalysis + { + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] + public sealed class NotNullIfNotNullAttribute : Attribute { - internal void M1() + public string ParameterName => ""; + + public NotNullIfNotNullAttribute(string parameterName) { - M2([|x => |]M3(x)); } + } + } + """); + } - partial void M3(string s); - partial void M3(string s) { } + [Fact] + public async Task TestTrivia1() + { + await TestInRegularAndScriptAsync( + """ + using System; - private static void M2(Action a) { } + class C + { + void Goo() + { + Bar(/*before*/[|s => |]Quux(s)/*after*/); } - """, - """ - using System; - using System.Diagnostics; - public partial class C + void Bar(Func f) { } + string Quux(int i) => default; + } + """, + """ + using System; + + class C + { + void Goo() { - internal void M1() - { - M2(M3); - } + Bar(/*before*/Quux/*after*/); + } + + void Bar(Func f) { } + string Quux(int i) => default; + } + """); + } - partial void M3(string s); - partial void M3(string s) { } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63465")] + public async Task TestNotWithPartialDefinition() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Diagnostics; - private static void M2(Action a) { } + public partial class C + { + internal void M1() + { + M2(x => M3(x)); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63464")] - public async Task TestNotWithConditionalAttribute() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - using System.Diagnostics; + partial void M3(string s); - public class C - { - internal void M1() - { - M2(x => M3(x)); - } + private static void M2(Action a) { } + } + """); + } - [Conditional("DEBUG")] - internal void M3(string s) { } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63465")] + public async Task TestWithPartialDefinitionAndImplementation() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Diagnostics; - private static void M2(Action a) { } + public partial class C + { + internal void M1() + { + M2([|x => |]M3(x)); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] - public async Task TestNotWithAssignmentOfInvokedExpression1() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - using System.Threading.Tasks; + partial void M3(string s); + partial void M3(string s) { } - TaskCompletionSource valueSet = new(); - Helper helper = new(v => valueSet.SetResult(v)); - helper.Set(true); - valueSet = new(); - helper.Set(false); + private static void M2(Action a) { } + } + """, + """ + using System; + using System.Diagnostics; - class Helper + public partial class C + { + internal void M1() { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } - - internal void Set(bool value) => action(value); + M2(M3); } - - """, outputKind: OutputKind.ConsoleApplication); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] - public async Task TestWithoutAssignmentOfInvokedExpression1() - { - await TestInRegularAndScriptAsync(""" - using System; - using System.Threading.Tasks; + partial void M3(string s); + partial void M3(string s) { } + + private static void M2(Action a) { } + } + """); + } - TaskCompletionSource valueSet = new(); - Helper helper = new([|v => |]valueSet.SetResult(v)); - helper.Set(true); - helper.Set(false); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63464")] + public async Task TestNotWithConditionalAttribute() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + using System.Diagnostics; - class Helper + public class C + { + internal void M1() { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } - - internal void Set(bool value) => action(value); + M2(x => M3(x)); } - - """, """ - using System; - using System.Threading.Tasks; - TaskCompletionSource valueSet = new(); - Helper helper = new(valueSet.SetResult); - helper.Set(true); - helper.Set(false); + [Conditional("DEBUG")] + internal void M3(string s) { } - class Helper - { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } + private static void M2(Action a) { } + } + """); + } - internal void Set(bool value) => action(value); - } - - """, - outputKind: OutputKind.ConsoleApplication); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] + public async Task TestNotWithAssignmentOfInvokedExpression1() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + using System.Threading.Tasks; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] - public async Task TestNotWithAssignmentOfInvokedExpression2() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - using System.Threading.Tasks; + TaskCompletionSource valueSet = new(); + Helper helper = new(v => valueSet.SetResult(v)); + helper.Set(true); + valueSet = new(); + helper.Set(false); - class C - { - void M() - { - TaskCompletionSource valueSet = new(); - Helper helper = new(v => valueSet.SetResult(v)); - helper.Set(true); - valueSet = new(); - helper.Set(false); - } - } + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """, outputKind: OutputKind.ConsoleApplication); + } - class Helper - { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] + public async Task TestWithoutAssignmentOfInvokedExpression1() + { + await TestInRegularAndScriptAsync(""" + using System; + using System.Threading.Tasks; - internal void Set(bool value) => action(value); - } - - """); - } + TaskCompletionSource valueSet = new(); + Helper helper = new([|v => |]valueSet.SetResult(v)); + helper.Set(true); + helper.Set(false); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] - public async Task TestWithoutAssignmentOfInvokedExpression2() - { - await TestInRegularAndScriptAsync(""" - using System; - using System.Threading.Tasks; + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """, """ + using System; + using System.Threading.Tasks; + + TaskCompletionSource valueSet = new(); + Helper helper = new(valueSet.SetResult); + helper.Set(true); + helper.Set(false); + + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """, + outputKind: OutputKind.ConsoleApplication); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] + public async Task TestNotWithAssignmentOfInvokedExpression2() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() - { - TaskCompletionSource valueSet = new(); - Helper helper = new([|v => |]valueSet.SetResult(v)); - helper.Set(true); - helper.Set(false); - } + TaskCompletionSource valueSet = new(); + Helper helper = new(v => valueSet.SetResult(v)); + helper.Set(true); + valueSet = new(); + helper.Set(false); } + } - class Helper - { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """); + } - internal void Set(bool value) => action(value); - } - - """, """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] + public async Task TestWithoutAssignmentOfInvokedExpression2() + { + await TestInRegularAndScriptAsync(""" + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - TaskCompletionSource valueSet = new(); - Helper helper = new(valueSet.SetResult); - helper.Set(true); - helper.Set(false); - } + TaskCompletionSource valueSet = new(); + Helper helper = new([|v => |]valueSet.SetResult(v)); + helper.Set(true); + helper.Set(false); } + } - class Helper + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """, """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } - - internal void Set(bool value) => action(value); + TaskCompletionSource valueSet = new(); + Helper helper = new(valueSet.SetResult); + helper.Set(true); + helper.Set(false); } - - """); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] - public async Task TestWithoutAssignmentOfInvokedExpression3() - { - await TestInRegularAndScriptAsync(""" - using System; - using System.Threading.Tasks; + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """); + } - class C - { - void M() - { - TaskCompletionSource valueSet = new(); - Helper helper = new([|v => |]valueSet.SetResult(v)); - helper.Set(true); - helper.Set(false); - - var v = () => - { - // this is a different local. it should not impact the outer simplification - TaskCompletionSource valueSet = new(); - valueSet = new(); - }; - } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69094")] + public async Task TestWithoutAssignmentOfInvokedExpression3() + { + await TestInRegularAndScriptAsync(""" + using System; + using System.Threading.Tasks; - class Helper + class C + { + void M() { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } + TaskCompletionSource valueSet = new(); + Helper helper = new([|v => |]valueSet.SetResult(v)); + helper.Set(true); + helper.Set(false); - internal void Set(bool value) => action(value); + var v = () => + { + // this is a different local. it should not impact the outer simplification + TaskCompletionSource valueSet = new(); + valueSet = new(); + }; } - - """, """ - using System; - using System.Threading.Tasks; + } - class C + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """, """ + using System; + using System.Threading.Tasks; + + class C + { + void M() { - void M() + TaskCompletionSource valueSet = new(); + Helper helper = new(valueSet.SetResult); + helper.Set(true); + helper.Set(false); + + var v = () => { + // this is a different local. it should not impact the outer simplification TaskCompletionSource valueSet = new(); - Helper helper = new(valueSet.SetResult); - helper.Set(true); - helper.Set(false); - - var v = () => - { - // this is a different local. it should not impact the outer simplification - TaskCompletionSource valueSet = new(); - valueSet = new(); - }; - } + valueSet = new(); + }; } + } - class Helper - { - private readonly Action action; - internal Helper(Action action) - { - this.action = action; - } + class Helper + { + private readonly Action action; + internal Helper(Action action) + { + this.action = action; + } + + internal void Set(bool value) => action(value); + } + + """); + } - internal void Set(bool value) => action(value); - } - - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71300")] + public async Task TestWithWriteInOtherMethod() + { + await TestInRegularAndScriptAsync(""" + using System; + using System.Linq; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71300")] - public async Task TestWithWriteInOtherMethod() - { - await TestInRegularAndScriptAsync(""" - using System; - using System.Linq; + public class Repro + { + private readonly MethodProvider _methodProvider; - public class Repro + public Repro(MethodProvider methodProvider) { - private readonly MethodProvider _methodProvider; - - public Repro(MethodProvider methodProvider) - { - // Assignment that should not block feature. - _methodProvider = methodProvider; - } - - public void Main() - { - int[] numbers = { 1, 2, 3, 4, 5 }; - string[] asStrings = numbers.Select([|x => |]_methodProvider.ToStr(x)).ToArray(); - Console.WriteLine(asStrings.Length); - } + // Assignment that should not block feature. + _methodProvider = methodProvider; } - public class MethodProvider + public void Main() { - public string ToStr(int x) - { - return x.ToString(); - } + int[] numbers = { 1, 2, 3, 4, 5 }; + string[] asStrings = numbers.Select([|x => |]_methodProvider.ToStr(x)).ToArray(); + Console.WriteLine(asStrings.Length); } - """, - """ - using System; - using System.Linq; + } - public class Repro + public class MethodProvider + { + public string ToStr(int x) { - private readonly MethodProvider _methodProvider; + return x.ToString(); + } + } + """, + """ + using System; + using System.Linq; - public Repro(MethodProvider methodProvider) - { - // Assignment that should not block feature. - _methodProvider = methodProvider; - } + public class Repro + { + private readonly MethodProvider _methodProvider; - public void Main() - { - int[] numbers = { 1, 2, 3, 4, 5 }; - string[] asStrings = numbers.Select(_methodProvider.ToStr).ToArray(); - Console.WriteLine(asStrings.Length); - } + public Repro(MethodProvider methodProvider) + { + // Assignment that should not block feature. + _methodProvider = methodProvider; } - public class MethodProvider + public void Main() { - public string ToStr(int x) - { - return x.ToString(); - } + int[] numbers = { 1, 2, 3, 4, 5 }; + string[] asStrings = numbers.Select(_methodProvider.ToStr).ToArray(); + Console.WriteLine(asStrings.Length); + } + } + + public class MethodProvider + { + public string ToStr(int x) + { + return x.ToString(); } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveTests.cs index 8e9539da0ed53..9843d4e171bee 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveRedundantNullableDirectiveTests.cs @@ -11,486 +11,483 @@ using Roslyn.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.RemoveUnnecessaryNullableDirective +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.RemoveUnnecessaryNullableDirective; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer, + CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryNullableDirective)] +public class CSharpRemoveRedundantNullableDirectiveTests { - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer, - CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider>; + [Theory] + [InlineData(NullableContextOptions.Disable, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Disable, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Disable, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Enable)] + public async Task TestRedundantEnableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) + { + await VerifyCodeFixAsync( + compilationContext, + $$""" + #nullable {{GetEnableDirectiveContext(codeContext)}} + [|#nullable {{GetEnableDirectiveContext(codeContext)}}|] + class Program + { + } + """, + $$""" + #nullable {{GetEnableDirectiveContext(codeContext)}} + class Program + { + } + """); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryNullableDirective)] - public class CSharpRemoveRedundantNullableDirectiveTests + [Theory] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Enable)] + public async Task TestRedundantEnableMatchesCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) { - [Theory] - [InlineData(NullableContextOptions.Disable, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Disable, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Disable, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Enable)] - public async Task TestRedundantEnableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) - { - await VerifyCodeFixAsync( - compilationContext, - $$""" - #nullable {{GetEnableDirectiveContext(codeContext)}} - [|#nullable {{GetEnableDirectiveContext(codeContext)}}|] - class Program - { - } - """, - $$""" - #nullable {{GetEnableDirectiveContext(codeContext)}} - class Program - { - } - """); - } - - [Theory] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Enable)] - public async Task TestRedundantEnableMatchesCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) - { - await VerifyCodeFixAsync( - compilationContext, - $$""" - [|#nullable {{GetEnableDirectiveContext(codeContext)}}|] - [|#nullable {{GetEnableDirectiveContext(codeContext)}}|] - class Program - { - } - """, - """ - class Program - { - } - """); - } - - [Theory] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Enable)] - public async Task TestRedundantDisableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) - { - await VerifyCodeFixAsync( - compilationContext, - $$""" - #nullable {{GetDisableDirectiveContext(codeContext)}} - [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] - class Program - { - } - """, - $$""" - #nullable {{GetDisableDirectiveContext(codeContext)}} - class Program - { - } - """); - } - - [Theory] - [InlineData(NullableContextOptions.Disable, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Disable, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Disable, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Annotations)] - public async Task TestRedundantDisableMatchesCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) - { - await VerifyCodeFixAsync( - compilationContext, - $$""" - [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] - [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] - class Program - { - } - """, - """ - class Program - { - } - """); - } + await VerifyCodeFixAsync( + compilationContext, + $$""" + [|#nullable {{GetEnableDirectiveContext(codeContext)}}|] + [|#nullable {{GetEnableDirectiveContext(codeContext)}}|] + class Program + { + } + """, + """ + class Program + { + } + """); + } - [Theory] - [CombinatorialData] - public async Task TestRedundantRestoreDiffersFromPriorContext(NullableContextOptions compilationContext) - { - var enable = compilationContext != NullableContextOptions.Enable; - await VerifyCodeFixAsync( - compilationContext, - $$""" - #nullable {{(enable ? "enable" : "disable")}} - #nullable restore - [|#nullable restore|] - class Program - { - } - """, - $$""" - #nullable {{(enable ? "enable" : "disable")}} - #nullable restore - class Program - { - } - """); - } + [Theory] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Enable)] + public async Task TestRedundantDisableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) + { + await VerifyCodeFixAsync( + compilationContext, + $$""" + #nullable {{GetDisableDirectiveContext(codeContext)}} + [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] + class Program + { + } + """, + $$""" + #nullable {{GetDisableDirectiveContext(codeContext)}} + class Program + { + } + """); + } - [Theory] - [CombinatorialData] - public async Task TestRedundantRestoreMatchesCompilation(NullableContextOptions compilationContext) - { - await VerifyCodeFixAsync( - compilationContext, - $$""" - [|#nullable restore|] - class Program - { - } - """, - """ - class Program - { - } - """); - } + [Theory] + [InlineData(NullableContextOptions.Disable, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Disable, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Disable, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Annotations)] + public async Task TestRedundantDisableMatchesCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) + { + await VerifyCodeFixAsync( + compilationContext, + $$""" + [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] + [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] + class Program + { + } + """, + """ + class Program + { + } + """); + } - [Fact] - public async Task TestRedundantDirectiveWithFileHeader() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - // File Header + [Theory, CombinatorialData] + public async Task TestRedundantRestoreDiffersFromPriorContext(NullableContextOptions compilationContext) + { + var enable = compilationContext != NullableContextOptions.Enable; + await VerifyCodeFixAsync( + compilationContext, + $$""" + #nullable {{(enable ? "enable" : "disable")}} + #nullable restore + [|#nullable restore|] + class Program + { + } + """, + $$""" + #nullable {{(enable ? "enable" : "disable")}} + #nullable restore + class Program + { + } + """); + } - [|#nullable enable|] + [Theory, CombinatorialData] + public async Task TestRedundantRestoreMatchesCompilation(NullableContextOptions compilationContext) + { + await VerifyCodeFixAsync( + compilationContext, + $$""" + [|#nullable restore|] + class Program + { + } + """, + """ + class Program + { + } + """); + } - class Program - { - } - """, - """ - // File Header + [Fact] + public async Task TestRedundantDirectiveWithFileHeader() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + // File Header - class Program - { - } - """); - } + [|#nullable enable|] - [Fact] - public async Task TestRedundantDirectiveBetweenUsingAndNamespace() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; - - [|#nullable enable|] - - namespace MyNamespace + class Program + { + } + """, + """ + // File Header + + class Program + { + } + """); + } + + [Fact] + public async Task TestRedundantDirectiveBetweenUsingAndNamespace() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; + + [|#nullable enable|] + + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveBetweenUsingAndNamespace2() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; - [|#nullable enable|] + [Fact] + public async Task TestRedundantDirectiveBetweenUsingAndNamespace2() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; + [|#nullable enable|] - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveBetweenUsingAndNamespace3() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; + [Fact] + public async Task TestRedundantDirectiveBetweenUsingAndNamespace3() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; - [|#nullable enable|] - namespace MyNamespace + [|#nullable enable|] + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveWithNamespaceAndDerivedType() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - [|#nullable enable|] + [Fact] + public async Task TestRedundantDirectiveWithNamespaceAndDerivedType() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + [|#nullable enable|] - using System; + using System; - namespace X.Y + namespace X.Y + { + class ProgramException : Exception { - class ProgramException : Exception - { - } } - """, - """ + } + """, + """ - using System; + using System; - namespace X.Y + namespace X.Y + { + class ProgramException : Exception { - class ProgramException : Exception - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveMultiple1() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; + [Fact] + public async Task TestRedundantDirectiveMultiple1() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; - [|#nullable enable|] - [|#nullable enable|] + [|#nullable enable|] + [|#nullable enable|] - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveMultiple2() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; + [Fact] + public async Task TestRedundantDirectiveMultiple2() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; - [|#nullable enable|] + [|#nullable enable|] - [|#nullable enable|] + [|#nullable enable|] - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveMultiple3() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; - [|#nullable enable|] - [|#nullable enable|] - - namespace MyNamespace + [Fact] + public async Task TestRedundantDirectiveMultiple3() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; + [|#nullable enable|] + [|#nullable enable|] + + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveMultiple4() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; - [|#nullable enable|] + [Fact] + public async Task TestRedundantDirectiveMultiple4() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; + [|#nullable enable|] - [|#nullable enable|] + [|#nullable enable|] - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - [Fact] - public async Task TestRedundantDirectiveMultiple5() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - using System; - - [|#nullable enable|] - [|#nullable enable|] - namespace MyNamespace + [Fact] + public async Task TestRedundantDirectiveMultiple5() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + using System; + + [|#nullable enable|] + [|#nullable enable|] + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """, - """ - using System; + } + """, + """ + using System; - namespace MyNamespace + namespace MyNamespace + { + class MyClass { - class MyClass - { - } } - """); - } + } + """); + } - private static string GetDisableDirectiveContext(NullableContextOptions options) + private static string GetDisableDirectiveContext(NullableContextOptions options) + { + return options switch { - return options switch - { - NullableContextOptions.Warnings => "disable warnings", - NullableContextOptions.Annotations => "disable annotations", - NullableContextOptions.Enable => "disable", - _ => throw ExceptionUtilities.UnexpectedValue(options), - }; - } + NullableContextOptions.Warnings => "disable warnings", + NullableContextOptions.Annotations => "disable annotations", + NullableContextOptions.Enable => "disable", + _ => throw ExceptionUtilities.UnexpectedValue(options), + }; + } - private static string GetEnableDirectiveContext(NullableContextOptions options) + private static string GetEnableDirectiveContext(NullableContextOptions options) + { + return options switch { - return options switch - { - NullableContextOptions.Warnings => "enable warnings", - NullableContextOptions.Annotations => "enable annotations", - NullableContextOptions.Enable => "enable", - _ => throw ExceptionUtilities.UnexpectedValue(options), - }; - } + NullableContextOptions.Warnings => "enable warnings", + NullableContextOptions.Annotations => "enable annotations", + NullableContextOptions.Enable => "enable", + _ => throw ExceptionUtilities.UnexpectedValue(options), + }; + } - private static async Task VerifyCodeFixAsync(NullableContextOptions compilationNullableContextOptions, string source, string fixedSource) + private static async Task VerifyCodeFixAsync(NullableContextOptions compilationNullableContextOptions, string source, string fixedSource) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = source, + FixedCode = fixedSource, + SolutionTransforms = { - TestCode = source, - FixedCode = fixedSource, - SolutionTransforms = + (solution, projectId) => { - (solution, projectId) => - { - var compilationOptions = (CSharpCompilationOptions?)solution.GetRequiredProject(projectId).CompilationOptions; - Contract.ThrowIfNull(compilationOptions); + var compilationOptions = (CSharpCompilationOptions?)solution.GetRequiredProject(projectId).CompilationOptions; + Contract.ThrowIfNull(compilationOptions); - return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithNullableContextOptions(compilationNullableContextOptions)); - }, + return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithNullableContextOptions(compilationNullableContextOptions)); }, - }.RunAsync(); - } + }, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs index 36c8e57cbb8b8..3096264bec24d 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryNullableDirective/CSharpRemoveUnnecessaryNullableDirectiveTests.cs @@ -11,239 +11,238 @@ using Roslyn.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.RemoveUnnecessaryNullableDirective -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer, - CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider>; +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.RemoveUnnecessaryNullableDirective; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryNullableDirective)] - public class CSharpRemoveUnnecessaryNullableDirectiveTests - { - [Theory] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Enable)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Annotations)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Warnings)] - [InlineData(NullableContextOptions.Enable, NullableContextOptions.Enable)] - public async Task TestUnnecessaryDisableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) - { - await VerifyCodeFixAsync( - compilationContext, - $$""" - [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] - class Program - { - } - """, - $$""" - class Program - { - } - """); - } +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnnecessaryNullableDirectiveDiagnosticAnalyzer, + CSharpRemoveUnnecessaryNullableDirectiveCodeFixProvider>; - [Fact] - public async Task TestUnnecessaryDisableEnumDeclaration() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - [|#nullable disable|] - enum EnumName - { - First, - Second, - } - """, - """ - enum EnumName - { - First, - Second, - } - """); - } +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryNullableDirective)] +public class CSharpRemoveUnnecessaryNullableDirectiveTests +{ + [Theory] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Annotations, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Warnings, NullableContextOptions.Enable)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Annotations)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Warnings)] + [InlineData(NullableContextOptions.Enable, NullableContextOptions.Enable)] + public async Task TestUnnecessaryDisableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) + { + await VerifyCodeFixAsync( + compilationContext, + $$""" + [|#nullable {{GetDisableDirectiveContext(codeContext)}}|] + class Program + { + } + """, + $$""" + class Program + { + } + """); + } - [Fact] - public async Task TestUnnecessaryDisableEnumDeclarationWithFileHeader() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - // File Header + [Fact] + public async Task TestUnnecessaryDisableEnumDeclaration() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + [|#nullable disable|] + enum EnumName + { + First, + Second, + } + """, + """ + enum EnumName + { + First, + Second, + } + """); + } - [|#nullable disable|] + [Fact] + public async Task TestUnnecessaryDisableEnumDeclarationWithFileHeader() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + // File Header - enum EnumName - { - First, - Second, - } - """, - """ - // File Header + [|#nullable disable|] - enum EnumName - { - First, - Second, - } - """); - } + enum EnumName + { + First, + Second, + } + """, + """ + // File Header + + enum EnumName + { + First, + Second, + } + """); + } - [Fact] - public async Task TestUnnecessaryDirectiveWithNamespaceAndDerivedType() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - [|#nullable disable|] + [Fact] + public async Task TestUnnecessaryDirectiveWithNamespaceAndDerivedType() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + [|#nullable disable|] - using System; + using System; - namespace X.Y + namespace X.Y + { + class ProgramException : Exception { - class ProgramException : Exception - { - } } - """, - """ + } + """, + """ - using System; + using System; - namespace X.Y + namespace X.Y + { + class ProgramException : Exception { - class ProgramException : Exception - { - } } - """); - } - - [Fact] - public async Task TestUnnecessaryDirectiveWithNamespaceAndDerivedFromQualifiedBaseType() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - [|#nullable disable|] + } + """); + } - namespace X.Y - { - class ProgramException : System.Exception - { - } - } - """, - """ + [Fact] + public async Task TestUnnecessaryDirectiveWithNamespaceAndDerivedFromQualifiedBaseType() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + [|#nullable disable|] - namespace X.Y + namespace X.Y + { + class ProgramException : System.Exception { - class ProgramException : System.Exception - { - } } - """); - } + } + """, + """ - [Fact] - public async Task TestUnnecessaryDirectiveWithQualifiedUsingDirectives() - { - await VerifyCodeFixAsync( - NullableContextOptions.Enable, - """ - [|#nullable disable|] - - using System; - using System.Runtime.InteropServices; - using CustomException = System.Exception; - using static System.String; - """, - """ - - using System; - using System.Runtime.InteropServices; - using CustomException = System.Exception; - using static System.String; - """); - } - - [Theory] - [InlineData("disable")] - [InlineData("restore")] - public async Task TestUnnecessaryDisableAtEndOfFile(string keyword) - { - await VerifyCodeFixAsync( - NullableContextOptions.Disable, - $$""" - #nullable enable - struct StructName + namespace X.Y + { + class ProgramException : System.Exception { - string Field; } - [|#nullable {{keyword}}|] + } + """); + } - """, - $$""" - #nullable enable - struct StructName - { - string Field; - } - - """); - } + [Fact] + public async Task TestUnnecessaryDirectiveWithQualifiedUsingDirectives() + { + await VerifyCodeFixAsync( + NullableContextOptions.Enable, + """ + [|#nullable disable|] + + using System; + using System.Runtime.InteropServices; + using CustomException = System.Exception; + using static System.String; + """, + """ + + using System; + using System.Runtime.InteropServices; + using CustomException = System.Exception; + using static System.String; + """); + } - [Fact] - public async Task TestUnnecessaryDisableIgnoredWhenFollowedByConditionalDirective() - { - var code = - """ - #nullable enable - struct StructName - { - string Field; - } - #nullable disable - #if false - #endif - """; + [Theory] + [InlineData("disable")] + [InlineData("restore")] + public async Task TestUnnecessaryDisableAtEndOfFile(string keyword) + { + await VerifyCodeFixAsync( + NullableContextOptions.Disable, + $$""" + #nullable enable + struct StructName + { + string Field; + } + [|#nullable {{keyword}}|] + + """, + $$""" + #nullable enable + struct StructName + { + string Field; + } + + """); + } - await VerifyCodeFixAsync(NullableContextOptions.Disable, code, code); - } + [Fact] + public async Task TestUnnecessaryDisableIgnoredWhenFollowedByConditionalDirective() + { + var code = + """ + #nullable enable + struct StructName + { + string Field; + } + #nullable disable + #if false + #endif + """; + + await VerifyCodeFixAsync(NullableContextOptions.Disable, code, code); + } - private static string GetDisableDirectiveContext(NullableContextOptions options) + private static string GetDisableDirectiveContext(NullableContextOptions options) + { + return options switch { - return options switch - { - NullableContextOptions.Warnings => "disable warnings", - NullableContextOptions.Annotations => "disable annotations", - NullableContextOptions.Enable => "disable", - _ => throw ExceptionUtilities.UnexpectedValue(options), - }; - } - - private static async Task VerifyCodeFixAsync(NullableContextOptions compilationNullableContextOptions, string source, string fixedSource) + NullableContextOptions.Warnings => "disable warnings", + NullableContextOptions.Annotations => "disable annotations", + NullableContextOptions.Enable => "disable", + _ => throw ExceptionUtilities.UnexpectedValue(options), + }; + } + + private static async Task VerifyCodeFixAsync(NullableContextOptions compilationNullableContextOptions, string source, string fixedSource) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = source, + FixedCode = fixedSource, + SolutionTransforms = { - TestCode = source, - FixedCode = fixedSource, - SolutionTransforms = + (solution, projectId) => { - (solution, projectId) => - { - var compilationOptions = (CSharpCompilationOptions?)solution.GetRequiredProject(projectId).CompilationOptions; - Contract.ThrowIfNull(compilationOptions); + var compilationOptions = (CSharpCompilationOptions?)solution.GetRequiredProject(projectId).CompilationOptions; + Contract.ThrowIfNull(compilationOptions); - return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithNullableContextOptions(compilationNullableContextOptions)); - }, + return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithNullableContextOptions(compilationNullableContextOptions)); }, - }.RunAsync(); - } + }, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryExpressionParenthesesTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryExpressionParenthesesTests.cs index 7b8b95b3403fa..a8d90e34f4f95 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryExpressionParenthesesTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryExpressionParenthesesTests.cs @@ -17,3446 +17,3445 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryParentheses +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryParentheses; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryParentheses)] +public partial class RemoveUnnecessaryExpressionParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryParentheses)] - public partial class RemoveUnnecessaryExpressionParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveUnnecessaryExpressionParenthesesTests(ITestOutputHelper logger) + : base(logger) { - public RemoveUnnecessaryExpressionParenthesesTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpRemoveUnnecessaryExpressionParenthesesDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryParenthesesCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpRemoveUnnecessaryExpressionParenthesesDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryParenthesesCodeFixProvider()); - private async Task TestAsync(string initial, string expected, bool offeredWhenRequireForClarityIsEnabled, int index = 0) - { - await TestInRegularAndScriptAsync(initial, expected, options: RemoveAllUnnecessaryParentheses, index: index); + private async Task TestAsync(string initial, string expected, bool offeredWhenRequireForClarityIsEnabled, int index = 0) + { + await TestInRegularAndScriptAsync(initial, expected, options: RemoveAllUnnecessaryParentheses, index: index); - if (offeredWhenRequireForClarityIsEnabled) - { - await TestInRegularAndScriptAsync(initial, expected, options: RequireAllParenthesesForClarity, index: index); - } - else - { - await TestMissingAsync(initial, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); - } + if (offeredWhenRequireForClarityIsEnabled) + { + await TestInRegularAndScriptAsync(initial, expected, options: RequireAllParenthesesForClarity, index: index); + } + else + { + await TestMissingAsync(initial, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); } + } - internal override bool ShouldSkipMessageDescriptionVerification(DiagnosticDescriptor descriptor) - => descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary) && descriptor.DefaultSeverity == DiagnosticSeverity.Hidden; + internal override bool ShouldSkipMessageDescriptionVerification(DiagnosticDescriptor descriptor) + => descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary) && descriptor.DefaultSeverity == DiagnosticSeverity.Hidden; - private static DiagnosticDescription GetRemoveUnnecessaryParenthesesDiagnostic(string text, int line, int column) - => TestHelpers.Diagnostic(IDEDiagnosticIds.RemoveUnnecessaryParenthesesDiagnosticId, text, startLocation: new LinePosition(line, column)); + private static DiagnosticDescription GetRemoveUnnecessaryParenthesesDiagnostic(string text, int line, int column) + => TestHelpers.Diagnostic(IDEDiagnosticIds.RemoveUnnecessaryParenthesesDiagnosticId, text, startLocation: new LinePosition(line, column)); - [Fact] - public async Task TestVariableInitializer_TestWithAllOptionsSetToIgnore() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestVariableInitializer_TestWithAllOptionsSetToIgnore() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1); - } + int x = $$(1); } - """, new TestParameters(options: IgnoreAllParentheses)); - } + } + """, new TestParameters(options: IgnoreAllParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29736")] - public async Task TestVariableInitializer_TestMissingParenthesis() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29736")] + public async Task TestVariableInitializer_TestMissingParenthesis() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1; - } + int x = $$(1; } - """); - } + } + """); + } - [Fact] - public async Task TestArithmeticRequiredForClarity1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestArithmeticRequiredForClarity1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + $$(2 * 3); - } + int x = 1 + $$(2 * 3); } - """, new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); - } + } + """, new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44629")] - public async Task TestStackAlloc() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44629")] + public async Task TestStackAlloc() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var span = $$(stackalloc byte[8]); - } + var span = $$(stackalloc byte[8]); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47365")] - public async Task TestDynamic() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47365")] + public async Task TestDynamic() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - dynamic i = 1; - dynamic s = "s"; - Console.WriteLine(s + $$(1 + i)); - } + dynamic i = 1; + dynamic s = "s"; + Console.WriteLine(s + $$(1 + i)); } - """); - } + } + """); + } - [Fact] - public async Task TestArithmeticRequiredForClarity2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestArithmeticRequiredForClarity2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - int x = a || $$(b && c); - } + int x = a || $$(b && c); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a || b && c; - } + int x = a || b && c; } - """, parameters: new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); - } + } + """, parameters: new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); + } - [Fact] - public async Task TestLogicalRequiredForClarity1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestLogicalRequiredForClarity1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = a || $$(b && c); - } + int x = a || $$(b && c); } - """, new TestParameters(options: RequireOtherBinaryParenthesesForClarity)); - } + } + """, new TestParameters(options: RequireOtherBinaryParenthesesForClarity)); + } - [Fact] - public async Task TestLogicalRequiredForClarity2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestLogicalRequiredForClarity2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - int x = a + $$(b * c); - } + int x = a + $$(b * c); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a + b * c; - } + int x = a + b * c; } - """, parameters: new TestParameters(options: RequireOtherBinaryParenthesesForClarity)); - } + } + """, parameters: new TestParameters(options: RequireOtherBinaryParenthesesForClarity)); + } - [Fact] - public async Task TestArithmeticNotRequiredForClarityWhenPrecedenceStaysTheSame_Integral1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArithmeticNotRequiredForClarityWhenPrecedenceStaysTheSame_Integral1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 + $$(2 + 3); - } + int x = 1 + $$(2 + 3); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 + 3; - } + int x = 1 + 2 + 3; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArithmeticNotRequiredForClarityWhenPrecedenceStaysTheSame_Integral2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArithmeticNotRequiredForClarityWhenPrecedenceStaysTheSame_Integral2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1 + 2) + 3; - } + int x = $$(1 + 2) + 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1 + 2 + 3; - } + int x = 1 + 2 + 3; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArithmeticRequiredForCorrectnessWhenPrecedenceStaysTheSameIfFloatingPoint() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestArithmeticRequiredForCorrectnessWhenPrecedenceStaysTheSameIfFloatingPoint() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1.0 + $$(2.0 + 3.0); - } + int x = 1.0 + $$(2.0 + 3.0); } - """); - } + } + """); + } - [Fact] - public async Task TestArithmeticNotRequiredForClarityWhenPrecedenceStaysTheSame_Floating2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArithmeticNotRequiredForClarityWhenPrecedenceStaysTheSame_Floating2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1.0 + 2.0) + 3.0; - } + int x = $$(1.0 + 2.0) + 3.0; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1.0 + 2.0 + 3.0; - } + int x = 1.0 + 2.0 + 3.0; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = a || $$(b || c); - } + int x = a || $$(b || c); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a || b || c; - } + int x = a || b || c; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(a || b) || c; - } + int x = $$(a || b) || c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a || b || c; - } + int x = a || b || c; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestVariableInitializer_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestVariableInitializer_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1); - } + int x = $$(1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1; - } + int x = 1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestReturnStatement_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestReturnStatement_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - return $$(1 + 2); - } + return $$(1 + 2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - return 1 + 2; - } + return 1 + 2; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestExpressionBody_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestExpressionBody_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + int M() => $$(1 + 2); + } + """, + """ + class C + { + int M() => 1 + 2; + } + """, offeredWhenRequireForClarityIsEnabled: true); + } + + [Fact] + public async Task TestCheckedExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - int M() => $$(1 + 2); + int i = checked($$(1 + 2)); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - int M() => 1 + 2; + int i = checked(1 + 2); } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCheckedExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAssignment_TestAvailableWithAlwaysRemove_And_TestNotAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int i = checked($$(1 + 2)); - } + i = $$(1 + 2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int i = checked(1 + 2); - } + i = 1 + 2; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAssignment_TestAvailableWithAlwaysRemove_And_TestNotAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestCompoundAssignment_TestAvailableWithAlwaysRemove_And_TestNotAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - i = $$(1 + 2); - } + i *= $$(1 + 2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - i = 1 + 2; - } + i *= 1 + 2; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCompoundAssignment_TestAvailableWithAlwaysRemove_And_TestNotAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPimaryAssignment_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - i *= $$(1 + 2); - } + i = $$(s.Length); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - i *= 1 + 2; - } + i = s.Length; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPimaryAssignment_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNestedParenthesizedExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - i = $$(s.Length); - } + int i = ( $$(1 + 2) ); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - i = s.Length; - } + int i = ( 1 + 2 ); } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true, index: 1); + } - [Fact] - public async Task TestNestedParenthesizedExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestIncrementExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int i = ( $$(1 + 2) ); - } + int i = $$(x++); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int i = ( 1 + 2 ); - } + int i = x++; } - """, offeredWhenRequireForClarityIsEnabled: true, index: 1); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestIncrementExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLambdaBody_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int i = $$(x++); - } - } - """, - """ - class C - { - void M() - { - int i = x++; - } - } - """, offeredWhenRequireForClarityIsEnabled: true); - } - - [Fact] - public async Task TestLambdaBody_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C - { - void M() - { - Func i = () => $$(1); - } + Func i = () => $$(1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - Func i = () => 1; - } + Func i = () => 1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArrayElement_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArrayElement_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int[] i = new int[] { $$(1) }; - } + int[] i = new int[] { $$(1) }; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int[] i = new int[] { 1 }; - } + int[] i = new int[] { 1 }; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestWhereClause_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestWhereClause_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = from c in customer - where $$(c.Age > 21) - select c; - } + var q = from c in customer + where $$(c.Age > 21) + select c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = from c in customer - where c.Age > 21 - select c; - } + var q = from c in customer + where c.Age > 21 + select c; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCastExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestCastExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int i = (int)$$(1); - } + int i = (int)$$(1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int i = (int)1; - } + int i = (int)1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestMissingForConditionalAccess1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMissingForConditionalAccess1() + { + await TestMissingAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - var v = $$(s?.Length).ToString(); - } + var v = $$(s?.Length).ToString(); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37046")] - public async Task TestMissingForConditionalAccess2() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37046")] + public async Task TestMissingForConditionalAccess2() + { + await TestMissingAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - var v = $$(s?.Length)?.ToString(); - } + var v = $$(s?.Length)?.ToString(); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestForConditionalAccessNotInExpression() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestForConditionalAccessNotInExpression() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - var v = $$(s?.Length); - } + var v = $$(s?.Length); } - """, + } + """, - """ - class C + """ + class C + { + void M(string s) { - void M(string s) - { - var v = s?.Length; - } + var v = s?.Length; } - """, options: RemoveAllUnnecessaryParentheses); - } + } + """, options: RemoveAllUnnecessaryParentheses); + } - [Fact] - public async Task TestMissingForConditionalIndex() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMissingForConditionalIndex() + { + await TestMissingAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - var v = $$(s?[0]).ToString(); - } + var v = $$(s?[0]).ToString(); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestBinaryInCastExpression() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestBinaryInCastExpression() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int i = (int)$$(1 + 2); - } + int i = (int)$$(1 + 2); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestAroundCastExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAroundCastExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int i = $$((int)1); - } + int i = $$((int)1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int i = (int)1; - } + int i = (int)1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestConditionalInInterpolation() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestConditionalInInterpolation() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var s = $"{ $$(a ? b : c) }"; - } + var s = $"{ $$(a ? b : c) }"; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestConditionalInInterpolation_FixAll_1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestConditionalInInterpolation_FixAll_1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var s1 = $"{ {|FixAllInDocument:(|}(a ? b : c)) }"; - var s2 = $"{ ((a ? b : c)) }"; - } + var s1 = $"{ {|FixAllInDocument:(|}(a ? b : c)) }"; + var s2 = $"{ ((a ? b : c)) }"; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var s1 = $"{ (a ? b : c) }"; - var s2 = $"{ (a ? b : c) }"; - } + var s1 = $"{ (a ? b : c) }"; + var s2 = $"{ (a ? b : c) }"; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestConditionalInInterpolation_FixAll_2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestConditionalInInterpolation_FixAll_2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var s1 = $"{ ({|FixAllInDocument:(|}a ? b : c)) }"; - var s2 = $"{ ((a ? b : c)) }"; - } + var s1 = $"{ ({|FixAllInDocument:(|}a ? b : c)) }"; + var s2 = $"{ ((a ? b : c)) }"; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var s1 = $"{ (a ? b : c) }"; - var s2 = $"{ (a ? b : c) }"; - } + var s1 = $"{ (a ? b : c) }"; + var s2 = $"{ (a ? b : c) }"; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestNonConditionalInInterpolation_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNonConditionalInInterpolation_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var s = $"{ $$(true) }"; - } + var s = $"{ $$(true) }"; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var s = $"{ true }"; - } + var s = $"{ true }"; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestBinaryExpression_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestBinaryExpression_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = $$(a * b) + c; - } + var q = $$(a * b) + c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = a * b + c; - } + var q = a * b + c; } - """, offeredWhenRequireForClarityIsEnabled: false); - } + } + """, offeredWhenRequireForClarityIsEnabled: false); + } - [Fact] - public async Task TestBinaryExpression_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestBinaryExpression_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = c + $$(a * b); - } + var q = c + $$(a * b); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = c + a * b; - } + var q = c + a * b; } - """, offeredWhenRequireForClarityIsEnabled: false); - } + } + """, offeredWhenRequireForClarityIsEnabled: false); + } - [Fact] - public async Task TestConditionalExpression_TestNotAvailableForComplexChildren1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_TestNotAvailableForComplexChildren1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var q = $$(a * b) ? (1 + 2) : (3 + 4); - } + var q = $$(a * b) ? (1 + 2) : (3 + 4); } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestConditionalExpression_TestNotAvailableForComplexChildren2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_TestNotAvailableForComplexChildren2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var q = (a * b) ? $$(1 + 2) : (3 + 4); - } + var q = (a * b) ? $$(1 + 2) : (3 + 4); } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestConditionalExpression_TestNotAvailableForComplexChildren3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_TestNotAvailableForComplexChildren3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var q = (a * b) ? (1 + 2) : $$(3 + 4); - } + var q = (a * b) ? (1 + 2) : $$(3 + 4); } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestConditionalExpression_TestAvailableForPrimaryChildren1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_TestAvailableForPrimaryChildren1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = $$(a.X()) ? (1 + 2) : (3 + 4); - } + var q = $$(a.X()) ? (1 + 2) : (3 + 4); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = a.X() ? (1 + 2) : (3 + 4); - } + var q = a.X() ? (1 + 2) : (3 + 4); } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestConditionalExpression_TestAvailableForPrimaryChildren2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_TestAvailableForPrimaryChildren2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = (a.X()) ? $$(x.Length) : (3 + 4); - } + var q = (a.X()) ? $$(x.Length) : (3 + 4); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = (a.X()) ? x.Length : (3 + 4); - } + var q = (a.X()) ? x.Length : (3 + 4); } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestConditionalExpression_TestAvailableForPrimaryChildren3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_TestAvailableForPrimaryChildren3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = (a.X()) ? (1 + 2) : $$(a[0]); - } + var q = (a.X()) ? (1 + 2) : $$(a[0]); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = (a.X()) ? (1 + 2) : a[0]; - } + var q = (a.X()) ? (1 + 2) : a[0]; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestIsPattern_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestIsPattern_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - if ( $$(a[0]) is string s) { } - } + if ( $$(a[0]) is string s) { } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - if ( a[0] is string s) { } - } + if ( a[0] is string s) { } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestIsPattern_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestIsPattern_TestAvailableWithAlwaysRemove_And_NotAvailableWhenRequiredForClarity_2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - if ( $$(a * b) is int i) { } - } + if ( $$(a * b) is int i) { } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - if ( a * b is int i) { } - } + if ( a * b is int i) { } } - """, offeredWhenRequireForClarityIsEnabled: false); - } + } + """, offeredWhenRequireForClarityIsEnabled: false); + } - [Fact] - public async Task TestForOverloadedOperatorOnLeft() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestForOverloadedOperatorOnLeft() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(C c1, C c2, C c3) { - void M(C c1, C c2, C c3) - { - var x = $$(c1 + c2) + c3; - } - - public static C operator +(C c1, C c2) => null; + var x = $$(c1 + c2) + c3; } - """, - """ - class C - { - void M(C c1, C c2, C c3) - { - var x = c1 + c2 + c3; - } - public static C operator +(C c1, C c2) => null; + public static C operator +(C c1, C c2) => null; + } + """, + """ + class C + { + void M(C c1, C c2, C c3) + { + var x = c1 + c2 + c3; } - """, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); - } - [Fact] - public async Task TestMissingForOverloadedOperatorOnRight() - { - await TestMissingAsync( - """ - class C - { - void M(C c1, C c2, C c3) - { - var x = c1 + $$(c2 + c3); - } + public static C operator +(C c1, C c2) => null; + } + """, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); + } - public static C operator +(C c1, C c2) => null; + [Fact] + public async Task TestMissingForOverloadedOperatorOnRight() + { + await TestMissingAsync( + """ + class C + { + void M(C c1, C c2, C c3) + { + var x = c1 + $$(c2 + c3); } - """, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); - } - [Fact] - public async Task TestShiftRequiredForClarity1() - { - await TestMissingAsync( - """ - class C + public static C operator +(C c1, C c2) => null; + } + """, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); + } + + [Fact] + public async Task TestShiftRequiredForClarity1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1 + 2) << 3; - } + int x = $$(1 + 2) << 3; } - """, parameters: new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); - } + } + """, parameters: new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); + } - [Fact] - public async Task TestShiftRequiredForClarity2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestShiftRequiredForClarity2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1 + 2) << 3; - } + int x = $$(1 + 2) << 3; } - """, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); - } + } + """, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); + } - [Fact] - public async Task TestDoNotRemoveShiftAcrossPrecedence() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestDoNotRemoveShiftAcrossPrecedence() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1 + 2) << 3; - } + int x = $$(1 + 2) << 3; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestRemoveShiftIfNotNecessary2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestRemoveShiftIfNotNecessary2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - int x = $$(1 << 2) << 3; - } + int x = $$(1 << 2) << 3; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 1 << 2 << 3; - } + int x = 1 << 2 << 3; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestDoNotRemoveShiftAcrossSamePrecedenceIfValueWouldChange() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestDoNotRemoveShiftAcrossSamePrecedenceIfValueWouldChange() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = 1 << $$(2 << 3); - } + int x = 1 << $$(2 << 3); } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestDoNotRemoveShiftIfShiftKindDiffers() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestDoNotRemoveShiftIfShiftKindDiffers() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(1 >> 2) << 3; - } + int x = $$(1 >> 2) << 3; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestRemoveCoalesceIfNotNecessary1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestRemoveCoalesceIfNotNecessary1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = $$(a ?? b) ?? c; - } + int x = $$(a ?? b) ?? c; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestRemoveCoalesceIfNotNecessary2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestRemoveCoalesceIfNotNecessary2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - int x = a ?? $$(b ?? c); - } + int x = a ?? $$(b ?? c); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = a ?? b ?? c; - } + int x = a ?? b ?? c; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestBitwiseExpression_TestMissingWithDifferencePrecedence1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestBitwiseExpression_TestMissingWithDifferencePrecedence1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var q = $$(a + b) & c; - } + var q = $$(a + b) & c; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestBitwiseExpression_TestMissingWithDifferencePrecedence2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestBitwiseExpression_TestMissingWithDifferencePrecedence2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var q = $$(a | b) & c; - } + var q = $$(a | b) & c; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestBitwiseExpression_TestAvailableWithSamePrecedenceMissingWithDifferencePrecedence2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestBitwiseExpression_TestAvailableWithSamePrecedenceMissingWithDifferencePrecedence2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - var q = $$(a & b) & c; - } + var q = $$(a & b) & c; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var q = a & b & c; - } + var q = a & b & c; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] - public async Task TestSwitchCase_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] + public async Task TestSwitchCase_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case $$(default(bool)): - } + case $$(default(bool)): } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case default(bool): - } + case default(bool): } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] - public async Task TestSwitchCase_WithWhenClause_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] + public async Task TestSwitchCase_WithWhenClause_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case $$(default(bool)) when true: - } + case $$(default(bool)) when true: } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case default(bool) when true: - } + case default(bool) when true: } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] - public async Task TestWhenClause_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] + public async Task TestWhenClause_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case true when $$(default(bool)): - } + case true when $$(default(bool)): } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case true when default(bool): - } + case true when default(bool): } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] - public async Task TestConstantPatternExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] + public async Task TestConstantPatternExpression_TestAvailableWithAlwaysRemove_And_TestAvailableWhenRequiredForClarity() + { + await TestAsync( + """ + class C + { + void M() { - void M() + if (true is $$(default(bool))) { - if (true is $$(default(bool))) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (true is default(bool)) { - if (true is default(bool)) - { - } } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] - public async Task TestConstantPatternExpression_RequiredForPrecedence() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25554")] + public async Task TestConstantPatternExpression_RequiredForPrecedence() + { + await TestMissingAsync( + """ + class C + { + void M(string s) { - void M(string s) + if (true is $$(true == true)) { - if (true is $$(true == true)) - { - } } } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestCastAmbiguity1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCastAmbiguity1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(-1); - } + int x = (X)$$(-1); } - """); - } + } + """); + } - [Fact] - public async Task TestCastAmbiguity2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCastAmbiguity2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(+1); - } + int x = (X)$$(+1); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestCastAmbiguity3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCastAmbiguity3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(&1); - } + int x = (X)$$(&1); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestCastAmbiguity4() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestCastAmbiguity4() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(*1); - } + int x = (X)$$(*1); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestPrimitiveCastNoAmbiguity1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPrimitiveCastNoAmbiguity1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$(-1); - } + int x = (int)$$(-1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (int)-1; - } + int x = (int)-1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPrimitiveCastNoAmbiguity2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPrimitiveCastNoAmbiguity2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$(+1); - } + int x = (int)$$(+1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (int)+1; - } + int x = (int)+1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPrimitiveCastNoAmbiguity3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPrimitiveCastNoAmbiguity3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$(&x); - } + int x = (int)$$(&x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (int)&x; - } + int x = (int)&x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPrimitiveCastNoAmbiguity4() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPrimitiveCastNoAmbiguity4() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (int)$$(*x); - } + int x = (int)$$(*x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (int)*x; - } + int x = (int)*x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArrayCastNoAmbiguity1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArrayCastNoAmbiguity1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T[])$$(-1); - } + int x = (T[])$$(-1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T[])-1; - } + int x = (T[])-1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArrayCastNoAmbiguity2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArrayCastNoAmbiguity2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T[])$$(+1); - } + int x = (T[])$$(+1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T[])+1; - } + int x = (T[])+1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArrayCastNoAmbiguity3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArrayCastNoAmbiguity3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T[])$$(&x); - } + int x = (T[])$$(&x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T[])&x; - } + int x = (T[])&x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestArrayCastNoAmbiguity4() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestArrayCastNoAmbiguity4() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T[])$$(*x); - } + int x = (T[])$$(*x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T[])*x; - } + int x = (T[])*x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPointerCastNoAmbiguity1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPointerCastNoAmbiguity1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T*)$$(-1); - } + int x = (T*)$$(-1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T*)-1; - } + int x = (T*)-1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPointerCastNoAmbiguity2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPointerCastNoAmbiguity2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T*)$$(+1); - } + int x = (T*)$$(+1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T*)+1; - } + int x = (T*)+1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPointerCastNoAmbiguity3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPointerCastNoAmbiguity3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T*)$$(&x); - } + int x = (T*)$$(&x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T*)&x; - } + int x = (T*)&x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestPointerCastNoAmbiguity4() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestPointerCastNoAmbiguity4() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T*)$$(*x); - } + int x = (T*)$$(*x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T*)*x; - } + int x = (T*)*x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestNullableCastNoAmbiguity1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNullableCastNoAmbiguity1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T?)$$(-1); - } + int x = (T?)$$(-1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T?)-1; - } + int x = (T?)-1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestNullableCastNoAmbiguity2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNullableCastNoAmbiguity2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T?)$$(+1); - } + int x = (T?)$$(+1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T?)+1; - } + int x = (T?)+1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestNullableCastNoAmbiguity3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNullableCastNoAmbiguity3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T?)$$(&x); - } + int x = (T?)$$(&x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T?)&x; - } + int x = (T?)&x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestNullableCastNoAmbiguity4() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNullableCastNoAmbiguity4() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (T?)$$(*x); - } + int x = (T?)$$(*x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (T?)*x; - } + int x = (T?)*x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAliasCastNoAmbiguity1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAliasCastNoAmbiguity1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)$$(-1); - } + int x = (e::N.T)$$(-1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)-1; - } + int x = (e::N.T)-1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAliasCastNoAmbiguity2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAliasCastNoAmbiguity2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)$$(+1); - } + int x = (e::N.T)$$(+1); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)+1; - } + int x = (e::N.T)+1; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAliasCastNoAmbiguity3() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAliasCastNoAmbiguity3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)$$(&x); - } + int x = (e::N.T)$$(&x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)&x; - } + int x = (e::N.T)&x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAliasCastNoAmbiguity4() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAliasCastNoAmbiguity4() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)$$(*x); - } + int x = (e::N.T)$$(*x); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (e::N.T)*x; - } + int x = (e::N.T)*x; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCastOfPrimary() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestCastOfPrimary() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(a); - } + int x = (X)$$(a); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (X)a; - } + int x = (X)a; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCastOfMemberAccess() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestCastOfMemberAccess() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(a.b); - } + int x = (X)$$(a.b); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (X)a.b; - } + int x = (X)a.b; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCastOfNonAmbiguousUnary() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestCastOfNonAmbiguousUnary() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$(!a); - } + int x = (X)$$(!a); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (X)!a; - } + int x = (X)!a; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestCastOfCast() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestCastOfCast() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = (X)$$((Y)a); - } + int x = (X)$$((Y)a); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = (X)(Y)a; - } + int x = (X)(Y)a; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestIsPatternAndLogical_TestWithAllOptionsSetToIgnore() - { - await TestAsync( - """ - class C - { - void M(object expression) - { - if ($$(expression is bool b) && b) { } - } + [Fact] + public async Task TestIsPatternAndLogical_TestWithAllOptionsSetToIgnore() + { + await TestAsync( + """ + class C + { + void M(object expression) + { + if ($$(expression is bool b) && b) { } } - """, - """ - class C + } + """, + """ + class C + { + void M(object expression) { - void M(object expression) - { - if (expression is bool b && b) { } - } + if (expression is bool b && b) { } } - """, + } + """, offeredWhenRequireForClarityIsEnabled: false); - } + } - [Fact] - public async Task TestGuardPatternMissing() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestGuardPatternMissing() + { + await TestMissingAsync( + """ + class C + { + void M(object expression) { - void M(object expression) - { - if (!$$(expression is bool b)) { } - } + if (!$$(expression is bool b)) { } } - """); - } + } + """); + } - [Fact] - public async Task TestParensAroundLValueMemberAccess() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundLValueMemberAccess() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - $$(this.Property) = Property; - } + $$(this.Property) = Property; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - this.Property = Property; - } + this.Property = Property; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundMultiplicationInAddEquals() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundMultiplicationInAddEquals() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - x += $$(y * z) - } + x += $$(y * z) } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - x += y * z - } + x += y * z } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundAddInMultipleEquals() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundAddInMultipleEquals() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - x *= $$(y + z) - } + x *= $$(y + z) } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - x *= y + z - } + x *= y + z } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestNecessaryCast() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNecessaryCast() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - $$((short)3).ToString(); - } + $$((short)3).ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestParensAroundChecked() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundChecked() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 3 * $$(checked(5)); - } + int x = 3 * $$(checked(5)); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 3 * checked(5); - } + int x = 3 * checked(5); } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundUnchecked() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundUnchecked() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int x = 3 * $$(unchecked(5)); - } + int x = 3 * $$(unchecked(5)); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int x = 3 * unchecked(5); - } + int x = 3 * unchecked(5); } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundNameof() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundNameof() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - string property = "My " + $$(nameof(property)); - } + string property = "My " + $$(nameof(property)); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - string property = "My " + nameof(property); - } + string property = "My " + nameof(property); } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensIsCheck() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensIsCheck() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - bool x = $$("" is string); - } + bool x = $$("" is string); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - bool x = "" is string; - } + bool x = "" is string; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestNecessaryParensAroundIs() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestNecessaryParensAroundIs() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - string x = $$("" is string).ToString(); - } + string x = $$("" is string).ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestParensAroundAssignmentInInitialization() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundAssignmentInInitialization() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - string y; - string x = $$(y = "text"); - } + string y; + string x = $$(y = "text"); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - string y; - string x = y = "text"; - } + string y; + string x = y = "text"; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundLambda1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundLambda1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - Func y2 = $$(v => v); - } + Func y2 = $$(v => v); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - Func y2 = v => v; - } + Func y2 = v => v; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundLambda2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundLambda2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - Func y2 = $$((v) => v); - } + Func y2 = $$((v) => v); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - Func y2 = (v) => v; - } + Func y2 = (v) => v; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundCastedLambda1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestParensAroundCastedLambda1() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - string y = ((Func)$$((v) => v))("text"); - } + string y = ((Func)$$((v) => v))("text"); } - """); - } + } + """); + } - [Fact] - public async Task TestParensAroundCastedLambda2() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestParensAroundCastedLambda2() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - string y = ($$(Func)((v) => v))("text"); - } + string y = ($$(Func)((v) => v))("text"); } - """); - } + } + """); + } - [Fact] - public async Task TestParensAroundCastedLambda3() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestParensAroundCastedLambda3() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - string y = $$((Func)((v) => v))("text"); - } + string y = $$((Func)((v) => v))("text"); } - """); - } + } + """); + } - [Fact] - public async Task TestParensAroundReturnValue1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundReturnValue1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - return$$(value); - } + return$$(value); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - return value; - } + return value; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundReturnValue2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundReturnValue2() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - return $$(value); - } + return $$(value); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - return value; - } + return value; } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundPPDirective1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundPPDirective1() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - #if$$(A || B) - #endif - } + #if$$(A || B) + #endif } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - #if A || B - #endif - } + #if A || B + #endif } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact] - public async Task TestParensAroundPPDirective2() - { - // Currently producing broken code. - await TestAsync( - """ - class C + [Fact] + public async Task TestParensAroundPPDirective2() + { + // Currently producing broken code. + await TestAsync( + """ + class C + { + void M() { - void M() - { - #if( $$(A || B) || C) - #endif - } + #if( $$(A || B) || C) + #endif } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - #if( A || B || C) - #endif - } + #if( A || B || C) + #endif } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true, index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57768")] - public async Task TestParensAroundPPDirective3() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57768")] + public async Task TestParensAroundPPDirective3() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - #if C - #elif$$(A || B) - #endif - } + #if C + #elif$$(A || B) + #endif } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - #if C - #elif A || B - #endif - } + #if C + #elif A || B + #endif } - """, + } + """, offeredWhenRequireForClarityIsEnabled: true); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestMissingForPreIncrement() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestMissingForPreIncrement() + { + await TestMissingAsync( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = (byte)$$(++x); - } + var v = (byte)$$(++x); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestMissingForPreDecrement() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestMissingForPreDecrement() + { + await TestMissingAsync( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = (byte)$$(--x); - } + var v = (byte)$$(--x); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestForPostIncrement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestForPostIncrement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = (byte)$$(x++); - } + var v = (byte)$$(x++); } - """, + } + """, - """ - class C + """ + class C + { + void M(int x) { - void M(int x) - { - var v = (byte)x++; - } + var v = (byte)x++; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestForPostDecrement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestForPostDecrement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = (byte)$$(x--); - } + var v = (byte)$$(x--); } - """, + } + """, - """ - class C + """ + class C + { + void M(int x) { - void M(int x) - { - var v = (byte)x--; - } + var v = (byte)x--; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestForPreIncrementInLocalDeclaration() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestForPreIncrementInLocalDeclaration() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = $$(++x); - } + var v = $$(++x); } - """, - """ - class C + } + """, + """ + class C + { + void M(int x) { - void M(int x) - { - var v = ++x; - } + var v = ++x; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestForPreIncrementInSimpleAssignment() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestForPreIncrementInSimpleAssignment() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int x, int v) { - void M(int x, int v) - { - v = $$(++x); - } + v = $$(++x); } - """, - """ - class C + } + """, + """ + class C + { + void M(int x, int v) { - void M(int x, int v) - { - v = ++x; - } + v = ++x; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestForPreIncrementInArgument() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestForPreIncrementInArgument() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int x) { - void M(int x) - { - M($$(++x)); - } + M($$(++x)); } - """, - """ - class C + } + """, + """ + class C + { + void M(int x) { - void M(int x) - { - M(++x); - } + M(++x); } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestMissingForPreIncrementAfterAdd() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestMissingForPreIncrementAfterAdd() + { + await TestMissingAsync( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = x+$$(++x); - } + var v = x+$$(++x); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] - public async Task TestMissingForUnaryPlusAfterAdd() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29454")] + public async Task TestMissingForUnaryPlusAfterAdd() + { + await TestMissingAsync( + """ + class C + { + void M(int x) { - void M(int x) - { - var v = x+$$(+x); - } + var v = x+$$(+x); } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31103")] - public async Task TestMissingForConditionalRefAsLeftHandSideValue() - { - await TestMissingAsync( - """ - class Bar + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31103")] + public async Task TestMissingForConditionalRefAsLeftHandSideValue() + { + await TestMissingAsync( + """ + class Bar + { + void Foo(bool cond, double a, double b) { - void Foo(bool cond, double a, double b) - { - [||](cond ? ref a : ref b) = 6.67e-11; - } + [||](cond ? ref a : ref b) = 6.67e-11; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31103")] - public async Task TestConditionalExpressionAsRightHandSideValue() - { - await TestInRegularAndScript1Async( - """ - class Bar + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31103")] + public async Task TestConditionalExpressionAsRightHandSideValue() + { + await TestInRegularAndScript1Async( + """ + class Bar + { + void Foo(bool cond, double a, double b) { - void Foo(bool cond, double a, double b) - { - double c = $$(cond ? a : b); - } + double c = $$(cond ? a : b); } - """, - """ - class Bar + } + """, + """ + class Bar + { + void Foo(bool cond, double a, double b) { - void Foo(bool cond, double a, double b) - { - double c = cond ? a : b; - } + double c = cond ? a : b; } - """, + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32085")] - public async Task TestMissingForNestedConditionalExpressionInLambda() - { - await TestMissingAsync( - """ - class Bar + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32085")] + public async Task TestMissingForNestedConditionalExpressionInLambda() + { + await TestMissingAsync( + """ + class Bar + { + void Test(bool a) { - void Test(bool a) - { - Func lambda = - number => number + $"{ ($$a ? "foo" : "bar") }"; - } + Func lambda = + number => number + $"{ ($$a ? "foo" : "bar") }"; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] - public async Task TestUnnecessaryParenthesisDiagnosticSingleLineExpression() - { - var parentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 + 2)", 4, 16); - await TestDiagnosticsAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] + public async Task TestUnnecessaryParenthesisDiagnosticSingleLineExpression() + { + var parentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 + 2)", 4, 16); + await TestDiagnosticsAsync( + """ + class C + { + void M() { - void M() - { - int x = [|(1 + 2)|]; - } + int x = [|(1 + 2)|]; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses), parentheticalExpressionDiagnostic); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses), parentheticalExpressionDiagnostic); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] - public async Task TestUnnecessaryParenthesisDiagnosticInMultiLineExpression() - { - var firstLineParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 +", 4, 16); - await TestDiagnosticsAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] + public async Task TestUnnecessaryParenthesisDiagnosticInMultiLineExpression() + { + var firstLineParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 +", 4, 16); + await TestDiagnosticsAsync( + """ + class C + { + void M() { - void M() - { - int x = [|(1 + - 2)|]; - } + int x = [|(1 + + 2)|]; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses), firstLineParentheticalExpressionDiagnostic); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses), firstLineParentheticalExpressionDiagnostic); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] - public async Task TestUnnecessaryParenthesisDiagnosticInNestedExpression() - { - var outerParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 + (2 + 3) + 4)", 4, 16); - var innerParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(2 + 3)", 4, 21); - var expectedDiagnostics = new DiagnosticDescription[] { outerParentheticalExpressionDiagnostic, innerParentheticalExpressionDiagnostic }; - await TestDiagnosticsAsync( - """ - class C - { - void M() - { - int x = [|(1 + (2 + 3) + 4)|]; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] + public async Task TestUnnecessaryParenthesisDiagnosticInNestedExpression() + { + var outerParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 + (2 + 3) + 4)", 4, 16); + var innerParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(2 + 3)", 4, 21); + var expectedDiagnostics = new DiagnosticDescription[] { outerParentheticalExpressionDiagnostic, innerParentheticalExpressionDiagnostic }; + await TestDiagnosticsAsync( + """ + class C + { + void M() + { + int x = [|(1 + (2 + 3) + 4)|]; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses), expectedDiagnostics); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses), expectedDiagnostics); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] - public async Task TestUnnecessaryParenthesisDiagnosticInNestedMultiLineExpression() - { - var outerFirstLineParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 + 2 +", 4, 16); - var innerParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(3 + 4)", 5, 12); - var expectedDiagnostics = new DiagnosticDescription[] { outerFirstLineParentheticalExpressionDiagnostic, innerParentheticalExpressionDiagnostic }; - await TestDiagnosticsAsync( - """ - class C - { - void M() - { - int x = [|(1 + 2 + - (3 + 4) + - 5 + 6)|]; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27925")] + public async Task TestUnnecessaryParenthesisDiagnosticInNestedMultiLineExpression() + { + var outerFirstLineParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(1 + 2 +", 4, 16); + var innerParentheticalExpressionDiagnostic = GetRemoveUnnecessaryParenthesesDiagnostic("(3 + 4)", 5, 12); + var expectedDiagnostics = new DiagnosticDescription[] { outerFirstLineParentheticalExpressionDiagnostic, innerParentheticalExpressionDiagnostic }; + await TestDiagnosticsAsync( + """ + class C + { + void M() + { + int x = [|(1 + 2 + + (3 + 4) + + 5 + 6)|]; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses), expectedDiagnostics); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses), expectedDiagnostics); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39529")] - public async Task TestUnnecessaryParenthesisIncludesFadeLocations() - { - var input = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39529")] + public async Task TestUnnecessaryParenthesisIncludesFadeLocations() + { + var input = """ + class C + { + void M() { - void M() - { - int x = [|{|expression:{|fade:(|}1 + 2{|fade:)|}|}|]; - } + int x = [|{|expression:{|fade:(|}1 + 2{|fade:)|}|}|]; } - """; + } + """; - var parameters = new TestParameters(options: RemoveAllUnnecessaryParentheses); - using var workspace = CreateWorkspaceFromOptions(input, parameters); - var expectedSpans = workspace.Documents.First().AnnotatedSpans; + var parameters = new TestParameters(options: RemoveAllUnnecessaryParentheses); + using var workspace = CreateWorkspaceFromOptions(input, parameters); + var expectedSpans = workspace.Documents.First().AnnotatedSpans; - var diagnostics = await GetDiagnosticsAsync(workspace, parameters).ConfigureAwait(false); - var diagnostic = diagnostics.Single(); + var diagnostics = await GetDiagnosticsAsync(workspace, parameters).ConfigureAwait(false); + var diagnostic = diagnostics.Single(); - Assert.Equal(3, diagnostic.AdditionalLocations.Count); - Assert.Equal(expectedSpans["expression"].Single(), diagnostic.AdditionalLocations[0].SourceSpan); - Assert.Equal(expectedSpans["fade"][0], diagnostic.AdditionalLocations[1].SourceSpan); - Assert.Equal(expectedSpans["fade"][1], diagnostic.AdditionalLocations[2].SourceSpan); + Assert.Equal(3, diagnostic.AdditionalLocations.Count); + Assert.Equal(expectedSpans["expression"].Single(), diagnostic.AdditionalLocations[0].SourceSpan); + Assert.Equal(expectedSpans["fade"][0], diagnostic.AdditionalLocations[1].SourceSpan); + Assert.Equal(expectedSpans["fade"][1], diagnostic.AdditionalLocations[2].SourceSpan); - Assert.Equal("[1,2]", diagnostic.Properties[WellKnownDiagnosticTags.Unnecessary]); - } + Assert.Equal("[1,2]", diagnostic.Properties[WellKnownDiagnosticTags.Unnecessary]); + } - [Fact, WorkItem(27925, "https://github.com/dotnet/roslyn/issues/39363")] - public async Task TestUnnecessaryParenthesesInSwitchExpression() - { - await TestAsync( - """ - class C + [Fact, WorkItem(27925, "https://github.com/dotnet/roslyn/issues/39363")] + public async Task TestUnnecessaryParenthesesInSwitchExpression() + { + await TestAsync( + """ + class C + { + void M(int x) { - void M(int x) - { - var result = x switch - { - 1 => $$(5), - 2 => 10 + 5, - _ => 100, - } - }; - } - """, - """ - class C - { - void M(int x) - { - var result = x switch - { - 1 => 5, - 2 => 10 + 5, - _ => 100, - } - }; - } - """, offeredWhenRequireForClarityIsEnabled: true); - } + var result = x switch + { + 1 => $$(5), + 2 => 10 + 5, + _ => 100, + } + }; + } + """, + """ + class C + { + void M(int x) + { + var result = x switch + { + 1 => 5, + 2 => 10 + 5, + _ => 100, + } + }; + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26311")] - public async Task TestUnnecessaryParenthesesAroundDefaultLiteral() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26311")] + public async Task TestUnnecessaryParenthesesAroundDefaultLiteral() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - bool f = false; + bool f = false; - string s2 = f ? "" : $$(default); - } + string s2 = f ? "" : $$(default); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - bool f = false; + bool f = false; - string s2 = f ? "" : default; - } + string s2 = f ? "" : default; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestRangeWithConstantExpression() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestRangeWithConstantExpression() + { + await TestAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - _ = s[$$(1)..]; - } + _ = s[$$(1)..]; } - """, - """ - class C + } + """, + """ + class C + { + void M(string s) { - void M(string s) - { - _ = s[1..]; - } + _ = s[1..]; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestRangeWithMemberAccessExpression() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestRangeWithMemberAccessExpression() + { + await TestAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - _ = s[$$(s.Length)..]; - } + _ = s[$$(s.Length)..]; } - """, - """ - class C + } + """, + """ + class C + { + void M(string s) { - void M(string s) - { - _ = s[s.Length..]; - } + _ = s[s.Length..]; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestRangeWithElementAccessExpression() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestRangeWithElementAccessExpression() + { + await TestAsync( + """ + class C + { + void M(string s, int[] indices) { - void M(string s, int[] indices) - { - _ = s[$$(indices[0])..]; - } + _ = s[$$(indices[0])..]; } - """, - """ - class C + } + """, + """ + class C + { + void M(string s, int[] indices) { - void M(string s, int[] indices) - { - _ = s[indices[0]..]; - } + _ = s[indices[0]..]; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestRangeWithBinaryExpression() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestRangeWithBinaryExpression() + { + await TestMissingAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - _ = s[$$(s.Length - 5)..]; - } + _ = s[$$(s.Length - 5)..]; } - """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact] - public async Task TestAlwaysUnnecessaryForPrimaryPattern1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAlwaysUnnecessaryForPrimaryPattern1() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is 1 or $$(2); - } + bool x = o is 1 or $$(2); } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is 1 or 2; - } + bool x = o is 1 or 2; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAlwaysUnnecessaryForPrimaryPattern2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAlwaysUnnecessaryForPrimaryPattern2() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is $$(1) or 2; - } + bool x = o is $$(1) or 2; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is 1 or 2; - } + bool x = o is 1 or 2; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50025")] - public async Task TestDoNotRemoveWithConstantAndTypeAmbiguity() - { - await TestMissingAsync( - """ - public class C - { - public const int Goo = 1; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50025")] + public async Task TestDoNotRemoveWithConstantAndTypeAmbiguity() + { + await TestMissingAsync( + """ + public class C + { + public const int Goo = 1; - public void M(Goo o) - { - if (o is $$(Goo)) M(1); - } + public void M(Goo o) + { + if (o is $$(Goo)) M(1); } + } - public class Goo { } - """); - } + public class Goo { } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50025")] - public async Task TestDoRemoveWithNoConstantAndTypeAmbiguity() - { - await TestAsync( - """ - public class C - { - public const int Goo = 1; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50025")] + public async Task TestDoRemoveWithNoConstantAndTypeAmbiguity() + { + await TestAsync( + """ + public class C + { + public const int Goo = 1; - public void M(object o) - { - if (o is $$(Goo)) M(1); - } - } - """, - """ - public class C - { - public const int Goo = 1; + public void M(object o) + { + if (o is $$(Goo)) M(1); + } + } + """, + """ + public class C + { + public const int Goo = 1; - public void M(object o) - { - if (o is Goo) M(1); - } - } - """, offeredWhenRequireForClarityIsEnabled: true); - } + public void M(object o) + { + if (o is Goo) M(1); + } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestElementAccessOfSuppressedExpression1() - { - await TestAsync( - """ - public class C + [Fact] + public async Task TestElementAccessOfSuppressedExpression1() + { + await TestAsync( + """ + public class C + { + public void M(string[] Strings) { - public void M(string[] Strings) - { - var v = $$(Strings!)[Strings.Count - 1]; - } + var v = $$(Strings!)[Strings.Count - 1]; } - """, - """ - public class C + } + """, + """ + public class C + { + public void M(string[] Strings) { - public void M(string[] Strings) - { - var v = Strings![Strings.Count - 1]; - } + var v = Strings![Strings.Count - 1]; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestElementAccessOfSuppressedExpression2() - { - await TestAsync( - """ - public class C - { - string[] Strings; + [Fact] + public async Task TestElementAccessOfSuppressedExpression2() + { + await TestAsync( + """ + public class C + { + string[] Strings; - public void M() - { - var v = $$(this.Strings!)[Strings.Count - 1]; - } - } - """, - """ - public class C + public void M() { - string[] Strings; - - public void M() - { - var v = this.Strings![Strings.Count - 1]; - } + var v = $$(this.Strings!)[Strings.Count - 1]; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, + """ + public class C + { + string[] Strings; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45100")] - public async Task TestArithmeticOverflow1() - { - await TestMissingAsync( - """ - class C + public void M() { - void M(int a) - { - checked - { - return a + $$(int.MaxValue + -int.MaxValue); - } - } + var v = this.Strings![Strings.Count - 1]; } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45100")] - public async Task TestArithmeticOverflow1_CompilationOption() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45100")] + public async Task TestArithmeticOverflow1() + { + await TestMissingAsync( + """ + class C + { + void M(int a) { - void M(int a) + checked { return a + $$(int.MaxValue + -int.MaxValue); } } - """, parameters: new TestParameters( - options: RemoveAllUnnecessaryParentheses, - compilationOptions: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, checkOverflow: true))); - } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45100")] - public async Task TestArithmeticOverflow2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45100")] + public async Task TestArithmeticOverflow1_CompilationOption() + { + await TestMissingAsync( + """ + class C + { + void M(int a) { - void M(int a) - { - return a + $$(int.MaxValue + -int.MaxValue); - } + return a + $$(int.MaxValue + -int.MaxValue); } - """, - """ - class C + } + """, parameters: new TestParameters( +options: RemoveAllUnnecessaryParentheses, +compilationOptions: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, checkOverflow: true))); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45100")] + public async Task TestArithmeticOverflow2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int a) { - void M(int a) - { - return a + int.MaxValue + -int.MaxValue; - } + return a + $$(int.MaxValue + -int.MaxValue); } - """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); - } + } + """, + """ + class C + { + void M(int a) + { + return a + int.MaxValue + -int.MaxValue; + } + } + """, parameters: new TestParameters(options: RemoveAllUnnecessaryParentheses)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestTupleArgumentsBecomeGenericSyntax1() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = ($$(N < T), (U > (5 + 0))); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestTupleArgumentsBecomeGenericSyntax1() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = ($$(N < T), (U > (5 + 0))); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = (N < T, (U > (5 + 0))); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = (N < T, (U > (5 + 0))); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestTupleArgumentsBecomeGenericSyntax2() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = ((N < T), (U > (5 + 0)$$)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestTupleArgumentsBecomeGenericSyntax2() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = ((N < T), (U > (5 + 0)$$)); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = ((N < T), U > (5 + 0)); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = ((N < T), U > (5 + 0)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestTupleArgumentsBecomeGenericSyntax3() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = ({|FixAllInDocument:$$(N < T), (U > (5 + 0))|}); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestTupleArgumentsBecomeGenericSyntax3() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = ({|FixAllInDocument:$$(N < T), (U > (5 + 0))|}); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = (N < T, (U > (5 + 0))); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = (N < T, (U > (5 + 0))); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestTupleArgumentsBecomeGenericSyntax4() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = ({|FixAllInDocument:(N < T), (U > (5 + 0)$$)|}); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestTupleArgumentsBecomeGenericSyntax4() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = ({|FixAllInDocument:(N < T), (U > (5 + 0)$$)|}); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = ((N < T), U > (5 + 0)); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = ((N < T), U > (5 + 0)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestMethodArgumentsBecomeGenericSyntax1() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = Goo($$(N < T), (U > (5 + 0))); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestMethodArgumentsBecomeGenericSyntax1() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = Goo($$(N < T), (U > (5 + 0))); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = Goo(N < T, (U > (5 + 0))); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = Goo(N < T, (U > (5 + 0))); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestMethodArgumentsBecomeGenericSyntax2() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = Goo((N < T), (U > (5 + 0)$$)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestMethodArgumentsBecomeGenericSyntax2() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = Goo((N < T), (U > (5 + 0)$$)); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = Goo((N < T), U > (5 + 0)); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = Goo((N < T), U > (5 + 0)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] - public async Task TestMethodArgumentsBecomeGenericSyntax3() - { - await TestInRegularAndScriptAsync( - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = Goo({|FixAllInDocument:$$(N < T), (U > (5 + 0))|}); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43934")] + public async Task TestMethodArgumentsBecomeGenericSyntax3() + { + await TestInRegularAndScriptAsync( + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = Goo({|FixAllInDocument:$$(N < T), (U > (5 + 0))|}); } - """, - """ - using System; - public class C { - public void M() - { - var T = 1; - var U = 8; - var N = 9; - var x = Goo(N < T, (U > (5 + 0))); - } + } + """, + """ + using System; + public class C { + public void M() + { + var T = 1; + var U = 8; + var N = 9; + var x = Goo(N < T, (U > (5 + 0))); } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs index 9b335c590f92b..b8873a266df61 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs @@ -15,324 +15,323 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryParentheses +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryParentheses; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryParentheses)] +public partial class RemoveUnnecessaryPatternParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryParentheses)] - public partial class RemoveUnnecessaryPatternParenthesesTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveUnnecessaryPatternParenthesesTests(ITestOutputHelper logger) + : base(logger) { - public RemoveUnnecessaryPatternParenthesesTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryParenthesesCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer(), new CSharpRemoveUnnecessaryParenthesesCodeFixProvider()); - private async Task TestAsync(string initial, string expected, bool offeredWhenRequireForClarityIsEnabled, int index = 0) - { - await TestInRegularAndScriptAsync(initial, expected, options: RemoveAllUnnecessaryParentheses, index: index); + private async Task TestAsync(string initial, string expected, bool offeredWhenRequireForClarityIsEnabled, int index = 0) + { + await TestInRegularAndScriptAsync(initial, expected, options: RemoveAllUnnecessaryParentheses, index: index); - if (offeredWhenRequireForClarityIsEnabled) - { - await TestInRegularAndScriptAsync(initial, expected, options: RequireAllParenthesesForClarity, index: index); - } - else - { - await TestMissingAsync(initial, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); - } + if (offeredWhenRequireForClarityIsEnabled) + { + await TestInRegularAndScriptAsync(initial, expected, options: RequireAllParenthesesForClarity, index: index); } + else + { + await TestMissingAsync(initial, parameters: new TestParameters(options: RequireAllParenthesesForClarity)); + } + } - internal override bool ShouldSkipMessageDescriptionVerification(DiagnosticDescriptor descriptor) - => descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary) && descriptor.DefaultSeverity == DiagnosticSeverity.Hidden; + internal override bool ShouldSkipMessageDescriptionVerification(DiagnosticDescriptor descriptor) + => descriptor.ImmutableCustomTags().Contains(WellKnownDiagnosticTags.Unnecessary) && descriptor.DefaultSeverity == DiagnosticSeverity.Hidden; - [Fact] - public async Task TestArithmeticRequiredForClarity2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestArithmeticRequiredForClarity2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or $$(b and c); - } + bool x = o is a or $$(b and c); } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or b and c; - } + bool x = o is a or b and c; } - """, parameters: new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); - } + } + """, parameters: new TestParameters(options: RequireArithmeticBinaryParenthesesForClarity)); + } - [Fact] - public async Task TestLogicalRequiredForClarity1() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestLogicalRequiredForClarity1() + { + await TestMissingAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or $$(b and c); - } + bool x = o is a or $$(b and c); } - """, new TestParameters(options: RequireOtherBinaryParenthesesForClarity)); - } + } + """, new TestParameters(options: RequireOtherBinaryParenthesesForClarity)); + } - [Fact] - public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame1() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or $$(b or c); - } + bool x = o is a or $$(b or c); } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or b or c; - } + bool x = o is a or b or c; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestLogicalNotRequiredForClarityWhenPrecedenceStaysTheSame2() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is $$(a or b) or c; - } + bool x = o is $$(a or b) or c; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or b or c; - } + bool x = o is a or b or c; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAlwaysUnnecessaryForIsPattern() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAlwaysUnnecessaryForIsPattern() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is $$(a or b); - } + bool x = o is $$(a or b); } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or b; - } + bool x = o is a or b; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAlwaysUnnecessaryForCasePattern() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAlwaysUnnecessaryForCasePattern() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) + switch (o) { - switch (o) - { - case $$(a or b): - return; - } + case $$(a or b): + return; } } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) + switch (o) { - switch (o) - { - case a or b: - return; - } + case a or b: + return; } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAlwaysUnnecessaryForSwitchArmPattern() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAlwaysUnnecessaryForSwitchArmPattern() + { + await TestAsync( + """ + class C + { + int M(object o) { - int M(object o) + return o switch { - return o switch - { - $$(a or b) => 0, - }; - } + $$(a or b) => 0, + }; } - """, - """ - class C + } + """, + """ + class C + { + int M(object o) { - int M(object o) + return o switch { - return o switch - { - a or b => 0, - }; - } + a or b => 0, + }; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestAlwaysUnnecessaryForSubPattern() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestAlwaysUnnecessaryForSubPattern() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is { X: $$(a or b) }; - } + bool x = o is { X: $$(a or b) }; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is { X: a or b }; - } + bool x = o is { X: a or b }; } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); + } - [Fact] - public async Task TestNotAlwaysUnnecessaryForUnaryPattern1() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNotAlwaysUnnecessaryForUnaryPattern1() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or $$(not b); - } + bool x = o is a or $$(not b); } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is a or not b; - } + bool x = o is a or not b; } - """, offeredWhenRequireForClarityIsEnabled: false); - } + } + """, offeredWhenRequireForClarityIsEnabled: false); + } - [Fact] - public async Task TestNotAlwaysUnnecessaryForUnaryPattern2() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestNotAlwaysUnnecessaryForUnaryPattern2() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is $$(not a) or b; - } + bool x = o is $$(not a) or b; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) - { - bool x = o is not a or b; - } + bool x = o is not a or b; } - """, offeredWhenRequireForClarityIsEnabled: false); - } + } + """, offeredWhenRequireForClarityIsEnabled: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52589")] - public async Task TestAlwaysNecessaryForDiscard() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52589")] + public async Task TestAlwaysNecessaryForDiscard() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(object o) { - void M(object o) + if (o is $$(_)) { - if (o is $$(_)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestUnnecessaryForDiscardInSubpattern() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestUnnecessaryForDiscardInSubpattern() + { + await TestAsync( + """ + class C + { + void M(object o) { - void M(object o) + if (o is string { Length: $$(_) }) { - if (o is string { Length: $$(_) }) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) + if (o is string { Length: _ }) { - if (o is string { Length: _ }) - { - } } } - """, offeredWhenRequireForClarityIsEnabled: true); - } + } + """, offeredWhenRequireForClarityIsEnabled: true); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs index e105ed467755e..6499aed4e886d 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessarySuppressions/RemoveUnnecessaryAttributeSuppressionsTests.cs @@ -12,51 +12,51 @@ Microsoft.CodeAnalysis.CSharp.RemoveUnnecessarySuppressions.CSharpRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer, Microsoft.CodeAnalysis.RemoveUnnecessarySuppressions.RemoveUnnecessaryAttributeSuppressionsCodeFixProvider>; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessarySuppressions +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessarySuppressions; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessarySuppressions)] +[WorkItem("https://github.com/dotnet/roslyn/issues/44176")] +public class RemoveUnnecessaryAttributeSuppressionsTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessarySuppressions)] - [WorkItem("https://github.com/dotnet/roslyn/issues/44176")] - public class RemoveUnnecessaryAttributeSuppressionsTests + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); + + [Theory] + // Field + [InlineData(@"Scope = ""member""", @"Target = ""~F:N.C.F""", "assembly")] + // Property + [InlineData(@"Scope = ""member""", @"Target = ""~P:N.C.P""", "assembly")] + // Method + [InlineData(@"Scope = ""member""", @"Target = ""~M:N.C.M()""", "assembly")] + // Type + [InlineData(@"Scope = ""member""", @"Target = ""~T:N.C""", "assembly")] + // Namespace + [InlineData(@"Scope = ""namespace""", @"Target = ""~N:N""", "assembly")] + // NamespaceAndDescendants + [InlineData(@"Scope = ""namespaceanddescendants""", @"Target = ""~N:N""", "assembly")] + // Module - no scope, no target + [InlineData(null, null, "assembly")] + // Module - no target + [InlineData(@"Scope = ""module""", null, "assembly")] + // Module - null target + [InlineData(@"Scope = ""module""", @"Target = null", "assembly")] + // Resource - not handled + [InlineData(@"Scope = ""resource""", @"Target = """"", "assembly")] + // 'module' attribute target + [InlineData(@"Scope = ""member""", @"Target = ""~M:N.C.M()""", "module")] + // Member with non-matching scope (seems to be respected by suppression decoder) + [InlineData(@"Scope = ""type""", @"Target = ""~M:N.C.M()""", "assembly")] + [InlineData(@"Scope = ""namespace""", @"Target = ""~F:N.C.F""", "assembly")] + // Case insensitive scope + [InlineData(@"Scope = ""Member""", @"Target = ""~F:N.C.F""", "assembly")] + [InlineData(@"Scope = ""MEMBER""", @"Target = ""~F:N.C.F""", "assembly")] + public async Task ValidSuppressions(string? scope, string? target, string attributeTarget) { - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); - - [Theory] - // Field - [InlineData(@"Scope = ""member""", @"Target = ""~F:N.C.F""", "assembly")] - // Property - [InlineData(@"Scope = ""member""", @"Target = ""~P:N.C.P""", "assembly")] - // Method - [InlineData(@"Scope = ""member""", @"Target = ""~M:N.C.M()""", "assembly")] - // Type - [InlineData(@"Scope = ""member""", @"Target = ""~T:N.C""", "assembly")] - // Namespace - [InlineData(@"Scope = ""namespace""", @"Target = ""~N:N""", "assembly")] - // NamespaceAndDescendants - [InlineData(@"Scope = ""namespaceanddescendants""", @"Target = ""~N:N""", "assembly")] - // Module - no scope, no target - [InlineData(null, null, "assembly")] - // Module - no target - [InlineData(@"Scope = ""module""", null, "assembly")] - // Module - null target - [InlineData(@"Scope = ""module""", @"Target = null", "assembly")] - // Resource - not handled - [InlineData(@"Scope = ""resource""", @"Target = """"", "assembly")] - // 'module' attribute target - [InlineData(@"Scope = ""member""", @"Target = ""~M:N.C.M()""", "module")] - // Member with non-matching scope (seems to be respected by suppression decoder) - [InlineData(@"Scope = ""type""", @"Target = ""~M:N.C.M()""", "assembly")] - [InlineData(@"Scope = ""namespace""", @"Target = ""~F:N.C.F""", "assembly")] - // Case insensitive scope - [InlineData(@"Scope = ""Member""", @"Target = ""~F:N.C.F""", "assembly")] - [InlineData(@"Scope = ""MEMBER""", @"Target = ""~F:N.C.F""", "assembly")] - public async Task ValidSuppressions(string? scope, string? target, string attributeTarget) - { - var scopeString = scope != null ? $@", {scope}" : string.Empty; - var targetString = target != null ? $@", {target}" : string.Empty; - - var input = $@" + var scopeString = scope != null ? $@", {scope}" : string.Empty; + var targetString = target != null ? $@", {target}" : string.Empty; + + var input = $@" [{attributeTarget}: System.Diagnostics.CodeAnalysis.SuppressMessage(""Category"", ""Id: Title"", Justification = ""Pending""{scopeString}{targetString})] namespace N @@ -68,49 +68,49 @@ class C public void M() {{ }} }} }}"; - await VerifyCS.VerifyCodeFixAsync(input, input); - } - - [Theory] - // Field - no matching symbol - [InlineData(@"Scope = ""member""", @"Target = ""~F:N.C.F2""", "assembly")] - // Field - no matching symbol (case insensitive) - [InlineData(@"Scope = ""Member""", @"Target = ""~F:N.C.F2""", "assembly")] - [InlineData(@"Scope = ""MEMBER""", @"Target = ""~F:N.C.F2""", "assembly")] - // Property - invalid scope - [InlineData(@"Scope = ""invalid""", @"Target = ""~P:N.C.P""", "assembly")] - // Method - wrong signature - [InlineData(@"Scope = ""member""", @"Target = ""~M:N.C.M(System.Int32)""", "assembly")] - // Method - module scope - [InlineData(@"Scope = ""module""", @"Target = ""~M:N.C.M()""", "assembly")] - // Method - null scope - [InlineData(@"Scope = null", @"Target = ""~M:N.C.M()""", "assembly")] - // Method - no scope - [InlineData(null, @"Target = ""~M:N.C.M()""", "assembly")] - // Member scope - null target - [InlineData(@"Scope = ""member""", @"Target = null", "assembly")] - // Member scope - no target - [InlineData(@"Scope = ""member""", null, "assembly")] - // Type - no matching namespace - [InlineData(@"Scope = ""type""", @"Target = ""~T:N2.C""", "assembly")] - // Namespace - extra namespace qualification - [InlineData(@"Scope = ""namespace""", @"Target = ""~N:N.N2""", "assembly")] - // NamespaceAndDescendants - empty target - [InlineData(@"Scope = ""namespaceanddescendants""", @"Target = """"", "assembly")] - // Module - no scope, empty target - [InlineData(null, @"Target = """"", "assembly")] - // Module - no scope, non-empty target - [InlineData(null, @"Target = ""~T:N.C""", "assembly")] - // Module scope, empty target - [InlineData(@"Scope = ""module""", @"Target = """"", "assembly")] - // Module no scope, non-empty target - [InlineData(@"Scope = ""module""", @"Target = ""~T:N.C""", "assembly")] - public async Task InvalidSuppressions(string? scope, string? target, string attributeTarget) - { - var scopeString = scope != null ? $@", {scope}" : string.Empty; - var targetString = target != null ? $@", {target}" : string.Empty; - - var input = $@" + await VerifyCS.VerifyCodeFixAsync(input, input); + } + + [Theory] + // Field - no matching symbol + [InlineData(@"Scope = ""member""", @"Target = ""~F:N.C.F2""", "assembly")] + // Field - no matching symbol (case insensitive) + [InlineData(@"Scope = ""Member""", @"Target = ""~F:N.C.F2""", "assembly")] + [InlineData(@"Scope = ""MEMBER""", @"Target = ""~F:N.C.F2""", "assembly")] + // Property - invalid scope + [InlineData(@"Scope = ""invalid""", @"Target = ""~P:N.C.P""", "assembly")] + // Method - wrong signature + [InlineData(@"Scope = ""member""", @"Target = ""~M:N.C.M(System.Int32)""", "assembly")] + // Method - module scope + [InlineData(@"Scope = ""module""", @"Target = ""~M:N.C.M()""", "assembly")] + // Method - null scope + [InlineData(@"Scope = null", @"Target = ""~M:N.C.M()""", "assembly")] + // Method - no scope + [InlineData(null, @"Target = ""~M:N.C.M()""", "assembly")] + // Member scope - null target + [InlineData(@"Scope = ""member""", @"Target = null", "assembly")] + // Member scope - no target + [InlineData(@"Scope = ""member""", null, "assembly")] + // Type - no matching namespace + [InlineData(@"Scope = ""type""", @"Target = ""~T:N2.C""", "assembly")] + // Namespace - extra namespace qualification + [InlineData(@"Scope = ""namespace""", @"Target = ""~N:N.N2""", "assembly")] + // NamespaceAndDescendants - empty target + [InlineData(@"Scope = ""namespaceanddescendants""", @"Target = """"", "assembly")] + // Module - no scope, empty target + [InlineData(null, @"Target = """"", "assembly")] + // Module - no scope, non-empty target + [InlineData(null, @"Target = ""~T:N.C""", "assembly")] + // Module scope, empty target + [InlineData(@"Scope = ""module""", @"Target = """"", "assembly")] + // Module no scope, non-empty target + [InlineData(@"Scope = ""module""", @"Target = ""~T:N.C""", "assembly")] + public async Task InvalidSuppressions(string? scope, string? target, string attributeTarget) + { + var scopeString = scope != null ? $@", {scope}" : string.Empty; + var targetString = target != null ? $@", {target}" : string.Empty; + + var input = $@" [{attributeTarget}: [|System.Diagnostics.CodeAnalysis.SuppressMessage(""Category"", ""Id: Title"", Justification = ""Pending""{scopeString}{targetString})|]] namespace N @@ -123,7 +123,7 @@ public void M() {{ }} }} }}"; - var fixedCode = $@" + var fixedCode = $@" namespace N {{ @@ -134,17 +134,17 @@ class C public void M() {{ }} }} }}"; - await VerifyCS.VerifyCodeFixAsync(input, fixedCode); - } + await VerifyCS.VerifyCodeFixAsync(input, fixedCode); + } - [Fact] - public async Task ValidAndInvalidSuppressions() - { - var attributePrefix = @"System.Diagnostics.CodeAnalysis.SuppressMessage(""Category"", ""Id: Title"", Justification = ""Pending"""; - var validSuppression = $@"{attributePrefix}, Scope = ""member"", Target = ""~T:C"")"; - var invalidSuppression = $@"[|{attributePrefix}, Scope = ""member"", Target = """")|]"; + [Fact] + public async Task ValidAndInvalidSuppressions() + { + var attributePrefix = @"System.Diagnostics.CodeAnalysis.SuppressMessage(""Category"", ""Id: Title"", Justification = ""Pending"""; + var validSuppression = $@"{attributePrefix}, Scope = ""member"", Target = ""~T:C"")"; + var invalidSuppression = $@"[|{attributePrefix}, Scope = ""member"", Target = """")|]"; - var input = $@" + var input = $@" [assembly: {validSuppression}] [assembly: {invalidSuppression}] [assembly: {validSuppression}, {validSuppression}] @@ -156,7 +156,7 @@ public async Task ValidAndInvalidSuppressions() class C {{ }} "; - var fixedCode = $@" + var fixedCode = $@" [assembly: {validSuppression}] [assembly: {validSuppression}, {validSuppression}] [assembly: {validSuppression}] @@ -165,40 +165,39 @@ class C {{ }} class C {{ }} "; - await VerifyCS.VerifyCodeFixAsync(input, fixedCode); - } - - [Theory] - [InlineData("")] - [InlineData(@", Scope = ""member"", Target = ""~M:C.M()""")] - [InlineData(@", Scope = ""invalid"", Target = ""invalid""")] - public async Task LocalSuppressions(string scopeAndTarget) - { - var input = $@" + await VerifyCS.VerifyCodeFixAsync(input, fixedCode); + } + + [Theory] + [InlineData("")] + [InlineData(@", Scope = ""member"", Target = ""~M:C.M()""")] + [InlineData(@", Scope = ""invalid"", Target = ""invalid""")] + public async Task LocalSuppressions(string scopeAndTarget) + { + var input = $@" [System.Diagnostics.CodeAnalysis.SuppressMessage(""Category"", ""Id: Title"", Justification = ""Pending""{scopeAndTarget})] class C {{ public void M() {{ }} }}"; - await VerifyCS.VerifyCodeFixAsync(input, input); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45465")] - public async Task LegacyModeGlobalSuppressionWithNamespaceAndDescendantsScope() - { - var target = "N:N.InvalidChild"; - var input = $@" + await VerifyCS.VerifyCodeFixAsync(input, input); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45465")] + public async Task LegacyModeGlobalSuppressionWithNamespaceAndDescendantsScope() + { + var target = "N:N.InvalidChild"; + var input = $@" [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage(""Category"", ""Id: Title"", Scope = ""namespaceanddescendants"", Target = {{|#0:""{target}""|}})] namespace N {{ class C {{ }} }}"; - var expectedDiagnostic = VerifyCS.Diagnostic(AbstractRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer.LegacyFormatTargetDescriptor) - .WithLocation(0) - .WithArguments(target); + var expectedDiagnostic = VerifyCS.Diagnostic(AbstractRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer.LegacyFormatTargetDescriptor) + .WithLocation(0) + .WithArguments(target); - await VerifyCS.VerifyCodeFixAsync(input, expectedDiagnostic, input); - } + await VerifyCS.VerifyCodeFixAsync(input, expectedDiagnostic, input); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnreachableCode/RemoveUnreachableCodeTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnreachableCode/RemoveUnreachableCodeTests.cs index 55a51d3334d8d..970e5677951da 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnreachableCode/RemoveUnreachableCodeTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnreachableCode/RemoveUnreachableCodeTests.cs @@ -10,1073 +10,1072 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnreachableCode -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnreachableCode; + +using VerifyCS = CSharpCodeFixVerifier; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnreachableCode)] - public class RemoveUnreachableCodeTests +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnreachableCode)] +public class RemoveUnreachableCodeTests +{ + [Fact] + public async Task TestSingleUnreachableStatement() { - [Fact] - public async Task TestSingleUnreachableStatement() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - } + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestInUnreachableIfBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestInUnreachableIfBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() + if (false) { - if (false) - { - [| var v = 0; - |] } - } + [| var v = 0; + |] } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (false) { - if (false) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestInIfWithNoBlock() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestInIfWithNoBlock() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - if (false) - [| {|CS1023:var v = 0;|} - |] } - } - """, - """ - class C + if (false) + [| {|CS1023:var v = 0;|} + |] } + } + """, + """ + class C + { + void M() { - void M() + if (false) { - if (false) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveSubsequentStatements() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestRemoveSubsequentStatements() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |][| var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |][| var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - } + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestFromSubsequentStatement() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFromSubsequentStatement() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |][| var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |][| var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - } + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveSubsequentStatementsExcludingLocalFunction() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestRemoveSubsequentStatementsExcludingLocalFunction() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |] - void Local() {} - [| - var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |] + void Local() {} + [| + var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); + throw new System.Exception(); - void Local() {} - } + void Local() {} } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveSubsequentStatementsExcludingMultipleLocalFunctions() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestRemoveSubsequentStatementsExcludingMultipleLocalFunctions() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |] - void Local() {} - void Local2() {} - [| - var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |] + void Local() {} + void Local2() {} + [| + var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); + throw new System.Exception(); - void Local() {} - void Local2() {} - } + void Local() {} + void Local2() {} } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveSubsequentStatementsInterspersedWithMultipleLocalFunctions() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestRemoveSubsequentStatementsInterspersedWithMultipleLocalFunctions() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |] - void Local() {} - [| - var z = 2; - |] - void Local2() {} - [| - var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |] + void Local() {} + [| + var z = 2; + |] + void Local2() {} + [| + var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); + throw new System.Exception(); - void Local() {} + void Local() {} - void Local2() {} - } + void Local2() {} } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveSubsequentStatementsInterspersedWithMultipleLocalFunctions2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestRemoveSubsequentStatementsInterspersedWithMultipleLocalFunctions2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |] - void Local() {} - [| - var z = 2; - var z2 = 2; - |] - void Local2() {} - [| - var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |] + void Local() {} + [| + var z = 2; + var z2 = 2; + |] + void Local2() {} + [| + var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); + throw new System.Exception(); - void Local() {} + void Local() {} - void Local2() {} - } + void Local2() {} } - """); - } + } + """); + } - [Fact] - public async Task TestRemoveSubsequentStatementsUpToNextLabel() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestRemoveSubsequentStatementsUpToNextLabel() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |][| - label: - System.Console.WriteLine(); - |][| - var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |][| + label: + System.Console.WriteLine(); + |][| + var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - } + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestOnUnreachableLabel() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestOnUnreachableLabel() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| var v = 0; - |][| - label: - System.Console.WriteLine(); - |][| - var y = 1; - |] } - } - """, - """ - class C + throw new System.Exception(); + [| var v = 0; + |][| + label: + System.Console.WriteLine(); + |][| + var y = 1; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - } + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnReachableLabel() - { - var code = """ - class C + [Fact] + public async Task TestMissingOnReachableLabel() + { + var code = """ + class C + { + void M(object o) { - void M(object o) + if (o != null) { - if (o != null) - { - goto label; - } + goto label; + } - throw new System.Exception(); - [| var v = 0; - |] - label: - System.Console.WriteLine(); + throw new System.Exception(); + [| var v = 0; + |] + label: + System.Console.WriteLine(); - var y = 1; - } + var y = 1; } - """; - var fixedCode = """ - class C + } + """; + var fixedCode = """ + class C + { + void M(object o) { - void M(object o) + if (o != null) { - if (o != null) - { - goto label; - } + goto label; + } - throw new System.Exception(); + throw new System.Exception(); - label: - System.Console.WriteLine(); + label: + System.Console.WriteLine(); - var y = 1; - } + var y = 1; } - """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } - [Fact] - public async Task TestInLambda() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; + [Fact] + public async Task TestInLambda() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - Action a = () => { - if (true) - return; - [| - Console.WriteLine(); - |] }; - } + Action a = () => { + if (true) + return; + [| + Console.WriteLine(); + |] }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - Action a = () => { - if (true) - return; - }; - } + Action a = () => { + if (true) + return; + }; } - """); - } - - [Fact] - public async Task TestInLambdaInExpressionBody() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; + } + """); + } - class C - { - Action M() - => () => { - if (true) - return; - [| - Console.WriteLine(); - |] }; - } - """, - """ - using System; + [Fact] + public async Task TestInLambdaInExpressionBody() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; - class C - { - Action M() - => () => { - if (true) - return; - }; - } - """); - } + class C + { + Action M() + => () => { + if (true) + return; + [| + Console.WriteLine(); + |] }; + } + """, + """ + using System; + + class C + { + Action M() + => () => { + if (true) + return; + }; + } + """); + } - [Fact] - public async Task TestSingleRemovalDoesNotTouchCodeInUnrelatedLocalFunction() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestSingleRemovalDoesNotTouchCodeInUnrelatedLocalFunction() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() + throw new System.Exception(); + [| var v = 0; + |] + void Local() { throw new System.Exception(); - [| var v = 0; - |] - void Local() - { - throw new System.Exception(); - [| var x = 0; - |] } - } + [| var x = 0; + |] } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + throw new System.Exception(); + + void Local() { throw new System.Exception(); - - void Local() - { - throw new System.Exception(); - } } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() + throw new System.Exception(); + [| var v = 0; + |] + void Local() { throw new System.Exception(); - [| var v = 0; - |] - void Local() - { - throw new System.Exception(); - [| var x = 0; - |] } - } + [| var x = 0; + |] } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + throw new System.Exception(); + + void Local() { throw new System.Exception(); - - void Local() - { - throw new System.Exception(); - } } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(object o) { - void M(object o) + if (o == null) { - if (o == null) - { - goto ReachableLabel; - } - - throw new System.Exception(); - [| var v = 0; - |][| - UnreachableLabel: - System.Console.WriteLine(o); - |] - ReachableLabel: - System.Console.WriteLine(o.ToString()); + goto ReachableLabel; } + + throw new System.Exception(); + [| var v = 0; + |][| + UnreachableLabel: + System.Console.WriteLine(o); + |] + ReachableLabel: + System.Console.WriteLine(o.ToString()); } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) + if (o == null) { - if (o == null) - { - goto ReachableLabel; - } + goto ReachableLabel; + } - throw new System.Exception(); + throw new System.Exception(); - ReachableLabel: - System.Console.WriteLine(o.ToString()); - } + ReachableLabel: + System.Console.WriteLine(o.ToString()); } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll3() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll3() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(object o) { - void M(object o) + if (o == null) { - if (o == null) - { - goto ReachableLabel2; - } + goto ReachableLabel2; + } - throw new System.Exception(); - [| var v = 0; - |] - ReachableLabel1: - System.Console.WriteLine(o); + throw new System.Exception(); + [| var v = 0; + |] + ReachableLabel1: + System.Console.WriteLine(o); - ReachableLabel2: - { - System.Console.WriteLine(o.ToString()); - goto ReachableLabel1; - } - [| - var x = 1; - |] } - } - """, - """ - class C + ReachableLabel2: + { + System.Console.WriteLine(o.ToString()); + goto ReachableLabel1; + } + [| + var x = 1; + |] } + } + """, + """ + class C + { + void M(object o) { - void M(object o) + if (o == null) { - if (o == null) - { - goto ReachableLabel2; - } + goto ReachableLabel2; + } - throw new System.Exception(); + throw new System.Exception(); - ReachableLabel1: - System.Console.WriteLine(o); + ReachableLabel1: + System.Console.WriteLine(o); - ReachableLabel2: - { - System.Console.WriteLine(o.ToString()); - goto ReachableLabel1; - } + ReachableLabel2: + { + System.Console.WriteLine(o.ToString()); + goto ReachableLabel1; } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll4() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll4() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(object o) { - void M(object o) + for (int i = 0; i < 10; i = i + 1) { - for (int i = 0; i < 10; i = i + 1) + for (int j = 0; j < 10; j = j + 1) { - for (int j = 0; j < 10; j = j + 1) - { - goto stop; - [| goto outerLoop; - |] } - outerLoop: - return; - } - stop: + goto stop; + [| goto outerLoop; + |] } + outerLoop: return; } + stop: + return; } - """, - """ - class C + } + """, + """ + class C + { + void M(object o) { - void M(object o) + for (int i = 0; i < 10; i = i + 1) { - for (int i = 0; i < 10; i = i + 1) + for (int j = 0; j < 10; j = j + 1) { - for (int j = 0; j < 10; j = j + 1) - { - goto stop; - } - outerLoop: - return; + goto stop; } - stop: + outerLoop: return; } + stop: + return; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll5() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll5() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - if (false) - throw new System.Exception(); - + if (false) throw new System.Exception(); - [| return; - |] } - } - """, - """ - class C - { - void M(object o) - { - if (false) - throw new System.Exception(); + throw new System.Exception(); + [| return; + |] } + } + """, + """ + class C + { + void M(object o) + { + if (false) throw new System.Exception(); - } + + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestInUnreachableInSwitchSection1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestInUnreachableInSwitchSection1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - case 0: - throw new System.Exception(); - [| var v = 0; - |][| break; - |] } - } + case 0: + throw new System.Exception(); + [| var v = 0; + |][| break; + |] } } - """, - """ - class C + } + """, + """ + class C + { + void M(int i) { - void M(int i) + switch (i) { - switch (i) - { - case 0: - throw new System.Exception(); - } + case 0: + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact] - public async Task TestDirectives1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestDirectives1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); - [| - #if true - var v = 0; - |]#endif - } + throw new System.Exception(); + [| + #if true + var v = 0; + |]#endif } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - throw new System.Exception(); + throw new System.Exception(); - #if true - #endif - } + #if true + #endif } - """); - } + } + """); + } - [Fact] - public async Task TestDirectives2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestDirectives2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - #if true - throw new System.Exception(); - [| var v = 0; - |]#endif - } + #if true + throw new System.Exception(); + [| var v = 0; + |]#endif } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - #if true - throw new System.Exception(); - #endif - } + #if true + throw new System.Exception(); + #endif } - """); - } + } + """); + } - [Fact] - public async Task TestDirectives3() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestDirectives3() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - #if true - throw new System.Exception(); - [|#endif - var v = 0; - |] } - } - """, - """ - class C + #if true + throw new System.Exception(); + [|#endif + var v = 0; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - #if true - throw new System.Exception(); + #if true + throw new System.Exception(); - #endif - } + #endif } - """); - } + } + """); + } - [Fact] - public async Task TestForLoop1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestForLoop1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() + for (int i = 0; i < 5;) { - for (int i = 0; i < 5;) - { - i = 2; - goto Lab2; - [| i = 1; - |][| break; - |] Lab2: - return ; - } + i = 2; + goto Lab2; + [| i = 1; + |][| break; + |] Lab2: + return ; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + for (int i = 0; i < 5;) { - for (int i = 0; i < 5;) - { - i = 2; - goto Lab2; - Lab2: - return ; - } + i = 2; + goto Lab2; + Lab2: + return ; } } - """); - } + } + """); + } - [Fact] - public async Task TestInfiniteForLoop() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestInfiniteForLoop() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M() { - void M() - { - for (;;) { } - [| return; - |] } - } - """, - """ - class C + for (;;) { } + [| return; + |] } + } + """, + """ + class C + { + void M() { - void M() - { - for (;;) { } - } + for (;;) { } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] - public async Task TestTopLevel_EndingWithNewLine() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] + public async Task TestTopLevel_EndingWithNewLine() + { + var code = """ + throw new System.Exception(); + [|System.Console.ReadLine(); + |] + """; + var fixedCode = """ + throw new System.Exception(); + + """; + await new VerifyCS.Test { - var code = """ - throw new System.Exception(); - [|System.Console.ReadLine(); - |] - """; - var fixedCode = """ - throw new System.Exception(); - - """; - await new VerifyCS.Test + TestState = { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] - public async Task TestTopLevel_NotEndingWithNewLine() + OutputKind = OutputKind.ConsoleApplication, + }, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] + public async Task TestTopLevel_NotEndingWithNewLine() + { + var code = """ + throw new System.Exception(); + [|System.Console.ReadLine();|] + """; + var fixedCode = """ + throw new System.Exception(); + + """; + await new VerifyCS.Test { - var code = """ - throw new System.Exception(); - [|System.Console.ReadLine();|] - """; - var fixedCode = """ - throw new System.Exception(); - - """; - await new VerifyCS.Test + TestState = { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] - public async Task TestTopLevel_MultipleUnreachableStatements() + OutputKind = OutputKind.ConsoleApplication, + }, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] + public async Task TestTopLevel_MultipleUnreachableStatements() + { + var code = """ + throw new System.Exception(); + [|System.Console.ReadLine(); + |][|System.Console.ReadLine(); + |] + """; + var fixedCode = """ + throw new System.Exception(); + + """; + await new VerifyCS.Test { - var code = """ - throw new System.Exception(); - [|System.Console.ReadLine(); - |][|System.Console.ReadLine(); - |] - """; - var fixedCode = """ - throw new System.Exception(); - - """; - await new VerifyCS.Test + TestState = { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] - public async Task TestTopLevel_MultipleUnreachableStatements_HasClassDeclarationInBetween() - { - var code = """ - throw new System.Exception(); - [|System.Console.ReadLine(); - |] + OutputKind = OutputKind.ConsoleApplication, + }, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - public class C { } - [| - {|CS8803:System.Console.ReadLine();|}|] - """; - var fixedCode = """ - throw new System.Exception(); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] + public async Task TestTopLevel_MultipleUnreachableStatements_HasClassDeclarationInBetween() + { + var code = """ + throw new System.Exception(); + [|System.Console.ReadLine(); + |] + public class C { } + [| + {|CS8803:System.Console.ReadLine();|}|] + """; + var fixedCode = """ + throw new System.Exception(); - public class C { } - """; - await new VerifyCS.Test + public class C { } + + """; + await new VerifyCS.Test + { + TestState = { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] - public async Task TestTopLevel_MultipleUnreachableStatements_AfterClassDeclaration1() + OutputKind = OutputKind.ConsoleApplication, + }, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] + public async Task TestTopLevel_MultipleUnreachableStatements_AfterClassDeclaration1() + { + var code = """ + throw new System.Exception(); + + public class C { } + [| + {|CS8803:System.Console.ReadLine();|}|] + """; + var fixedCode = """ + throw new System.Exception(); + + public class C { } + + """; + await new VerifyCS.Test { - var code = """ - throw new System.Exception(); + TestState = + { + OutputKind = OutputKind.ConsoleApplication, + }, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - public class C { } - [| - {|CS8803:System.Console.ReadLine();|}|] - """; - var fixedCode = """ - throw new System.Exception(); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] + public async Task TestTopLevel_MultipleUnreachableStatements_AfterClassDeclaration2() + { + var code = """ + public class C { } - public class C { } + {|CS8803:throw new System.Exception();|} + [|System.Console.ReadLine();|] + """; + var fixedCode = """ + public class C { } - """; - await new VerifyCS.Test + {|CS8803:throw new System.Exception();|} + + """; + await new VerifyCS.Test + { + TestState = { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61810")] - public async Task TestTopLevel_MultipleUnreachableStatements_AfterClassDeclaration2() + OutputKind = OutputKind.ConsoleApplication, + }, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72024")] + public async Task TestIncompleteBinaryExpression() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ public class C { } - + {|CS8803:throw new System.Exception();|} - [|System.Console.ReadLine();|] - """; - var fixedCode = """ + [|1+1|]{|CS1002:|} + """, + FixedCode = """ public class C { } - + {|CS8803:throw new System.Exception();|} - """; - await new VerifyCS.Test - { - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72024")] - public async Task TestIncompleteBinaryExpression() - { - await new VerifyCS.Test + """, + TestState = { - TestCode = """ - public class C { } - - {|CS8803:throw new System.Exception();|} - [|1+1|]{|CS1002:|} - """, - FixedCode = """ - public class C { } - - {|CS8803:throw new System.Exception();|} - - """, - TestState = - { - OutputKind = OutputKind.ConsoleApplication, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + OutputKind = OutputKind.ConsoleApplication, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnusedLocalFunction/RemoveUnusedLocalFunctionTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnusedLocalFunction/RemoveUnusedLocalFunctionTests.cs index d4ed4ff113b1a..1edc1e0d0d5af 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnusedLocalFunction/RemoveUnusedLocalFunctionTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnusedLocalFunction/RemoveUnusedLocalFunctionTests.cs @@ -13,145 +13,144 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedLocalFunction +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedLocalFunction; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedLocalFunction)] +public partial class RemoveUnusedLocalFunctionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedLocalFunction)] - public partial class RemoveUnusedLocalFunctionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public RemoveUnusedLocalFunctionTests(ITestOutputHelper logger) + : base(logger) { - public RemoveUnusedLocalFunctionTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpRemoveUnusedLocalFunctionCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpRemoveUnusedLocalFunctionCodeFixProvider()); - [Fact] - public async Task RemoveUnusedLocalFunction() - { - await TestInRegularAndScriptAsync( - """ - class Class + [Fact] + public async Task RemoveUnusedLocalFunction() + { + await TestInRegularAndScriptAsync( + """ + class Class + { + void Method() { - void Method() - { - void [|Goo|]() { } - } + void [|Goo|]() { } } - """, - """ - class Class + } + """, + """ + class Class + { + void Method() { - void Method() - { - } } - """); - } + } + """); + } - [Fact] - public async Task RemoveUnusedLocalFunctionFixAll1() - { - await TestInRegularAndScriptAsync( - """ - class Class + [Fact] + public async Task RemoveUnusedLocalFunctionFixAll1() + { + await TestInRegularAndScriptAsync( + """ + class Class + { + void Method() { - void Method() - { - void {|FixAllInDocument:F|}() { } - void G() { } - } + void {|FixAllInDocument:F|}() { } + void G() { } } - """, - """ - class Class + } + """, + """ + class Class + { + void Method() { - void Method() - { - } } - """); - } + } + """); + } - [Fact] - public async Task RemoveUnusedLocalFunctionFixAll2() - { - await TestInRegularAndScriptAsync( - """ - class Class + [Fact] + public async Task RemoveUnusedLocalFunctionFixAll2() + { + await TestInRegularAndScriptAsync( + """ + class Class + { + void Method() { - void Method() - { - void G() { } - void {|FixAllInDocument:F|}() { } - } + void G() { } + void {|FixAllInDocument:F|}() { } } - """, - """ - class Class + } + """, + """ + class Class + { + void Method() { - void Method() - { - } } - """); - } + } + """); + } - [Fact] - public async Task RemoveUnusedLocalFunctionFixAll3() - { - await TestInRegularAndScriptAsync( - """ - class Class + [Fact] + public async Task RemoveUnusedLocalFunctionFixAll3() + { + await TestInRegularAndScriptAsync( + """ + class Class + { + void Method() { - void Method() - { - void {|FixAllInDocument:F|}() { void G() { } } - } + void {|FixAllInDocument:F|}() { void G() { } } } - """, - """ - class Class + } + """, + """ + class Class + { + void Method() { - void Method() - { - } } - """); - } + } + """); + } - [Fact] - public async Task RemoveUnusedLocalFunctionFixAll4() - { - await TestInRegularAndScriptAsync( - """ - class Class + [Fact] + public async Task RemoveUnusedLocalFunctionFixAll4() + { + await TestInRegularAndScriptAsync( + """ + class Class + { + void Method() { - void Method() - { - void G() { void {|FixAllInDocument:F|}() { } } - } + void G() { void {|FixAllInDocument:F|}() { } } } - """, - """ - class Class + } + """, + """ + class Class + { + void Method() { - void Method() - { - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44272")] - public async Task TopLevelStatement() - { - await TestAsync(""" - void [|local()|] { } - """, - """ + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44272")] + public async Task TopLevelStatement() + { + await TestAsync(""" + void [|local()|] { } + """, + """ - """, TestOptions.Regular); - } + """, TestOptions.Regular); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnusedMembers/RemoveUnusedMembersTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnusedMembers/RemoveUnusedMembersTests.cs index af3a950e24d70..2bcf767b9dfeb 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnusedMembers/RemoveUnusedMembersTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnusedMembers/RemoveUnusedMembersTests.cs @@ -14,3229 +14,3227 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedMembers +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedMembers; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnusedMembersDiagnosticAnalyzer, + CSharpRemoveUnusedMembersCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)] +public class RemoveUnusedMembersTests { - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveUnusedMembersDiagnosticAnalyzer, - CSharpRemoveUnusedMembersCodeFixProvider>; + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)] - public class RemoveUnusedMembersTests + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31582")] + public async Task FieldReadViaSuppression() { - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31582")] - public async Task FieldReadViaSuppression() - { - var code = """ - #nullable enable - class MyClass - { - string? _field = null; - public void M() - { - _field!.ToString(); - } - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateField(string accessibility) - { - var code = $$""" - class MyClass - { - {{accessibility}} int _goo; - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateFieldWithConstantInitializer(string accessibility) - { - var code = $$""" - class MyClass - { - {{accessibility}} int _goo = 0; - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateFieldWithNonConstantInitializer(string accessibility) - { - var code = $$""" - class MyClass - { - {{accessibility}} int _goo = _goo2; - private static readonly int _goo2 = 0; - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateMethod(string accessibility) - { - var code = $$""" - class MyClass - { - {{accessibility}} void M() { } - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateProperty(string accessibility) - { - var code = $$""" - class MyClass - { - {{accessibility}} int P { get; } - } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateIndexer(string accessibility) - { - var code = $$""" - class MyClass + var code = """ + #nullable enable + class MyClass + { + string? _field = null; + public void M() { - {{accessibility}} - int this[int arg] { get { return 0; } set { } } + _field!.ToString(); } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData("public")] - [InlineData("internal")] - [InlineData("protected")] - [InlineData("protected internal")] - [InlineData("private protected")] - public async Task NonPrivateEvent(string accessibility) - { - var code = $$""" - using System; + } + """; - class MyClass - { - {{accessibility}} event EventHandler RaiseCustomEvent; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateField(string accessibility) + { + var code = $$""" + class MyClass + { + {{accessibility}} int _goo; + } + """; - [Fact] - public async Task FieldIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|_goo|]; - } - """, - """ - class MyClass - { - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task MethodIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|M|]() => 0; - } - """, - """ - class MyClass - { - } - """); - } + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateFieldWithConstantInitializer(string accessibility) + { + var code = $$""" + class MyClass + { + {{accessibility}} int _goo = 0; + } + """; - [Fact] - public async Task GenericMethodIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|M|]() => 0; - } - """, - """ - class MyClass - { - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task MethodInGenericTypeIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|M|]() => 0; - } - """, - """ - class MyClass - { - } - """); - } + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateFieldWithNonConstantInitializer(string accessibility) + { + var code = $$""" + class MyClass + { + {{accessibility}} int _goo = _goo2; + private static readonly int _goo2 = 0; + } + """; - [Fact] - public async Task InstanceConstructorIsUnused_NoArguments() - { - // We only flag constructors with arguments. - var code = """ - class MyClass - { - private MyClass() { } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateMethod(string accessibility) + { + var code = $$""" + class MyClass + { + {{accessibility}} void M() { } + } + """; - [Fact] - public async Task InstanceConstructorIsUnused_WithArguments() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private [|MyClass|](int i) { } - } - """, - """ - class MyClass - { - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task StaticConstructorIsNotFlagged() - { - var code = """ - class MyClass - { - static MyClass() { } - } - """; + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateProperty(string accessibility) + { + var code = $$""" + class MyClass + { + {{accessibility}} int P { get; } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task DestructorIsNotFlagged() - { - var code = """ - class MyClass - { - ~MyClass() { } - } - """; + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateIndexer(string accessibility) + { + var code = $$""" + class MyClass + { + {{accessibility}} + int this[int arg] { get { return 0; } set { } } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task PropertyIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|P|] { get; set; } - } - """, - """ - class MyClass - { - } - """); - } + [Theory] + [InlineData("public")] + [InlineData("internal")] + [InlineData("protected")] + [InlineData("protected internal")] + [InlineData("private protected")] + public async Task NonPrivateEvent(string accessibility) + { + var code = $$""" + using System; - [Fact] - public async Task IndexerIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|this|][int x] { get { return 0; } set { } } - } - """, - """ - class MyClass - { - } - """); - } + class MyClass + { + {{accessibility}} event EventHandler RaiseCustomEvent; + } + """; - [Fact] - public async Task EventIsUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private event System.EventHandler [|e|]; - } - """, - """ - class MyClass - { - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task EntryPointMethodNotFlagged() - { - var code = """ - class MyClass - { - private static void Main() { } - } - """; + [Fact] + public async Task FieldIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|_goo|]; + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MethodIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|M|]() => 0; + } + """, + """ + class MyClass + { + } + """); + } - [Fact] - public async Task EntryPointMethodNotFlagged_02() - { - var code = """ - using System.Threading.Tasks; + [Fact] + public async Task GenericMethodIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|M|]() => 0; + } + """, + """ + class MyClass + { + } + """); + } - class MyClass - { - private static async Task Main() => await Task.CompletedTask; - } - """; + [Fact] + public async Task MethodInGenericTypeIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|M|]() => 0; + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task InstanceConstructorIsUnused_NoArguments() + { + // We only flag constructors with arguments. + var code = """ + class MyClass + { + private MyClass() { } + } + """; - [Fact] - public async Task EntryPointMethodNotFlagged_03() - { - var code = """ - using System.Threading.Tasks; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class MyClass - { - private static async Task Main() => await Task.FromResult(0); - } - """; + [Fact] + public async Task InstanceConstructorIsUnused_WithArguments() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private [|MyClass|](int i) { } + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task StaticConstructorIsNotFlagged() + { + var code = """ + class MyClass + { + static MyClass() { } + } + """; - [Fact] - public async Task EntryPointMethodNotFlagged_04() - { - var code = """ - using System.Threading.Tasks; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class MyClass - { - private static Task Main() => Task.CompletedTask; - } - """; + [Fact] + public async Task DestructorIsNotFlagged() + { + var code = """ + class MyClass + { + ~MyClass() { } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31572")] - public async Task EntryPointMethodNotFlagged_05() - { - var code = """ - using System.Threading.Tasks; + [Fact] + public async Task PropertyIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|P|] { get; set; } + } + """, + """ + class MyClass + { + } + """); + } - class MyClass - { - private static int Main() => 0; - } - """; + [Fact] + public async Task IndexerIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|this|][int x] { get { return 0; } set { } } + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task EventIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private event System.EventHandler [|e|]; + } + """, + """ + class MyClass + { + } + """); + } - [Fact] - public async Task EntryPointMethodNotFlagged_06() - { - var code = """ - return 0; - """; + [Fact] + public async Task EntryPointMethodNotFlagged() + { + var code = """ + class MyClass + { + private static void Main() { } + } + """; - await new VerifyCS.Test + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task EntryPointMethodNotFlagged_02() + { + var code = """ + using System.Threading.Tasks; + + class MyClass { - TestCode = code, - FixedCode = code, - ExpectedDiagnostics = - { - // /0/Test0.cs(2,1): error CS8805: Program using top-level statements must be an executable. - DiagnosticResult.CompilerError("CS8805").WithSpan(1, 1, 1, 10), - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task EntryPointMethodNotFlagged_07() - { - var code = """ - return 0; - """; + private static async Task Main() => await Task.CompletedTask; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task EntryPointMethodNotFlagged_03() + { + var code = """ + using System.Threading.Tasks; - await new VerifyCS.Test + class MyClass { - TestState = - { - Sources = { code, code }, - }, - FixedState = - { - Sources = { code, code }, - }, - ExpectedDiagnostics = - { - // /0/Test0.cs(2,1): error CS8805: Program using top-level statements must be an executable. - DiagnosticResult.CompilerError("CS8805").WithSpan(1, 1, 1, 10), - // /0/Test1.cs(2,1): error CS8802: Only one compilation unit can have top-level statements. - DiagnosticResult.CompilerError("CS8802").WithSpan("/0/Test1.cs", 1, 1, 1, 7), - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task EntryPointMethodNotFlagged_08() - { - var code = """ - return 0; - """; + private static async Task Main() => await Task.FromResult(0); + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task EntryPointMethodNotFlagged_04() + { + var code = """ + using System.Threading.Tasks; - await new VerifyCS.Test + class MyClass { - TestState = - { - Sources = { code }, - OutputKind = OutputKind.ConsoleApplication, - }, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task EntryPointMethodNotFlagged_09() - { - var code = """ - return 0; - """; + private static Task Main() => Task.CompletedTask; + } + """; - await new VerifyCS.Test + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31572")] + public async Task EntryPointMethodNotFlagged_05() + { + var code = """ + using System.Threading.Tasks; + + class MyClass { - TestState = - { - Sources = { code, code }, - OutputKind = OutputKind.ConsoleApplication, - }, - FixedState = - { - Sources = { code, code }, - }, - ExpectedDiagnostics = - { - // /0/Test1.cs(2,1): error CS8802: Only one compilation unit can have top-level statements. - DiagnosticResult.CompilerError("CS8802").WithSpan("/0/Test1.cs", 1, 1, 1, 7), - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task FieldIsUnused_ReadOnly() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private readonly int [|_goo|]; - } - """, - """ - class MyClass - { - } - """); - } + private static int Main() => 0; + } + """; - [Fact] - public async Task PropertyIsUnused_ReadOnly() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|P|] { get; } - } - """, - """ - class MyClass - { - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task EventIsUnused_ReadOnly() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - // error CS0106: The modifier 'readonly' is not valid for this item - private readonly event System.EventHandler {|CS0106:[|E|]|}; - } - """, - """ - class MyClass - { - } - """); - } + [Fact] + public async Task EntryPointMethodNotFlagged_06() + { + var code = """ + return 0; + """; - [Fact] - public async Task FieldIsUnused_Static() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private static int [|_goo|]; - } - """, - """ - class MyClass - { - } - """); - } + TestCode = code, + FixedCode = code, + ExpectedDiagnostics = + { + // /0/Test0.cs(2,1): error CS8805: Program using top-level statements must be an executable. + DiagnosticResult.CompilerError("CS8805").WithSpan(1, 1, 1, 10), + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task MethodIsUnused_Static() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private static void [|M|]() { } - } - """, - """ - class MyClass - { - } - """); - } + [Fact] + public async Task EntryPointMethodNotFlagged_07() + { + var code = """ + return 0; + """; - [Fact] - public async Task PropertyIsUnused_Static() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private static int [|P|] { get { return 0; } } - } - """, - """ - class MyClass - { - } - """); - } + TestState = + { + Sources = { code, code }, + }, + FixedState = + { + Sources = { code, code }, + }, + ExpectedDiagnostics = + { + // /0/Test0.cs(2,1): error CS8805: Program using top-level statements must be an executable. + DiagnosticResult.CompilerError("CS8805").WithSpan(1, 1, 1, 10), + // /0/Test1.cs(2,1): error CS8802: Only one compilation unit can have top-level statements. + DiagnosticResult.CompilerError("CS8802").WithSpan("/0/Test1.cs", 1, 1, 1, 7), + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task IndexerIsUnused_Static() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - // error CS0106: The modifier 'static' is not valid for this item - private static int {|CS0106:[|this|]|}[int x] { get { return 0; } set { } } - } - """, - """ - class MyClass - { - } - """); - } + [Fact] + public async Task EntryPointMethodNotFlagged_08() + { + var code = """ + return 0; + """; - [Fact] - public async Task EventIsUnused_Static() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private static event System.EventHandler [|e1|]; - } - """, - """ - class MyClass - { - } - """); - } + TestState = + { + Sources = { code }, + OutputKind = OutputKind.ConsoleApplication, + }, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task EntryPointMethodNotFlagged_09() + { + var code = """ + return 0; + """; - [Fact] - public async Task MethodIsUnused_Extern() + await new VerifyCS.Test { - var code = """ - using System.Runtime.InteropServices; + TestState = + { + Sources = { code, code }, + OutputKind = OutputKind.ConsoleApplication, + }, + FixedState = + { + Sources = { code, code }, + }, + ExpectedDiagnostics = + { + // /0/Test1.cs(2,1): error CS8802: Only one compilation unit can have top-level statements. + DiagnosticResult.CompilerError("CS8802").WithSpan("/0/Test1.cs", 1, 1, 1, 7), + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - class C - { - [DllImport("Assembly.dll")] - private static extern void M(); - } - """; + [Fact] + public async Task FieldIsUnused_ReadOnly() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private readonly int [|_goo|]; + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task PropertyIsUnused_ReadOnly() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|P|] { get; } + } + """, + """ + class MyClass + { + } + """); + } - [Fact] - public async Task MethodIsUnused_Abstract() - { - var code = """ - abstract class C - { - protected abstract void M(); - } - """; + [Fact] + public async Task EventIsUnused_ReadOnly() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + // error CS0106: The modifier 'readonly' is not valid for this item + private readonly event System.EventHandler {|CS0106:[|E|]|}; + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsUnused_Static() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private static int [|_goo|]; + } + """, + """ + class MyClass + { + } + """); + } - [Fact] - public async Task MethodIsUnused_InterfaceMethod() - { - var code = """ - interface I - { - void M(); - } - """; + [Fact] + public async Task MethodIsUnused_Static() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private static void [|M|]() { } + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task PropertyIsUnused_Static() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private static int [|P|] { get { return 0; } } + } + """, + """ + class MyClass + { + } + """); + } - [Fact] - public async Task MethodIsUnused_ExplicitInterfaceImplementation() - { - var code = """ - interface I - { - void M(); - } + [Fact] + public async Task IndexerIsUnused_Static() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + // error CS0106: The modifier 'static' is not valid for this item + private static int {|CS0106:[|this|]|}[int x] { get { return 0; } set { } } + } + """, + """ + class MyClass + { + } + """); + } + + [Fact] + public async Task EventIsUnused_Static() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private static event System.EventHandler [|e1|]; + } + """, + """ + class MyClass + { + } + """); + } + + [Fact] + public async Task MethodIsUnused_Extern() + { + var code = """ + using System.Runtime.InteropServices; + + class C + { + [DllImport("Assembly.dll")] + private static extern void M(); + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task MethodIsUnused_Abstract() + { + var code = """ + abstract class C + { + protected abstract void M(); + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task MethodIsUnused_InterfaceMethod() + { + var code = """ + interface I + { + void M(); + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task MethodIsUnused_ExplicitInterfaceImplementation() + { + var code = """ + interface I + { + void M(); + } + + class C : I + { + void I.M() { } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task PropertyIsUnused_ExplicitInterfaceImplementation() + { + var code = """ + interface I + { + int P { get; set; } + } + + class C : I + { + int I.P { get { return 0; } set { } } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30965")] + public async Task EventIsUnused_ExplicitInterfaceImplementation() + { + var code = """ + interface I + { + event System.Action E; + } - class C : I + class C : I + { + event System.Action I.E { - void I.M() { } + add { } + remove { } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task PropertyIsUnused_ExplicitInterfaceImplementation() - { - var code = """ - interface I - { - int P { get; set; } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30894")] + public async Task WriteOnlyProperty_NotWritten() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + int [|P|] { set { } } + } + """, + """ + class C + { + } + """); + } - class C : I - { - int I.P { get { return 0; } set { } } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30894")] + public async Task WriteOnlyProperty_Written() + { + var code = """ + class C + { + int P { set { } } + public void M(int i) => P = i; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30965")] - public async Task EventIsUnused_ExplicitInterfaceImplementation() - { - var code = """ - interface I - { - event System.Action E; - } + [Fact] + public async Task FieldIsUnused_Const() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private const int [|_goo|] = 0; + } + """, + """ + class MyClass + { + } + """); + } - class C : I - { - event System.Action I.E - { - add { } - remove { } - } - } - """; + [Fact] + public async Task FieldIsRead_ExpressionBody() + { + var code = """ + class MyClass + { + private int _goo; + public int M() => _goo; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30894")] - public async Task WriteOnlyProperty_NotWritten() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C - { - int [|P|] { set { } } - } - """, - """ - class C - { - } - """); - } + [Fact] + public async Task FieldIsRead_BlockBody() + { + var code = """ + class MyClass + { + private int _goo; + public int M() { return _goo; } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30894")] - public async Task WriteOnlyProperty_Written() - { - var code = """ - class C + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task FieldIsRead_ExpressionLambda() + { + var code = """ + using System; + class MyClass + { + private int _goo; + public void M() { - int P { set { } } - public void M(int i) => P = i; + Func getGoo = () => _goo; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsUnused_Const() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private const int [|_goo|] = 0; - } - """, - """ - class MyClass + [Fact] + public async Task FieldIsRead_BlockLambda() + { + var code = """ + using System; + class MyClass + { + private int _goo; + public void M() { + Func getGoo = () => { return _goo; }; } - """); - } + } + """; - [Fact] - public async Task FieldIsRead_ExpressionBody() - { - var code = """ - class MyClass + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task FieldIsRead_Delegate() + { + var code = """ + using System; + class MyClass + { + private int _goo; + public void M() { - private int _goo; - public int M() => _goo; + Func getGoo = delegate { return _goo; }; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_BlockBody() - { - var code = """ - class MyClass + [Fact] + public async Task FieldIsRead_ExpressionBodyLocalFunction() + { + var code = """ + class MyClass + { + private int _goo; + public int M() { - private int _goo; - public int M() { return _goo; } + int LocalFunction() => _goo; + return LocalFunction(); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_ExpressionLambda() - { - var code = """ - using System; - class MyClass + [Fact] + public async Task FieldIsRead_BlockBodyLocalFunction() + { + var code = """ + class MyClass + { + private int _goo; + public int M() { - private int _goo; - public void M() - { - Func getGoo = () => _goo; - } + int LocalFunction() { return _goo; } + return LocalFunction(); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_BlockLambda() - { - var code = """ - using System; - class MyClass + [Fact] + public async Task FieldIsRead_Accessor() + { + var code = """ + class MyClass + { + private int _goo; + public int Goo { - private int _goo; - public void M() + get { - Func getGoo = () => { return _goo; }; + return _goo; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_Delegate() - { - var code = """ - using System; - class MyClass + [Fact] + public async Task FieldIsRead_Deconstruction() + { + var code = """ + class MyClass + { + private int _goo; + public void M(int x) { - private int _goo; - public void M() - { - Func getGoo = delegate { return _goo; }; - } + var y = (_goo, x); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_ExpressionBodyLocalFunction() - { - var code = """ - class MyClass - { - private int _goo; - public int M() - { - int LocalFunction() => _goo; - return LocalFunction(); - } - } - """; + [Fact] + public async Task FieldIsRead_DifferentInstance() + { + var code = """ + class MyClass + { + private int _goo; + public int M() => new MyClass()._goo; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_BlockBodyLocalFunction() - { - var code = """ - class MyClass - { - private int _goo; - public int M() - { - int LocalFunction() { return _goo; } - return LocalFunction(); - } - } - """; + [Fact] + public async Task FieldIsRead_ObjectInitializer() + { + var code = """ + class C + { + public int F; + } + class MyClass + { + private int _goo; + public C M() => new C() { F = _goo }; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_Accessor() - { - var code = """ - class MyClass - { - private int _goo; - public int Goo - { - get - { - return _goo; - } - } - } - """; + [Fact] + public async Task FieldIsRead_ThisInstance() + { + var code = """ + class MyClass + { + private int _goo; + public int M() => this._goo; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_Deconstruction() - { - var code = """ - class MyClass - { - private int _goo; - public void M(int x) - { - var y = (_goo, x); - } - } - """; + [Fact] + public async Task FieldIsRead_Attribute() + { + var code = """ + class MyClass + { + private const string _goo = ""; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [System.Obsolete(_goo)] + public void M() { } + } + """; - [Fact] - public async Task FieldIsRead_DifferentInstance() - { - var code = """ - class MyClass - { - private int _goo; - public int M() => new MyClass()._goo; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MethodIsInvoked() + { + var code = """ + class MyClass + { + private int M1() => 0; + public int M2() => M1(); + } + """; - [Fact] - public async Task FieldIsRead_ObjectInitializer() - { - var code = """ - class C - { - public int F; - } - class MyClass + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task MethodIsAddressTaken() + { + var code = """ + class MyClass + { + private int M1() => 0; + public void M2() { - private int _goo; - public C M() => new C() { F = _goo }; + System.Func m1 = M1; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_ThisInstance() - { - var code = """ - class MyClass - { - private int _goo; - public int M() => this._goo; - } - """; + [Fact] + public async Task GenericMethodIsInvoked_ExplicitTypeArguments() + { + var code = """ + class MyClass + { + private int M1() => 0; + public int M2() => M1(); + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_Attribute() - { - var code = """ - class MyClass - { - private const string _goo = ""; + [Fact] + public async Task GenericMethodIsInvoked_ImplicitTypeArguments() + { + var code = """ + class MyClass + { + private T M1(T t) => t; + public int M2() => M1(0); + } + """; - [System.Obsolete(_goo)] - public void M() { } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MethodInGenericTypeIsInvoked_NoTypeArguments() + { + var code = """ + class MyClass + { + private int M1() => 0; + public int M2() => M1(); + } + """; - [Fact] - public async Task MethodIsInvoked() - { - var code = """ - class MyClass - { - private int M1() => 0; - public int M2() => M1(); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MethodInGenericTypeIsInvoked_NonConstructedType() + { + var code = """ + class MyClass + { + private int M1() => 0; + public int M2(MyClass m) => m.M1(); + } + """; - [Fact] - public async Task MethodIsAddressTaken() - { - var code = """ - class MyClass - { - private int M1() => 0; - public void M2() - { - System.Func m1 = M1; - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MethodInGenericTypeIsInvoked_ConstructedType() + { + var code = """ + class MyClass + { + private int M1() => 0; + public int M2(MyClass m) => m.M1(); + } + """; - [Fact] - public async Task GenericMethodIsInvoked_ExplicitTypeArguments() - { - var code = """ - class MyClass - { - private int M1() => 0; - public int M2() => M1(); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task InstanceConstructorIsUsed_NoArguments() + { + var code = """ + class MyClass + { + private MyClass() { } + public static readonly MyClass Instance = new MyClass(); + } + """; - [Fact] - public async Task GenericMethodIsInvoked_ImplicitTypeArguments() - { - var code = """ - class MyClass - { - private T M1(T t) => t; - public int M2() => M1(0); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task InstanceConstructorIsUsed_WithArguments() + { + var code = """ + class MyClass + { + private MyClass(int i) { } + public static readonly MyClass Instance = new MyClass(0); + } + """; - [Fact] - public async Task MethodInGenericTypeIsInvoked_NoTypeArguments() - { - var code = """ - class MyClass - { - private int M1() => 0; - public int M2() => M1(); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task InstanceConstructorIsUsed_RecordCopyConstructor() + { + var code = """ + var a = new A(); + + sealed record A() + { + private A(A other) => throw new System.NotImplementedException(); + } + """; + + await new VerifyCS.Test + { + TestState = + { + Sources = { code }, + OutputKind = OutputKind.ConsoleApplication + }, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task MethodInGenericTypeIsInvoked_NonConstructedType() - { - var code = """ - class MyClass - { - private int M1() => 0; - public int M2(MyClass m) => m.M1(); - } - """; + [Fact] + public async Task PropertyIsRead() + { + var code = """ + class MyClass + { + private int P => 0; + public int M() => P; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task MethodInGenericTypeIsInvoked_ConstructedType() - { - var code = """ - class MyClass - { - private int M1() => 0; - public int M2(MyClass m) => m.M1(); - } - """; + [Fact] + public async Task IndexerIsRead() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public int M(int x) => this[x]; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task InstanceConstructorIsUsed_NoArguments() - { - var code = """ - class MyClass - { - private MyClass() { } - public static readonly MyClass Instance = new MyClass(); - } - """; + [Fact] + public async Task EventIsRead() + { + var code = """ + using System; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + class MyClass + { + private event EventHandler e; + public EventHandler P => e; + } + """; - [Fact] - public async Task InstanceConstructorIsUsed_WithArguments() - { - var code = """ - class MyClass - { - private MyClass(int i) { } - public static readonly MyClass Instance = new MyClass(0); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task EventIsSubscribed() + { + var code = """ + using System; - [Fact] - public async Task InstanceConstructorIsUsed_RecordCopyConstructor() - { - var code = """ - var a = new A(); - - sealed record A() - { - private A(A other) => throw new System.NotImplementedException(); - } - """; - - await new VerifyCS.Test - { - TestState = - { - Sources = { code }, - OutputKind = OutputKind.ConsoleApplication - }, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task PropertyIsRead() - { - var code = """ - class MyClass + class MyClass + { + private event EventHandler e; + public void M() { - private int P => 0; - public int M() => P; + e += MyHandler; } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - [Fact] - public async Task IndexerIsRead() - { - var code = """ - class MyClass + static void MyHandler(object sender, EventArgs e) { - private int this[int x] { get { return 0; } set { } } - public int M(int x) => this[x]; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task EventIsRead() - { - var code = """ - using System; + [Fact] + public async Task EventIsRaised() + { + var code = """ + using System; - class MyClass + class MyClass + { + private event EventHandler _eventHandler; + + public void RaiseEvent(EventArgs e) { - private event EventHandler e; - public EventHandler P => e; + _eventHandler(this, e); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task EventIsSubscribed() - { - var code = """ - using System; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class MyClass - { - private event EventHandler e; - public void M() - { - e += MyHandler; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32488")] + public async Task FieldInNameOf() + { + var code = """ + class MyClass + { + private int _goo; + public string _goo2 = nameof(_goo); + } + """; - static void MyHandler(object sender, EventArgs e) - { - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33765")] + public async Task GenericFieldInNameOf() + { + var code = """ + class MyClass + { + private T _goo; + public string _goo2 = nameof(MyClass._goo); + } + """; - [Fact] - public async Task EventIsRaised() - { - var code = """ - using System; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class MyClass - { - private event EventHandler _eventHandler; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31581")] + public async Task MethodInNameOf() + { + var code = """ + class MyClass + { + private void M() { } + private string _goo = nameof(M); + } + """; - public void RaiseEvent(EventArgs e) - { - _eventHandler(this, e); - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33765")] + public async Task GenericMethodInNameOf() + { + var code = """ + class MyClass + { + private void M() { } + private string _goo2 = nameof(MyClass.M); + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32488")] - public async Task FieldInNameOf() - { - var code = """ - class MyClass - { - private int _goo; - public string _goo2 = nameof(_goo); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31581")] + public async Task PropertyInNameOf() + { + var code = """ + class MyClass + { + private int P { get; } + public string _goo = nameof(P); + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33765")] - public async Task GenericFieldInNameOf() - { - var code = """ - class MyClass - { - private T _goo; - public string _goo2 = nameof(MyClass._goo); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32522")] + public async Task TestDynamicInvocation() + { + var code = """ + class MyClass + { + private void M(dynamic d) { } + public void M2(dynamic d) => M(d); + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31581")] - public async Task MethodInNameOf() - { - var code = """ - class MyClass - { - private void M() { } - private string _goo = nameof(M); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32522")] + public async Task TestDynamicObjectCreation() + { + var code = """ + class MyClass + { + private MyClass(int i) { } + public static MyClass Create(dynamic d) => new MyClass(d); + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33765")] - public async Task GenericMethodInNameOf() - { - var code = """ - class MyClass - { - private void M() { } - private string _goo2 = nameof(MyClass.M); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32522")] + public async Task TestDynamicIndexerAccess() + { + var code = """ + class MyClass + { + private int[] _list; + private int this[int index] => _list[index]; + public int M2(dynamic d) => this[d]; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31581")] - public async Task PropertyInNameOf() - { - var code = """ - class MyClass - { - private int P { get; } - public string _goo = nameof(P); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldInDocComment() + { + var code = """ + /// + /// + /// + class C + { + private static int {|IDE0052:_goo|}; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32522")] - public async Task TestDynamicInvocation() - { - var code = """ - class MyClass - { - private void M(dynamic d) { } - public void M2(dynamic d) => M(d); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldInDocComment_02() + { + var code = """ + class C + { + /// + /// + /// + private static int {|IDE0052:_goo|}; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32522")] - public async Task TestDynamicObjectCreation() - { - var code = """ - class MyClass - { - private MyClass(int i) { } - public static MyClass Create(dynamic d) => new MyClass(d); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldInDocComment_03() + { + var code = """ + class C + { + /// + /// + /// + public void M() { } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32522")] - public async Task TestDynamicIndexerAccess() - { - var code = """ - class MyClass - { - private int[] _list; - private int this[int index] => _list[index]; - public int M2(dynamic d) => this[d]; - } - """; + private static int {|IDE0052:_goo|}; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldInDocComment() - { - var code = """ + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48247")] + public async Task GenericMethodInDocComment() + { + var code = """ + class C + { /// - /// + /// /// - class C - { - private static int {|IDE0052:_goo|}; - } - """; + public void M1() { } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + private void {|IDE0052:M2|}() { } + } + """; - [Fact] - public async Task FieldInDocComment_02() - { - var code = """ - class C + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task FieldIsOnlyWritten() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M() { - /// - /// - /// - private static int {|IDE0052:_goo|}; + _goo = 0; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldInDocComment_03() - { - var code = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33994")] + public async Task PropertyIsOnlyWritten() + { + var source = + """ + class MyClass + { + private int {|#0:P|} { get; set; } + public void M() { - /// - /// - /// - public void M() { } - - private static int {|IDE0052:_goo|}; + P = 0; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + var descriptor = new CSharpRemoveUnusedMembersDiagnosticAnalyzer().SupportedDiagnostics.First(x => x.Id == "IDE0052"); + var expectedMessage = string.Format(AnalyzersResources.Private_property_0_can_be_converted_to_a_method_as_its_get_accessor_is_never_invoked, "MyClass.P"); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48247")] - public async Task GenericMethodInDocComment() + await new VerifyCS.Test { - var code = """ - class C - { - /// - /// - /// - public void M1() { } + TestCode = source, + ExpectedDiagnostics = + { + // Test0.cs(3,17): info IDE0052: Private property 'MyClass.P' can be converted to a method as its get accessor is never invoked. + VerifyCS.Diagnostic(descriptor).WithMessage(expectedMessage).WithLocation(0), + }, + FixedCode = source, + }.RunAsync(); + } - private void {|IDE0052:M2|}() { } + [Fact] + public async Task IndexerIsOnlyWritten() + { + var code = """ + class MyClass + { + private int {|IDE0052:this|}[int x] { get { return 0; } set { } } + public void M(int x, int y) + { + this[x] = y; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsOnlyWritten() - { - var code = """ - class MyClass + [Fact] + public async Task EventIsOnlyWritten() + { + var code = """ + class MyClass + { + private event System.EventHandler e { add { } remove { } } + public void M() { - private int {|IDE0052:_goo|}; - public void M() - { - _goo = 0; - } + // CS0079: The event 'MyClass.e' can only appear on the left hand side of += or -= + {|CS0079:e|} = null; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33994")] - public async Task PropertyIsOnlyWritten() - { - var source = - """ - class MyClass - { - private int {|#0:P|} { get; set; } - public void M() - { - P = 0; - } - } - """; + [Fact] + public async Task FieldIsOnlyInitialized_NonConstant() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|} = M(); + public static int M() => 0; + } + """; - var descriptor = new CSharpRemoveUnusedMembersDiagnosticAnalyzer().SupportedDiagnostics.First(x => x.Id == "IDE0052"); - var expectedMessage = string.Format(AnalyzersResources.Private_property_0_can_be_converted_to_a_method_as_its_get_accessor_is_never_invoked, "MyClass.P"); + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await new VerifyCS.Test + [Fact] + public async Task FieldIsOnlyWritten_Deconstruction() + { + var code = """ + class MyClass { - TestCode = source, - ExpectedDiagnostics = - { - // Test0.cs(3,17): info IDE0052: Private property 'MyClass.P' can be converted to a method as its get accessor is never invoked. - VerifyCS.Diagnostic(descriptor).WithMessage(expectedMessage).WithLocation(0), - }, - FixedCode = source, - }.RunAsync(); - } - - [Fact] - public async Task IndexerIsOnlyWritten() - { - var code = """ - class MyClass + private int {|IDE0052:_goo|}; + public void M() { - private int {|IDE0052:this|}[int x] { get { return 0; } set { } } - public void M(int x, int y) - { - this[x] = y; - } + int x; + (_goo, x) = (0, 0); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task EventIsOnlyWritten() - { - var code = """ - class MyClass - { - private event System.EventHandler e { add { } remove { } } - public void M() - { - // CS0079: The event 'MyClass.e' can only appear on the left hand side of += or -= - {|CS0079:e|} = null; - } - } - """; + [Fact] + public async Task FieldIsOnlyWritten_ObjectInitializer() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public MyClass M() => new MyClass() { _goo = 0 }; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsOnlyInitialized_NonConstant() - { - var code = """ - class MyClass + [Fact] + public async Task FieldIsOnlyWritten_InProperty() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public int Goo { - private int {|IDE0052:_goo|} = M(); - public static int M() => 0; + get { return 0; } + set { _goo = value; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsOnlyWritten_Deconstruction() - { - var code = """ - class MyClass + [Fact] + public async Task FieldIsReadAndWritten() + { + var code = """ + class MyClass + { + private int _goo; + public void M() { - private int {|IDE0052:_goo|}; - public void M() - { - int x; - (_goo, x) = (0, 0); - } + _goo = 0; + System.Console.WriteLine(_goo); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsOnlyWritten_ObjectInitializer() - { - var code = """ - class MyClass + [Fact] + public async Task PropertyIsReadAndWritten() + { + var code = """ + class MyClass + { + private int P { get; set; } + public void M() { - private int {|IDE0052:_goo|}; - public MyClass M() => new MyClass() { _goo = 0 }; + P = 0; + System.Console.WriteLine(P); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsOnlyWritten_InProperty() - { - var code = """ - class MyClass + [Fact] + public async Task IndexerIsReadAndWritten() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public void M(int x) { - private int {|IDE0052:_goo|}; - public int Goo - { - get { return 0; } - set { _goo = value; } - } + this[x] = 0; + System.Console.WriteLine(this[x]); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsReadAndWritten() - { - var code = """ - class MyClass + [Fact] + public async Task FieldIsReadAndWritten_InProperty() + { + var code = """ + class MyClass + { + private int _goo; + public int Goo { - private int _goo; - public void M() - { - _goo = 0; - System.Console.WriteLine(_goo); - } + get { return _goo; } + set { _goo = value; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task PropertyIsReadAndWritten() - { - var code = """ - class MyClass - { - private int P { get; set; } - public void M() - { - P = 0; - System.Console.WriteLine(P); - } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30397")] + public async Task FieldIsIncrementedAndValueUsed() + { + var code = """ + class MyClass + { + private int _goo; + public int M1() => ++_goo; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task IndexerIsReadAndWritten() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public void M(int x) - { - this[x] = 0; - System.Console.WriteLine(this[x]); - } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30397")] + public async Task FieldIsIncrementedAndValueUsed_02() + { + var code = """ + class MyClass + { + private int _goo; + public int M1() { return ++_goo; } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsReadAndWritten_InProperty() - { - var code = """ - class MyClass - { - private int _goo; - public int Goo - { - get { return _goo; } - set { _goo = value; } - } - } - """; + [Fact] + public async Task FieldIsIncrementedAndValueDropped() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M1() => ++_goo; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30397")] - public async Task FieldIsIncrementedAndValueUsed() - { - var code = """ - class MyClass - { - private int _goo; - public int M1() => ++_goo; - } - """; + [Fact] + public async Task FieldIsIncrementedAndValueDropped_02() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M1() { ++_goo; } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30397")] - public async Task FieldIsIncrementedAndValueUsed_02() - { - var code = """ - class MyClass - { - private int _goo; - public int M1() { return ++_goo; } - } - """; + [Fact] + public async Task PropertyIsIncrementedAndValueUsed() + { + var code = """ + class MyClass + { + private int P { get; set; } + public int M1() => ++P; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsIncrementedAndValueDropped() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public void M1() => ++_goo; - } - """; + [Fact] + public async Task PropertyIsIncrementedAndValueDropped() + { + var code = """ + class MyClass + { + private int {|IDE0052:P|} { get; set; } + public void M1() { ++P; } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsIncrementedAndValueDropped_02() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public void M1() { ++_goo; } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task PropertyIsIncrementedAndValueDropped_VerifyAnalizerMessage() + { + var code = """ + class MyClass + { + private int P { get; set; } + public void M1() { ++P; } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( + CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) + .WithSpan(3, 17, 3, 18) + .WithArguments("MyClass.P")); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task PropertyIsIncrementedAndValueDropped_NoDiagnosticWhenPropertyIsReadSomewhereElse() + { + var code = """ + class MyClass + { + private int P { get; set; } + public void M1() { ++P; } + public int M2() => P; + } + """; - [Fact] - public async Task PropertyIsIncrementedAndValueUsed() - { - var code = """ - class MyClass - { - private int P { get; set; } - public int M1() => ++P; - } - """; + await VerifyCS.VerifyAnalyzerAsync(code, []); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task IndexerIsIncrementedAndValueUsed() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public int M1(int x) => ++this[x]; + } + """; - [Fact] - public async Task PropertyIsIncrementedAndValueDropped() - { - var code = """ - class MyClass - { - private int {|IDE0052:P|} { get; set; } - public void M1() { ++P; } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task IndexerIsIncrementedAndValueDropped() + { + var code = """ + class MyClass + { + private int {|IDE0052:this|}[int x] { get { return 0; } set { } } + public void M1(int x) => ++this[x]; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task PropertyIsIncrementedAndValueDropped_VerifyAnalizerMessage() - { - var code = """ - class MyClass - { - private int P { get; set; } - public void M1() { ++P; } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( - CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) - .WithSpan(3, 17, 3, 18) - .WithArguments("MyClass.P")); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task IndexerIsIncrementedAndValueDropped_VerifyAnalizerMessage() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public void M1(int x) => ++this[x]; + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( + CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) + .WithSpan(3, 17, 3, 21) + .WithArguments("MyClass.this")); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task PropertyIsIncrementedAndValueDropped_NoDiagnosticWhenPropertyIsReadSomewhereElse() - { - var code = """ - class MyClass - { - private int P { get; set; } - public void M1() { ++P; } - public int M2() => P; - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task IndexerIsIncrementedAndValueDropped_NoDiagnosticWhenIndexerIsReadSomewhereElse() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public void M1(int x) => ++this[x]; + public int M2(int x) => this[x]; + } + """; - await VerifyCS.VerifyAnalyzerAsync(code, []); - } + await VerifyCS.VerifyAnalyzerAsync(code, []); + } - [Fact] - public async Task IndexerIsIncrementedAndValueUsed() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public int M1(int x) => ++this[x]; - } - """; + [Fact] + public async Task FieldIsTargetOfCompoundAssignmentAndValueUsed() + { + var code = """ + class MyClass + { + private int _goo; + public int M1(int x) => _goo += x; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task IndexerIsIncrementedAndValueDropped() - { - var code = """ - class MyClass - { - private int {|IDE0052:this|}[int x] { get { return 0; } set { } } - public void M1(int x) => ++this[x]; - } - """; + [Fact] + public async Task FieldIsTargetOfCompoundAssignmentAndValueUsed_02() + { + var code = """ + class MyClass + { + private int _goo; + public int M1(int x) { return _goo += x; } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task IndexerIsIncrementedAndValueDropped_VerifyAnalizerMessage() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public void M1(int x) => ++this[x]; - } - """; + [Fact] + public async Task FieldIsTargetOfCompoundAssignmentAndValueDropped() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M1(int x) => _goo += x; + } + """; - await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( - CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) - .WithSpan(3, 17, 3, 21) - .WithArguments("MyClass.this")); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task IndexerIsIncrementedAndValueDropped_NoDiagnosticWhenIndexerIsReadSomewhereElse() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public void M1(int x) => ++this[x]; - public int M2(int x) => this[x]; - } - """; + [Fact] + public async Task FieldIsTargetOfCompoundAssignmentAndValueDropped_02() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M1(int x) { _goo += x; } + } + """; - await VerifyCS.VerifyAnalyzerAsync(code, []); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsTargetOfCompoundAssignmentAndValueUsed() - { - var code = """ - class MyClass - { - private int _goo; - public int M1(int x) => _goo += x; - } - """; + [Fact] + public async Task PropertyIsTargetOfCompoundAssignmentAndValueUsed() + { + var code = """ + class MyClass + { + private int P { get; set; } + public int M1(int x) => P += x; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsTargetOfCompoundAssignmentAndValueUsed_02() - { - var code = """ - class MyClass - { - private int _goo; - public int M1(int x) { return _goo += x; } - } - """; + [Fact] + public async Task PropertyIsTargetOfCompoundAssignmentAndValueDropped() + { + var code = """ + class MyClass + { + private int {|IDE0052:P|} { get; set; } + public void M1(int x) { P += x; } + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsTargetOfCompoundAssignmentAndValueDropped() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public void M1(int x) => _goo += x; - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task PropertyIsTargetOfCompoundAssignmentAndValueDropped_VerifyAnalizerMessage() + { + var code = """ + class MyClass + { + private int P { get; set; } + public void M1(int x) { P += x; } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( + CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) + .WithSpan(3, 17, 3, 18) + .WithArguments("MyClass.P")); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task PropertyIsTargetOfCompoundAssignmentAndValueDropped_NoDiagnosticWhenPropertyIsReadSomewhereElse() + { + var code = """ + class MyClass + { + private int P { get; set; } + public void M1(int x) { P += x; } + public int M2() => P; + } + """; - [Fact] - public async Task FieldIsTargetOfCompoundAssignmentAndValueDropped_02() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public void M1(int x) { _goo += x; } - } - """; + await VerifyCS.VerifyAnalyzerAsync(code, []); + } + + [Fact] + public async Task IndexerIsTargetOfCompoundAssignmentAndValueUsed() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public int M1(int x, int y) => this[x] += y; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task PropertyIsTargetOfCompoundAssignmentAndValueUsed() - { - var code = """ - class MyClass - { - private int P { get; set; } - public int M1(int x) => P += x; - } - """; + [Fact] + public async Task IndexerIsTargetOfCompoundAssignmentAndValueDropped() + { + var code = """ + class MyClass + { + private int {|IDE0052:this|}[int x] { get { return 0; } set { } } + public void M1(int x, int y) => this[x] += y; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task PropertyIsTargetOfCompoundAssignmentAndValueDropped() - { - var code = """ - class MyClass - { - private int {|IDE0052:P|} { get; set; } - public void M1(int x) { P += x; } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task IndexerIsTargetOfCompoundAssignmentAndValueDropped_VerifyAnalyzerMessage() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public void M1(int x, int y) => this[x] += y; + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( + CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) + .WithSpan(3, 17, 3, 21) + .WithArguments("MyClass.this")); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] + public async Task IndexerIsTargetOfCompoundAssignmentAndValueDropped_NoDiagnosticWhenIndexerIsReadSomewhereElse() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public void M1(int x, int y) => this[x] += y; + public int M2(int x) => this[x]; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task PropertyIsTargetOfCompoundAssignmentAndValueDropped_VerifyAnalizerMessage() - { - var code = """ - class MyClass - { - private int P { get; set; } - public void M1(int x) { P += x; } - } - """; + await VerifyCS.VerifyAnalyzerAsync(code, []); + } - await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( - CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) - .WithSpan(3, 17, 3, 18) - .WithArguments("MyClass.P")); - } + [Fact] + public async Task FieldIsTargetOfAssignmentAndParenthesized() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M1(int x) => (_goo) = x; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task PropertyIsTargetOfCompoundAssignmentAndValueDropped_NoDiagnosticWhenPropertyIsReadSomewhereElse() - { - var code = """ - class MyClass - { - private int P { get; set; } - public void M1(int x) { P += x; } - public int M2() => P; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyAnalyzerAsync(code, []); - } + [Fact] + public async Task FieldIsTargetOfAssignmentAndHasImplicitConversion() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public static implicit operator int(MyClass c) => 0; + public void M1(MyClass c) => _goo = c; + } + """; - [Fact] - public async Task IndexerIsTargetOfCompoundAssignmentAndValueUsed() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public int M1(int x, int y) => this[x] += y; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsArg() + { + var code = """ + class MyClass + { + private int _goo; + public int M1() => M2(_goo); + public int M2(int i) { i = 0; return i; } + } + """; - [Fact] - public async Task IndexerIsTargetOfCompoundAssignmentAndValueDropped() - { - var code = """ - class MyClass - { - private int {|IDE0052:this|}[int x] { get { return 0; } set { } } - public void M1(int x, int y) => this[x] += y; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsInArg() + { + var code = """ + class MyClass + { + private int _goo; + public int M1() => M2(_goo); + public int M2(in int i) { return i; } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task IndexerIsTargetOfCompoundAssignmentAndValueDropped_VerifyAnalyzerMessage() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public void M1(int x, int y) => this[x] += y; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyAnalyzerAsync(code, new DiagnosticResult( - CSharpRemoveUnusedMembersDiagnosticAnalyzer.s_removeUnreadMembersRule) - .WithSpan(3, 17, 3, 21) - .WithArguments("MyClass.this")); - } + [Fact] + public async Task FieldIsRefArg() + { + var code = """ + class MyClass + { + private int _goo; + public int M1() => M2(ref _goo); + public int M2(ref int i) => i; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43191")] - public async Task IndexerIsTargetOfCompoundAssignmentAndValueDropped_NoDiagnosticWhenIndexerIsReadSomewhereElse() - { - var code = """ - class MyClass - { - private int this[int x] { get { return 0; } set { } } - public void M1(int x, int y) => this[x] += y; - public int M2(int x) => this[x]; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyAnalyzerAsync(code, []); - } + [Fact] + public async Task FieldIsOutArg() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public int M1() => M2(out _goo); + public int M2(out int i) { i = 0; return i; } + } + """; - [Fact] - public async Task FieldIsTargetOfAssignmentAndParenthesized() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public void M1(int x) => (_goo) = x; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MethodIsArg() + { + var code = """ + class MyClass + { + private int M() => 0; + public int M1() => M2(M); + public int M2(System.Func m) => m(); + } + """; - [Fact] - public async Task FieldIsTargetOfAssignmentAndHasImplicitConversion() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public static implicit operator int(MyClass c) => 0; - public void M1(MyClass c) => _goo = c; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task PropertyIsArg() + { + var code = """ + class MyClass + { + private int P => 0; + public int M1() => M2(P); + public int M2(int p) => p; + } + """; - [Fact] - public async Task FieldIsArg() - { - var code = """ - class MyClass - { - private int _goo; - public int M1() => M2(_goo); - public int M2(int i) { i = 0; return i; } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task IndexerIsArg() + { + var code = """ + class MyClass + { + private int this[int x] { get { return 0; } set { } } + public int M1(int x) => M2(this[x]); + public int M2(int p) => p; + } + """; - [Fact] - public async Task FieldIsInArg() - { - var code = """ - class MyClass - { - private int _goo; - public int M1() => M2(_goo); - public int M2(in int i) { return i; } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task EventIsArg() + { + var code = """ + using System; - [Fact] - public async Task FieldIsRefArg() - { - var code = """ - class MyClass - { - private int _goo; - public int M1() => M2(ref _goo); - public int M2(ref int i) => i; - } - """; + class MyClass + { + private event EventHandler _e; + public EventHandler M1() => M2(_e); + public EventHandler M2(EventHandler e) => e; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsOutArg() - { - var code = """ - class MyClass - { - private int {|IDE0052:_goo|}; - public int M1() => M2(out _goo); - public int M2(out int i) { i = 0; return i; } - } - """; + [Fact] + public async Task MultipleFields_AllUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|_goo|] = 0, [|_bar|] = 0; + } + """, + """ + class MyClass + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Theory, CombinatorialData] + public async Task MultipleFields_AllUnused_FixOne( + [CombinatorialValues("[|_goo|]", "[|_goo|] = 0")] string firstField, + [CombinatorialValues("[|_bar|]", "[|_bar|] = 2")] string secondField, + [CombinatorialValues(0, 1)] int diagnosticIndex) + { + var source = $$""" + class MyClass + { + private int {{firstField}}, {{secondField}}; + } + """; + var fixedSource = $$""" + class MyClass + { + private int {{(diagnosticIndex == 0 ? secondField : firstField)}}; + } + """; + var batchFixedSource = """ + class MyClass + { + } + """; - [Fact] - public async Task MethodIsArg() + await new VerifyCS.Test { - var code = """ - class MyClass - { - private int M() => 0; - public int M1() => M2(M); - public int M2(System.Func m) => m(); - } - """; + TestCode = source, + FixedState = + { + Sources = { fixedSource }, + MarkupHandling = MarkupMode.Allow, + }, + BatchFixedCode = batchFixedSource, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, + DiagnosticSelector = fixableDiagnostics => fixableDiagnostics[diagnosticIndex], + }.RunAsync(); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task MultipleFields_SomeUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|_goo|] = 0, _bar = 0; + public int M() => _bar; + } + """, + """ + class MyClass + { + private int _bar = 0; + public int M() => _bar; + } + """); + } - [Fact] - public async Task PropertyIsArg() - { - var code = """ - class MyClass - { - private int P => 0; - public int M1() => M2(P); - public int M2(int p) => p; - } - """; + [Fact] + public async Task MultipleFields_SomeUnused_02() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int _goo = 0, [|_bar|] = 0; + public int M() => _goo; + } + """, + """ + class MyClass + { + private int _goo = 0; + public int M() => _goo; + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsRead_InNestedType() + { + var code = """ + class MyClass + { + private int _goo; - [Fact] - public async Task IndexerIsArg() - { - var code = """ - class MyClass + class Derived : MyClass { - private int this[int x] { get { return 0; } set { } } - public int M1(int x) => M2(this[x]); - public int M2(int p) => p; + public int M() => _goo; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task EventIsArg() - { - var code = """ - using System; + [Fact] + public async Task MethodIsInvoked_InNestedType() + { + var code = """ + class MyClass + { + private int M1() => 0; - class MyClass + class Derived : MyClass { - private event EventHandler _e; - public EventHandler M1() => M2(_e); - public EventHandler M2(EventHandler e) => e; + public int M2() => M1(); } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task MultipleFields_AllUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|_goo|] = 0, [|_bar|] = 0; - } - """, - """ - class MyClass - { - } - """); - } - - [Theory] - [CombinatorialData] - public async Task MultipleFields_AllUnused_FixOne( - [CombinatorialValues("[|_goo|]", "[|_goo|] = 0")] string firstField, - [CombinatorialValues("[|_bar|]", "[|_bar|] = 2")] string secondField, - [CombinatorialValues(0, 1)] int diagnosticIndex) - { - var source = $$""" - class MyClass - { - private int {{firstField}}, {{secondField}}; - } - """; - var fixedSource = $$""" - class MyClass + [Fact] + public async Task FieldOfNestedTypeIsUnused() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + class NestedType { - private int {{(diagnosticIndex == 0 ? secondField : firstField)}}; + private int [|_goo|]; } - """; - var batchFixedSource = """ - class MyClass + } + """, + """ + class MyClass + { + class NestedType { } - """; + } + """); + } - await new VerifyCS.Test + [Fact] + public async Task FieldOfNestedTypeIsRead() + { + var code = """ + class MyClass { - TestCode = source, - FixedState = - { - Sources = { fixedSource }, - MarkupHandling = MarkupMode.Allow, - }, - BatchFixedCode = batchFixedSource, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne, - DiagnosticSelector = fixableDiagnostics => fixableDiagnostics[diagnosticIndex], - }.RunAsync(); - } - - [Fact] - public async Task MultipleFields_SomeUnused() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass + class NestedType { - private int [|_goo|] = 0, _bar = 0; - public int M() => _bar; - } - """, - """ - class MyClass - { - private int _bar = 0; - public int M() => _bar; - } - """); - } + private int _goo; - [Fact] - public async Task MultipleFields_SomeUnused_02() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int _goo = 0, [|_bar|] = 0; - public int M() => _goo; - } - """, - """ - class MyClass - { - private int _goo = 0; public int M() => _goo; } - """); - } - - [Fact] - public async Task FieldIsRead_InNestedType() - { - var code = """ - class MyClass - { - private int _goo; + } + """; - class Derived : MyClass - { - public int M() => _goo; - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsUnused_PartialClass() + { + await VerifyCS.VerifyCodeFixAsync( + """ + partial class MyClass + { + private int [|_goo|]; + } + """, + """ + partial class MyClass + { + } + """); + } - [Fact] - public async Task MethodIsInvoked_InNestedType() - { - var code = """ - class MyClass - { - private int M1() => 0; + [Fact] + public async Task FieldIsRead_PartialClass() + { + var code = """ + partial class MyClass + { + private int _goo; + } + partial class MyClass + { + public int M() => _goo; + } + """; - class Derived : MyClass - { - public int M2() => M1(); - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsRead_PartialClass_DifferentFile() + { + var source1 = """ + partial class MyClass + { + private int _goo; + } + """; + var source2 = """ + partial class MyClass + { + public int M() => _goo; + } + """; - [Fact] - public async Task FieldOfNestedTypeIsUnused() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - class NestedType - { - private int [|_goo|]; - } - } - """, - """ - class MyClass - { - class NestedType - { - } - } - """); - } + TestState = { Sources = { source1, source2 } }, + FixedState = { Sources = { source1, source2 } }, + }.RunAsync(); + } + + [Fact] + public async Task FieldIsOnlyWritten_PartialClass_DifferentFile() + { + var source1 = """ + partial class MyClass + { + private int {|IDE0052:_goo|}; + } + """; + var source2 = """ + partial class MyClass + { + public void M() { _goo = 0; } + } + """; - [Fact] - public async Task FieldOfNestedTypeIsRead() + await new VerifyCS.Test { - var code = """ - class MyClass - { - class NestedType - { - private int _goo; + TestState = { Sources = { source1, source2 } }, + FixedState = { Sources = { source1, source2 } }, + }.RunAsync(); + } - public int M() => _goo; - } - } - """; + [Fact] + public async Task FieldIsRead_InParens() + { + var code = """ + class MyClass + { + private int _goo; + public int M() => (_goo); + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsUnused_PartialClass() - { - await VerifyCS.VerifyCodeFixAsync( - """ - partial class MyClass - { - private int [|_goo|]; - } - """, - """ - partial class MyClass - { - } - """); - } + [Fact] + public async Task FieldIsWritten_InParens() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public void M() { (_goo) = 1; } + } + """; - [Fact] - public async Task FieldIsRead_PartialClass() - { - var code = """ - partial class MyClass - { - private int _goo; - } - partial class MyClass - { - public int M() => _goo; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsWritten_InParens_02() + { + var code = """ + class MyClass + { + private int {|IDE0052:_goo|}; + public int M() => (_goo) = 1; + } + """; - [Fact] - public async Task FieldIsRead_PartialClass_DifferentFile() - { - var source1 = """ - partial class MyClass - { - private int _goo; - } - """; - var source2 = """ - partial class MyClass - { - public int M() => _goo; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await new VerifyCS.Test + [Fact] + public async Task FieldIsRead_InDeconstruction_InParens() + { + var code = """ + class C { - TestState = { Sources = { source1, source2 } }, - FixedState = { Sources = { source1, source2 } }, - }.RunAsync(); - } + private int i; - [Fact] - public async Task FieldIsOnlyWritten_PartialClass_DifferentFile() - { - var source1 = """ - partial class MyClass - { - private int {|IDE0052:_goo|}; - } - """; - var source2 = """ - partial class MyClass + public void M() { - public void M() { _goo = 0; } + var x = ((i, 0), 0); } - """; + } + """; - await new VerifyCS.Test - { - TestState = { Sources = { source1, source2 } }, - FixedState = { Sources = { source1, source2 } }, - }.RunAsync(); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsRead_InParens() - { - var code = """ - class MyClass - { - private int _goo; - public int M() => (_goo); - } - """; + [Fact] + public async Task FieldInTypeWithGeneratedCode() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + private int [|i|]; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + private int j; - [Fact] - public async Task FieldIsWritten_InParens() - { - var code = """ - class MyClass + public void M() { - private int {|IDE0052:_goo|}; - public void M() { (_goo) = 1; } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } + } + """, + """ + class C + { + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + private int j; - [Fact] - public async Task FieldIsWritten_InParens_02() - { - var code = """ - class MyClass + public void M() { - private int {|IDE0052:_goo|}; - public int M() => (_goo) = 1; } - """; + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsGeneratedCode() + { + var code = """ + class C + { + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + private int i; - [Fact] - public async Task FieldIsRead_InDeconstruction_InParens() - { - var code = """ - class C + public void M() { - private int i; - - public void M() - { - var x = ((i, 0), 0); - } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldInTypeWithGeneratedCode() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C - { - private int [|i|]; + [Fact] + public async Task FieldUsedInGeneratedCode() + { + var code = """ + class C + { + private int i; - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - private int j; + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + public int M() => i; + } + """; - public void M() - { - } - } - """, - """ - class C - { - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - private int j; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - public void M() - { - } - } - """); - } + [Fact] + public async Task FieldIsUnusedInType_SyntaxError() + { + var code = """ + class C + { + private int i; - [Fact] - public async Task FieldIsGeneratedCode() - { - var code = """ - class C - { - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - private int i; + public int M() { return {|CS1525:=|} {|CS1525:;|} } + } + """; - public void M() - { - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsUnusedInType_SemanticError() + { + var code = """ + class C + { + private int i; - [Fact] - public async Task FieldUsedInGeneratedCode() - { - var code = """ - class C - { - private int i; + // 'ii' is undefined. + public int M() => {|CS0103:ii|}; + } + """; - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - public int M() => i; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task FieldIsUnusedInType_SemanticErrorInDifferentType() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + private int [|i|]; + } - [Fact] - public async Task FieldIsUnusedInType_SyntaxError() - { - var code = """ - class C - { - private int i; + class C2 + { + // 'ii' is undefined. + public int M() => {|CS0103:ii|}; + } + """, + """ + class C + { + } - public int M() { return {|CS1525:=|} {|CS1525:;|} } - } - """; + class C2 + { + // 'ii' is undefined. + public int M() => {|CS0103:ii|}; + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task StructLayoutAttribute_ExplicitLayout() + { + var code = """ + using System.Runtime.InteropServices; - [Fact] - public async Task FieldIsUnusedInType_SemanticError() - { - var code = """ - class C - { - private int i; + [StructLayoutAttribute(LayoutKind.Explicit)] + class C + { + [FieldOffset(0)] + private int i; - // 'ii' is undefined. - public int M() => {|CS0103:ii|}; - } - """; + [FieldOffset(4)] + private int i2; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FieldIsUnusedInType_SemanticErrorInDifferentType() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C - { - private int [|i|]; - } + [Fact] + public async Task StructLayoutAttribute_SequentialLayout() + { + var code = """ + using System.Runtime.InteropServices; - class C2 - { - // 'ii' is undefined. - public int M() => {|CS0103:ii|}; - } - """, - """ - class C - { - } + [StructLayoutAttribute(LayoutKind.Sequential)] + struct S + { + private int i; + private int i2; + } + """; - class C2 - { - // 'ii' is undefined. - public int M() => {|CS0103:ii|}; - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task StructLayoutAttribute_ExplicitLayout() - { - var code = """ - using System.Runtime.InteropServices; + [Fact] + public async Task DebuggerDisplayAttribute_OnType_ReferencesField() + { + var code = """ + [System.Diagnostics.DebuggerDisplayAttribute("{s}")] + class C + { + private string s; + } + """; - [StructLayoutAttribute(LayoutKind.Explicit)] - class C - { - [FieldOffset(0)] - private int i; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [FieldOffset(4)] - private int i2; - } - """; + [Fact] + public async Task DebuggerDisplayAttribute_OnType_ReferencesMethod() + { + var code = """ + [System.Diagnostics.DebuggerDisplayAttribute("{GetString()}")] + class C + { + private string GetString() => ""; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task StructLayoutAttribute_SequentialLayout() - { - var code = """ - using System.Runtime.InteropServices; + [Fact] + public async Task DebuggerDisplayAttribute_OnType_ReferencesProperty() + { + var code = """ + [System.Diagnostics.DebuggerDisplayAttribute("{MyString}")] + class C + { + private string MyString => ""; + } + """; - [StructLayoutAttribute(LayoutKind.Sequential)] - struct S - { - private int i; - private int i2; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task DebuggerDisplayAttribute_OnField_ReferencesField() + { + var code = """ + class C + { + private string s; - [Fact] - public async Task DebuggerDisplayAttribute_OnType_ReferencesField() - { - var code = """ [System.Diagnostics.DebuggerDisplayAttribute("{s}")] - class C - { - private string s; - } - """; + public int M; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task DebuggerDisplayAttribute_OnProperty_ReferencesMethod() + { + var code = """ + class C + { + private string GetString() => ""; - [Fact] - public async Task DebuggerDisplayAttribute_OnType_ReferencesMethod() - { - var code = """ [System.Diagnostics.DebuggerDisplayAttribute("{GetString()}")] - class C - { - private string GetString() => ""; - } - """; + public int M => 0; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task DebuggerDisplayAttribute_OnProperty_ReferencesProperty() + { + var code = """ + class C + { + private string MyString { get { return ""; } } - [Fact] - public async Task DebuggerDisplayAttribute_OnType_ReferencesProperty() - { - var code = """ [System.Diagnostics.DebuggerDisplayAttribute("{MyString}")] - class C - { - private string MyString => ""; - } - """; + public int M { get { return 0; } } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task DebuggerDisplayAttribute_OnNestedTypeMember_ReferencesField() + { + var code = """ + class C + { + private static string s; - [Fact] - public async Task DebuggerDisplayAttribute_OnField_ReferencesField() - { - var code = """ - class C + class Nested { - private string s; - - [System.Diagnostics.DebuggerDisplayAttribute("{s}")] + [System.Diagnostics.DebuggerDisplayAttribute("{C.s}")] public int M; } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task DebuggerDisplayAttribute_OnProperty_ReferencesMethod() - { - var code = """ - class C - { - private string GetString() => ""; + } + """; - [System.Diagnostics.DebuggerDisplayAttribute("{GetString()}")] - public int M => 0; - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30886")] + public async Task SerializableConstructor_TypeImplementsISerializable() + { + var code = """ + using System.Runtime.Serialization; - [Fact] - public async Task DebuggerDisplayAttribute_OnProperty_ReferencesProperty() - { - var code = """ - class C + class C : ISerializable + { + public C() { - private string MyString { get { return ""; } } - - [System.Diagnostics.DebuggerDisplayAttribute("{MyString}")] - public int M { get { return 0; } } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - [Fact] - public async Task DebuggerDisplayAttribute_OnNestedTypeMember_ReferencesField() - { - var code = """ - class C + private C(SerializationInfo info, StreamingContext context) { - private static string s; - - class Nested - { - [System.Diagnostics.DebuggerDisplayAttribute("{C.s}")] - public int M; - } } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30886")] - public async Task SerializableConstructor_TypeImplementsISerializable() - { - var code = """ - using System.Runtime.Serialization; - - class C : ISerializable + public void GetObjectData(SerializationInfo info, StreamingContext context) { - public C() - { - } - - private C(SerializationInfo info, StreamingContext context) - { - } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30886")] - public async Task SerializableConstructor_BaseTypeImplementsISerializable() - { - var code = """ - using System; - using System.Runtime.Serialization; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30886")] + public async Task SerializableConstructor_BaseTypeImplementsISerializable() + { + var code = """ + using System; + using System.Runtime.Serialization; - class C : Exception + class C : Exception + { + public C() { - public C() - { - } - - private C(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Theory] - [InlineData(@"[System.Runtime.Serialization.OnDeserializingAttribute]")] - [InlineData(@"[System.Runtime.Serialization.OnDeserializedAttribute]")] - [InlineData(@"[System.Runtime.Serialization.OnSerializingAttribute]")] - [InlineData(@"[System.Runtime.Serialization.OnSerializedAttribute]")] - [InlineData(@"[System.Runtime.InteropServices.ComRegisterFunctionAttribute]")] - [InlineData(@"[System.Runtime.InteropServices.ComUnregisterFunctionAttribute]")] - public async Task MethodsWithSpecialAttributes(string attribute) - { - var code = $$""" - class C + + private C(SerializationInfo info, StreamingContext context) + : base(info, context) { - {{attribute}} - private void M() - { - } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30887")] - public async Task ShouldSerializePropertyMethod() - { - var code = """ - class C + public void GetObjectData(SerializationInfo info, StreamingContext context) { - private bool ShouldSerializeData() - { - return true; - } - - public int Data { get; private set; } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38491")] - public async Task ResetPropertyMethod() - { - var code = """ - class C + [Theory] + [InlineData(@"[System.Runtime.Serialization.OnDeserializingAttribute]")] + [InlineData(@"[System.Runtime.Serialization.OnDeserializedAttribute]")] + [InlineData(@"[System.Runtime.Serialization.OnSerializingAttribute]")] + [InlineData(@"[System.Runtime.Serialization.OnSerializedAttribute]")] + [InlineData(@"[System.Runtime.InteropServices.ComRegisterFunctionAttribute]")] + [InlineData(@"[System.Runtime.InteropServices.ComUnregisterFunctionAttribute]")] + public async Task MethodsWithSpecialAttributes(string attribute) + { + var code = $$""" + class C + { + {{attribute}} + private void M() { - private void ResetData() - { - return; - } - - public int Data { get; private set; } } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30377")] - public async Task EventHandlerMethod() - { - var code = """ - using System; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30887")] + public async Task ShouldSerializePropertyMethod() + { + var code = """ + class C + { + private bool ShouldSerializeData() { - private void M(object o, EventArgs args) - { - } + return true; } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + public int Data { get; private set; } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32727")] - public async Task NestedStructLayoutTypeWithReference() - { - var code = """ - using System.Runtime.InteropServices; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38491")] + public async Task ResetPropertyMethod() + { + var code = """ + class C + { + private void ResetData() { - private const int MAX_PATH = 260; - - [StructLayout(LayoutKind.Sequential)] - internal struct ProcessEntry32 - { - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] - public string szExeFile; - } + return; } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } - - [Fact] - public async Task FixAllFields_Document() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|_goo|] = 0, [|_bar|]; - private int [|_x|] = 0, [|_y|], _z = 0; - private string [|_fizz|] = null; - public int Method() => _z; - } - """, - """ - class MyClass - { - private int _z = 0; + public int Data { get; private set; } + } + """; - public int Method() => _z; - } - """); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task FixAllMethods_Document() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|M1|]() => 0; - private void [|M2|]() { } - private static void [|M3|]() { } - private class NestedClass - { - private void [|M4|]() { } - } - } - """, - """ - class MyClass - { - private class NestedClass - { - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30377")] + public async Task EventHandlerMethod() + { + var code = """ + using System; - [Fact] - public async Task FixAllProperties_Document() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class MyClass - { - private int [|P1|] => 0; - private int [|P2|] { get; set; } - private int [|P3|] { get { return 0; } set { } } - private int [|this|][int i] { get { return 0; } } - } - """, - """ - class MyClass + class C + { + private void M(object o, EventArgs args) { } - """); - } + } + """; - [Fact] - public async Task FixAllEvents_Document() - { - await VerifyCS.VerifyCodeFixAsync( - """ - using System; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class MyClass - { - private event EventHandler [|E1|], E2 = null, [|E3|]; - private event EventHandler [|E4|], [|E5|] = null; - private event EventHandler [|E|] - { - add { } - remove { } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32727")] + public async Task NestedStructLayoutTypeWithReference() + { + var code = """ + using System.Runtime.InteropServices; - public void M() - { - EventHandler handler = E2; - } - } - """, - """ - using System; + class Program + { + private const int MAX_PATH = 260; - class MyClass + [StructLayout(LayoutKind.Sequential)] + internal struct ProcessEntry32 { - private event EventHandler E2 = null; - - public void M() - { - EventHandler handler = E2; - } + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] + public string szExeFile; } - """); - } + } + """; - [Fact] - public async Task FixAllMembers_Project() - { - var source1 = """ - using System; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - partial class MyClass - { - private int [|f1|], f2 = 0, [|f3|]; - private void [|M1|]() { } - private int [|P1|] => 0; - private int [|this|][int x] { get { return 0; } set { } } - private event EventHandler [|e1|], [|e2|] = null; - } + [Fact] + public async Task FixAllFields_Document() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|_goo|] = 0, [|_bar|]; + private int [|_x|] = 0, [|_y|], _z = 0; + private string [|_fizz|] = null; + + public int Method() => _z; + } + """, + """ + class MyClass + { + private int _z = 0; + + public int Method() => _z; + } + """); + } - class MyClass2 + [Fact] + public async Task FixAllMethods_Document() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|M1|]() => 0; + private void [|M2|]() { } + private static void [|M3|]() { } + private class NestedClass { - private void [|M2|]() { } + private void [|M4|]() { } } - """; - var source2 = """ - partial class MyClass + } + """, + """ + class MyClass + { + private class NestedClass { - private void [|M3|]() { } - public int M4() => f2; } + } + """); + } - static class MyClass3 - { - private static void [|M5|]() { } - } - """; - var fixedSource1 = """ - using System; + [Fact] + public async Task FixAllProperties_Document() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class MyClass + { + private int [|P1|] => 0; + private int [|P2|] { get; set; } + private int [|P3|] { get { return 0; } set { } } + private int [|this|][int i] { get { return 0; } } + } + """, + """ + class MyClass + { + } + """); + } - partial class MyClass - { - private int f2 = 0; - } + [Fact] + public async Task FixAllEvents_Document() + { + await VerifyCS.VerifyCodeFixAsync( + """ + using System; - class MyClass2 - { - } - """; - var fixedSource2 = """ - partial class MyClass + class MyClass + { + private event EventHandler [|E1|], E2 = null, [|E3|]; + private event EventHandler [|E4|], [|E5|] = null; + private event EventHandler [|E|] { - public int M4() => f2; + add { } + remove { } } - static class MyClass3 + public void M() { + EventHandler handler = E2; } - """; + } + """, + """ + using System; - await new VerifyCS.Test + class MyClass { - TestState = { Sources = { source1, source2 } }, - FixedState = { Sources = { fixedSource1, fixedSource2 } }, - }.RunAsync(); - } + private event EventHandler E2 = null; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32702")] - public async Task UsedExtensionMethod_ReferencedFromPartialMethod() - { - var source1 = """ - static partial class B + public void M() { - public static void Entry() => PartialMethod(); - static partial void PartialMethod(); + EventHandler handler = E2; } - """; - var source2 = """ - static partial class B - { - static partial void PartialMethod() - { - UsedMethod(); - } + } + """); + } - private static void UsedMethod() { } - } - """; + [Fact] + public async Task FixAllMembers_Project() + { + var source1 = """ + using System; - await new VerifyCS.Test + partial class MyClass { - TestState = { Sources = { source1, source2 } }, - FixedState = { Sources = { source1, source2 } }, - }.RunAsync(); - } + private int [|f1|], f2 = 0, [|f3|]; + private void [|M1|]() { } + private int [|P1|] => 0; + private int [|this|][int x] { get { return 0; } set { } } + private event EventHandler [|e1|], [|e2|] = null; + } + + class MyClass2 + { + private void [|M2|]() { } + } + """; + var source2 = """ + partial class MyClass + { + private void [|M3|]() { } + public int M4() => f2; + } - [Fact] - public async Task UsedExtensionMethod_ReferencedFromExtendedPartialMethod() - { - var source1 = """ - static partial class B - { - public static void Entry() => PartialMethod(); - public static partial void PartialMethod(); - } - """; - var source2 = """ - static partial class B - { - public static partial void PartialMethod() - { - UsedMethod(); - } + static class MyClass3 + { + private static void [|M5|]() { } + } + """; + var fixedSource1 = """ + using System; - private static void UsedMethod() { } - } - """; + partial class MyClass + { + private int f2 = 0; + } + + class MyClass2 + { + } + """; + var fixedSource2 = """ + partial class MyClass + { + public int M4() => f2; + } - await new VerifyCS.Test + static class MyClass3 { - TestState = { Sources = { source1, source2 } }, - FixedState = { Sources = { source1, source2 } }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32842")] - public async Task FieldIsRead_NullCoalesceAssignment() + await new VerifyCS.Test { - var code = """ - public class MyClass + TestState = { Sources = { source1, source2 } }, + FixedState = { Sources = { fixedSource1, fixedSource2 } }, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32702")] + public async Task UsedExtensionMethod_ReferencedFromPartialMethod() + { + var source1 = """ + static partial class B + { + public static void Entry() => PartialMethod(); + static partial void PartialMethod(); + } + """; + var source2 = """ + static partial class B + { + static partial void PartialMethod() { - private MyClass _field; - public MyClass Property => _field ??= new MyClass(); + UsedMethod(); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + private static void UsedMethod() { } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32842")] - [WorkItem("https://github.com/dotnet/roslyn/issues/66975")] - public async Task FieldIsNotRead_NullCoalesceAssignment() + await new VerifyCS.Test { - var code = """ - public class MyClass + TestState = { Sources = { source1, source2 } }, + FixedState = { Sources = { source1, source2 } }, + }.RunAsync(); + } + + [Fact] + public async Task UsedExtensionMethod_ReferencedFromExtendedPartialMethod() + { + var source1 = """ + static partial class B + { + public static void Entry() => PartialMethod(); + public static partial void PartialMethod(); + } + """; + var source2 = """ + static partial class B + { + public static partial void PartialMethod() { - private MyClass _field; - public void M() => _field ??= new MyClass(); + UsedMethod(); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + private static void UsedMethod() { } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37213")] - public async Task UsedPrivateExtensionMethod() + await new VerifyCS.Test { - var code = """ - public static class B - { - public static void PublicExtensionMethod(this string s) => s.PrivateExtensionMethod(); - private static void PrivateExtensionMethod(this string s) { } - } - """; + TestState = { Sources = { source1, source2 } }, + FixedState = { Sources = { source1, source2 } }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32842")] + public async Task FieldIsRead_NullCoalesceAssignment() + { + var code = """ + public class MyClass + { + private MyClass _field; + public MyClass Property => _field ??= new MyClass(); + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30884")] - public async Task TestMessageForConstructor() - { - await VerifyCS.VerifyAnalyzerAsync( - """ - class C - { - private C(int i) { } - } - """, - // /0/Test0.cs(3,13): info IDE0051: Private member 'C.C' is unused - VerifyCS.Diagnostic("IDE0051").WithSpan(3, 13, 3, 14).WithArguments("C.C")); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32842")] + [WorkItem("https://github.com/dotnet/roslyn/issues/66975")] + public async Task FieldIsNotRead_NullCoalesceAssignment() + { + var code = """ + public class MyClass + { + private MyClass _field; + public void M() => _field ??= new MyClass(); + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62856")] - public async Task DontWarnForAwaiterMethods() - { - const string code = """ - using System; - using System.Runtime.CompilerServices; - using System.Threading.Tasks; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - class C : ICriticalNotifyCompletion - { - public async Task M() - { - await this; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37213")] + public async Task UsedPrivateExtensionMethod() + { + var code = """ + public static class B + { + public static void PublicExtensionMethod(this string s) => s.PrivateExtensionMethod(); + private static void PrivateExtensionMethod(this string s) { } + } + """; - private C GetAwaiter() => this; - private bool IsCompleted => false; - private void GetResult() { } - public void OnCompleted(Action continuation) => Task.Run(continuation); - public void UnsafeOnCompleted(Action continuation) => Task.Run(continuation); - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyAnalyzerAsync(code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/30884")] + public async Task TestMessageForConstructor() + { + await VerifyCS.VerifyAnalyzerAsync( + """ + class C + { + private C(int i) { } + } + """, +// /0/Test0.cs(3,13): info IDE0051: Private member 'C.C' is unused +VerifyCS.Diagnostic("IDE0051").WithSpan(3, 13, 3, 14).WithArguments("C.C")); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62856")] - public async Task WarnForAwaiterMethodsNotImplementingInterface() - { - const string code = """ - using System; - using System.Runtime.CompilerServices; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62856")] + public async Task DontWarnForAwaiterMethods() + { + const string code = """ + using System; + using System.Runtime.CompilerServices; + using System.Threading.Tasks; - class C + class C : ICriticalNotifyCompletion + { + public async Task M() { - private C [|GetAwaiter|]() => this; - private bool [|IsCompleted|] => false; - private void [|GetResult|]() { } - public void OnCompleted(Action continuation) => Task.Run(continuation); - public void UnsafeOnCompleted(Action continuation) => Task.Run(continuation); + await this; } - """; - const string fixedCode = """ - using System; - using System.Runtime.CompilerServices; - using System.Threading.Tasks; - class C - { - public void OnCompleted(Action continuation) => Task.Run(continuation); - public void UnsafeOnCompleted(Action continuation) => Task.Run(continuation); - } - """; + private C GetAwaiter() => this; + private bool IsCompleted => false; + private void GetResult() { } + public void OnCompleted(Action continuation) => Task.Run(continuation); + public void UnsafeOnCompleted(Action continuation) => Task.Run(continuation); + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62856")] + public async Task WarnForAwaiterMethodsNotImplementingInterface() + { + const string code = """ + using System; + using System.Runtime.CompilerServices; + using System.Threading.Tasks; + + class C + { + private C [|GetAwaiter|]() => this; + private bool [|IsCompleted|] => false; + private void [|GetResult|]() { } + public void OnCompleted(Action continuation) => Task.Run(continuation); + public void UnsafeOnCompleted(Action continuation) => Task.Run(continuation); + } + """; + const string fixedCode = """ + using System; + using System.Runtime.CompilerServices; + using System.Threading.Tasks; + + class C + { + public void OnCompleted(Action continuation) => Task.Run(continuation); + public void UnsafeOnCompleted(Action continuation) => Task.Run(continuation); + } + """; - await VerifyCS.VerifyCodeFixAsync(code, fixedCode); - } + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedParametersTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedParametersTests.cs index bf7a305de685f..d609103963861 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedParametersTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedParametersTests.cs @@ -18,1907 +18,1906 @@ using Xunit.Abstractions; using static Roslyn.Test.Utilities.TestHelpers; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedParameters)] +public class RemoveUnusedParametersTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedParameters)] - public class RemoveUnusedParametersTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor - { - public RemoveUnusedParametersTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpRemoveUnusedParametersAndValuesDiagnosticAnalyzer(), new CSharpRemoveUnusedValuesCodeFixProvider()); - - private OptionsCollection NonPublicMethodsOnly - => Option(CodeStyleOptions2.UnusedParameters, - new CodeStyleOption2(UnusedParametersPreference.NonPublicMethods, NotificationOption2.Suggestion)); - - // Ensure that we explicitly test missing UnusedParameterDiagnosticId, which has no corresponding code fix (non-fixable diagnostic). - private Task TestDiagnosticMissingAsync(string initialMarkup, ParseOptions? parseOptions = null) - => TestDiagnosticMissingAsync(initialMarkup, options: null, parseOptions); - private Task TestDiagnosticsAsync(string initialMarkup, params DiagnosticDescription[] expectedDiagnostics) - => TestDiagnosticsAsync(initialMarkup, options: null, parseOptions: null, expectedDiagnostics); - private Task TestDiagnosticMissingAsync(string initialMarkup, OptionsCollection? options, ParseOptions? parseOptions = null) - => TestDiagnosticMissingAsync(initialMarkup, new TestParameters(parseOptions, options: options, retainNonFixableDiagnostics: true)); - private Task TestDiagnosticsAsync(string initialMarkup, OptionsCollection options, params DiagnosticDescription[] expectedDiagnostics) - => TestDiagnosticsAsync(initialMarkup, options, parseOptions: null, expectedDiagnostics); - private Task TestDiagnosticsAsync(string initialMarkup, OptionsCollection? options, ParseOptions? parseOptions, params DiagnosticDescription[] expectedDiagnostics) - => TestDiagnosticsAsync(initialMarkup, new TestParameters(parseOptions, options: options, retainNonFixableDiagnostics: true), expectedDiagnostics); - - [Fact] - public async Task Parameter_Used() - { - await TestDiagnosticMissingAsync( - """ - class C - { - void M(int [|p|]) - { - var x = p; - } + public RemoveUnusedParametersTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpRemoveUnusedParametersAndValuesDiagnosticAnalyzer(), new CSharpRemoveUnusedValuesCodeFixProvider()); + + private OptionsCollection NonPublicMethodsOnly + => Option(CodeStyleOptions2.UnusedParameters, + new CodeStyleOption2(UnusedParametersPreference.NonPublicMethods, NotificationOption2.Suggestion)); + + // Ensure that we explicitly test missing UnusedParameterDiagnosticId, which has no corresponding code fix (non-fixable diagnostic). + private Task TestDiagnosticMissingAsync(string initialMarkup, ParseOptions? parseOptions = null) + => TestDiagnosticMissingAsync(initialMarkup, options: null, parseOptions); + private Task TestDiagnosticsAsync(string initialMarkup, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, options: null, parseOptions: null, expectedDiagnostics); + private Task TestDiagnosticMissingAsync(string initialMarkup, OptionsCollection? options, ParseOptions? parseOptions = null) + => TestDiagnosticMissingAsync(initialMarkup, new TestParameters(parseOptions, options: options, retainNonFixableDiagnostics: true)); + private Task TestDiagnosticsAsync(string initialMarkup, OptionsCollection options, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, options, parseOptions: null, expectedDiagnostics); + private Task TestDiagnosticsAsync(string initialMarkup, OptionsCollection? options, ParseOptions? parseOptions, params DiagnosticDescription[] expectedDiagnostics) + => TestDiagnosticsAsync(initialMarkup, new TestParameters(parseOptions, options: options, retainNonFixableDiagnostics: true), expectedDiagnostics); + + [Fact] + public async Task Parameter_Used() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int [|p|]) + { + var x = p; } - """); - } + } + """); + } - [Fact] - public async Task Parameter_Unused() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task Parameter_Unused() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int [|p|]) { - void M(int [|p|]) - { - } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Theory] - [InlineData("public", "public")] - [InlineData("public", "protected")] - public async Task Parameter_Unused_NonPrivate_NotApplicable(string typeAccessibility, string methodAccessibility) - { - await TestDiagnosticMissingAsync( - $$""" - {{typeAccessibility}} class C + [Theory] + [InlineData("public", "public")] + [InlineData("public", "protected")] + public async Task Parameter_Unused_NonPrivate_NotApplicable(string typeAccessibility, string methodAccessibility) + { + await TestDiagnosticMissingAsync( + $$""" + {{typeAccessibility}} class C + { + {{methodAccessibility}} void M(int [|p|]) { - {{methodAccessibility}} void M(int [|p|]) - { - } } - """, NonPublicMethodsOnly); - } - - [Theory] - [InlineData("public", "private")] - [InlineData("public", "internal")] - [InlineData("internal", "private")] - [InlineData("internal", "public")] - [InlineData("internal", "internal")] - [InlineData("internal", "protected")] - public async Task Parameter_Unused_NonPublicMethod(string typeAccessibility, string methodAccessibility) - { - await TestDiagnosticsAsync( - $$""" - {{typeAccessibility}} class C - { - {{methodAccessibility}} void M(int [|p|]) - { - } + } + """, NonPublicMethodsOnly); + } + + [Theory] + [InlineData("public", "private")] + [InlineData("public", "internal")] + [InlineData("internal", "private")] + [InlineData("internal", "public")] + [InlineData("internal", "internal")] + [InlineData("internal", "protected")] + public async Task Parameter_Unused_NonPublicMethod(string typeAccessibility, string methodAccessibility) + { + await TestDiagnosticsAsync( + $$""" + {{typeAccessibility}} class C + { + {{methodAccessibility}} void M(int [|p|]) + { } - """, NonPublicMethodsOnly, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, NonPublicMethodsOnly, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task Parameter_Unused_UnusedExpressionAssignment_PreferNone() - { - var unusedValueAssignmentOptionSuppressed = Option(CSharpCodeStyleOptions.UnusedValueAssignment, - new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.None)); + [Fact] + public async Task Parameter_Unused_UnusedExpressionAssignment_PreferNone() + { + var unusedValueAssignmentOptionSuppressed = Option(CSharpCodeStyleOptions.UnusedValueAssignment, + new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.None)); - await TestDiagnosticMissingAsync( - """ - class C + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int [|p|]) { - void M(int [|p|]) - { - var x = p; - } + var x = p; } - """, options: unusedValueAssignmentOptionSuppressed); - } + } + """, options: unusedValueAssignmentOptionSuppressed); + } - [Fact] - public async Task Parameter_WrittenOnly() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task Parameter_WrittenOnly() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int [|p|]) { - void M(int [|p|]) - { - p = 1; - } + p = 1; } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } + + [Fact] + public async Task Parameter_WrittenThenRead() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int [|p|]) + { + p = 1; + var x = p; + } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task Parameter_WrittenThenRead() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task Parameter_WrittenOnAllControlPaths_BeforeRead() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int [|p|], bool flag) { - void M(int [|p|]) + if (flag) { - p = 1; - var x = p; + p = 0; } - } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - - [Fact] - public async Task Parameter_WrittenOnAllControlPaths_BeforeRead() - { - await TestDiagnosticsAsync( - """ - class C - { - void M(int [|p|], bool flag) + else { - if (flag) - { - p = 0; - } - else - { - p = 1; - } - - var x = p; + p = 1; } + + var x = p; } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task Parameter_WrittenOnSomeControlPaths_BeforeRead() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task Parameter_WrittenOnSomeControlPaths_BeforeRead() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int [|p|], bool flag, bool flag2) { - void M(int [|p|], bool flag, bool flag2) + if (flag) { - if (flag) - { - if (flag2) - { - p = 0; - } - } - else + if (flag2) { - p = 1; + p = 0; } - - var x = p; } - } - """); - } - - [Fact] - public async Task OptionalParameter_Unused() - { - await TestDiagnosticsAsync( - """ - class C - { - void M(int [|p|] = 0) + else { + p = 1; } - } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - [Fact] - public async Task Parameter_UsedInConstructorInitializerOnly() - { - await TestDiagnosticMissingAsync( - """ - class B - { - protected B(int p) { } + var x = p; } + } + """); + } - class C: B + [Fact] + public async Task OptionalParameter_Unused() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int [|p|] = 0) { - C(int [|p|]) - : base(p) - { - } } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task Parameter_NotUsedInConstructorInitializer_UsedInConstructorBody() - { - await TestDiagnosticMissingAsync( - """ - class B - { - protected B(int p) { } - } + [Fact] + public async Task Parameter_UsedInConstructorInitializerOnly() + { + await TestDiagnosticMissingAsync( + """ + class B + { + protected B(int p) { } + } - class C: B + class C: B + { + C(int [|p|]) + : base(p) { - C(int [|p|]) - : base(0) - { - var x = p; - } } - """); - } + } + """); + } - [Fact] - public async Task Parameter_UsedInConstructorInitializerAndConstructorBody() - { - await TestDiagnosticMissingAsync( - """ - class B - { - protected B(int p) { } - } + [Fact] + public async Task Parameter_NotUsedInConstructorInitializer_UsedInConstructorBody() + { + await TestDiagnosticMissingAsync( + """ + class B + { + protected B(int p) { } + } + + class C: B + { + C(int [|p|]) + : base(0) + { + var x = p; + } + } + """); + } - class C: B - { - C(int [|p|]) - : base(p) - { - var x = p; - } - } - """); - } + [Fact] + public async Task Parameter_UsedInConstructorInitializerAndConstructorBody() + { + await TestDiagnosticMissingAsync( + """ + class B + { + protected B(int p) { } + } + + class C: B + { + C(int [|p|]) + : base(p) + { + var x = p; + } + } + """); + } - [Fact] - public async Task UnusedLocalFunctionParameter() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task UnusedLocalFunctionParameter() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int y) { - void M(int y) + LocalFunction(y); + void LocalFunction(int [|p|]) { - LocalFunction(y); - void LocalFunction(int [|p|]) - { - } } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task UnusedLocalFunctionParameter_02() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task UnusedLocalFunctionParameter_02() + { + await TestDiagnosticsAsync( + """ + class C + { + void M() { - void M() + LocalFunction(0); + void LocalFunction(int [|p|]) { - LocalFunction(0); - void LocalFunction(int [|p|]) - { - } } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task UnusedLocalFunctionParameter_Discard() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task UnusedLocalFunctionParameter_Discard() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M() { - void M() + LocalFunction(0); + void LocalFunction(int [|_|]) { - LocalFunction(0); - void LocalFunction(int [|_|]) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task UnusedLocalFunctionParameter_PassedAsDelegateArgument() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact] + public async Task UnusedLocalFunctionParameter_PassedAsDelegateArgument() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + M2(LocalFunction); + void LocalFunction(int [|p|]) { - M2(LocalFunction); - void LocalFunction(int [|p|]) - { - } } - - void M2(Action a) => a(0); } - """); - } - [Fact] - public async Task UsedInLambda_ReturnsDelegate() - { - // Currently we bail out from analysis for method returning delegate types. - await TestDiagnosticMissingAsync( - """ - using System; + void M2(Action a) => a(0); + } + """); + } + + [Fact] + public async Task UsedInLambda_ReturnsDelegate() + { + // Currently we bail out from analysis for method returning delegate types. + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + private static Action M(object [|p|] = null, Action myDelegate) { - private static Action M(object [|p|] = null, Action myDelegate) - { - return d => { myDelegate(p); }; - } + return d => { myDelegate(p); }; } - """); - } + } + """); + } - [Fact] - public async Task UnusedInLambda_ReturnsDelegate() - { - // We bail out from unused value analysis for method returning delegate types. - // We should still report unused parameters. - await TestDiagnosticsAsync( - """ - using System; + [Fact] + public async Task UnusedInLambda_ReturnsDelegate() + { + // We bail out from unused value analysis for method returning delegate types. + // We should still report unused parameters. + await TestDiagnosticsAsync( + """ + using System; - class C + class C + { + private static Action M(object [|p|]) { - private static Action M(object [|p|]) - { - return () => { }; - } + return () => { }; } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task UnusedInLambda_LambdaPassedAsArgument() - { - // We bail out from unused value analysis when lambda is passed as argument. - // We should still report unused parameters. - await TestDiagnosticsAsync( - """ - using System; + [Fact] + public async Task UnusedInLambda_LambdaPassedAsArgument() + { + // We bail out from unused value analysis when lambda is passed as argument. + // We should still report unused parameters. + await TestDiagnosticsAsync( + """ + using System; - class C + class C + { + private static void M(object [|p|]) { - private static void M(object [|p|]) - { - M2(() => { }); - } - - private static void M2(Action a) { } + M2(() => { }); } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - [Fact] - public async Task ReadInLambda_LambdaPassedAsArgument() - { - await TestDiagnosticMissingAsync( - """ - using System; + private static void M2(Action a) { } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } + + [Fact] + public async Task ReadInLambda_LambdaPassedAsArgument() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + private static void M(object [|p|]) { - private static void M(object [|p|]) - { - M2(() => { M3(p); }); - } + M2(() => { M3(p); }); + } - private static void M2(Action a) { } + private static void M2(Action a) { } - private static void M3(object o) { } - } - """); - } + private static void M3(object o) { } + } + """); + } - [Fact] - public async Task OnlyWrittenInLambda_LambdaPassedAsArgument() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact] + public async Task OnlyWrittenInLambda_LambdaPassedAsArgument() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + private static void M(object [|p|]) { - private static void M(object [|p|]) - { - M2(() => { M3(out p); }); - } + M2(() => { M3(out p); }); + } - private static void M2(Action a) { } + private static void M2(Action a) { } - private static void M3(out object o) { o = null; } - } - """); - } + private static void M3(out object o) { o = null; } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] - public async Task UnusedInExpressionTree_PassedAsArgument() - { - await TestDiagnosticsAsync( - """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] + public async Task UnusedInExpressionTree_PassedAsArgument() + { + await TestDiagnosticsAsync( + """ + using System; + using System.Linq.Expressions; - class C + class C + { + public static void M1(object [|p|]) { - public static void M1(object [|p|]) - { - M2(x => x.M3()); - } - - private static C M2(Expression> a) { return null; } - private int M3() { return 0; } + M2(x => x.M3()); } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] - public async Task ReadInExpressionTree_PassedAsArgument() - { - await TestDiagnosticMissingAsync( - """ - using System; - using System.Linq.Expressions; + private static C M2(Expression> a) { return null; } + private int M3() { return 0; } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - class C - { - public static void M1(object [|p|]) - { - M2(x => x.M3(p)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] + public async Task ReadInExpressionTree_PassedAsArgument() + { + await TestDiagnosticMissingAsync( + """ + using System; + using System.Linq.Expressions; - private static C M2(Expression> a) { return null; } - private int M3(object o) { return 0; } + class C + { + public static void M1(object [|p|]) + { + M2(x => x.M3(p)); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] - public async Task OnlyWrittenInExpressionTree_PassedAsArgument() - { - await TestDiagnosticMissingAsync( - """ - using System; - using System.Linq.Expressions; + private static C M2(Expression> a) { return null; } + private int M3(object o) { return 0; } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] + public async Task OnlyWrittenInExpressionTree_PassedAsArgument() + { + await TestDiagnosticMissingAsync( + """ + using System; + using System.Linq.Expressions; - class C + class C + { + public static void M1(object [|p|]) { - public static void M1(object [|p|]) - { - M2(x => x.M3(out p)); - } - - private static C M2(Expression> a) { return null; } - private int M3(out object o) { o = null; return 0; } + M2(x => x.M3(out p)); } - """); - } - [Fact] - public async Task UsedInLambda_AssignedToField() - { - // Currently we bail out from analysis if we have a delegate creation that is not assigned - // too a local/parameter. - await TestDiagnosticMissingAsync( - """ - using System; + private static C M2(Expression> a) { return null; } + private int M3(out object o) { o = null; return 0; } + } + """); + } + + [Fact] + public async Task UsedInLambda_AssignedToField() + { + // Currently we bail out from analysis if we have a delegate creation that is not assigned + // too a local/parameter. + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + private Action _field; + private static void M(object [|p|]) { - private Action _field; - private static void M(object [|p|]) - { - _field = () => { Console.WriteLine(p); }; - } + _field = () => { Console.WriteLine(p); }; } - """); - } + } + """); + } + + [Fact] + public async Task MethodWithLockAndControlFlow() + { + await TestDiagnosticMissingAsync( + """ + using System; - [Fact] - public async Task MethodWithLockAndControlFlow() - { - await TestDiagnosticMissingAsync( - """ - using System; + class C + { + private static readonly object s_gate = new object(); - class C + public static C M(object [|p|], bool flag, C c1, C c2) { - private static readonly object s_gate = new object(); - - public static C M(object [|p|], bool flag, C c1, C c2) + C c; + lock (s_gate) { - C c; - lock (s_gate) - { - c = flag > 0 ? c1 : c2; - } - - c.M2(p); - return c; + c = flag > 0 ? c1 : c2; } - private void M2(object p) { } + c.M2(p); + return c; } - """); - } - [Fact] - public async Task UnusedLambdaParameter() - { - await TestDiagnosticMissingAsync( - """ - using System; + private void M2(object p) { } + } + """); + } + + [Fact] + public async Task UnusedLambdaParameter() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M(int y) { - void M(int y) + Action myLambda = [|p|] => { - Action myLambda = [|p|] => - { - }; + }; - myLambda(y); - } + myLambda(y); } - """); - } + } + """); + } - [Fact] - public async Task UnusedLambdaParameter_Discard() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact] + public async Task UnusedLambdaParameter_Discard() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M(int y) { - void M(int y) + Action myLambda = [|_|] => { - Action myLambda = [|_|] => - { - }; + }; - myLambda(y); - } + myLambda(y); } - """); - } + } + """); + } - [Fact] - public async Task UnusedLambdaParameter_DiscardTwo() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact] + public async Task UnusedLambdaParameter_DiscardTwo() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M(int y) { - void M(int y) + Action myLambda = ([|_|], _) => { - Action myLambda = ([|_|], _) => - { - }; + }; - myLambda(y, y); - } + myLambda(y, y); } - """); - } + } + """); + } - [Fact] - public async Task UnusedLocalFunctionParameter_DiscardTwo() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact] + public async Task UnusedLocalFunctionParameter_DiscardTwo() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M(int y) { - void M(int y) + void local([|_|], _) { - void local([|_|], _) - { - } - - local(y, y); } + + local(y, y); } - """); - } + } + """); + } - [Fact] - public async Task UnusedMethodParameter_DiscardTwo() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact] + public async Task UnusedMethodParameter_DiscardTwo() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M([|_|], _) { - void M([|_|], _) - { - } - - void M2(int y) - { - M(y, y); - } } - """); - } - [Fact] - public async Task UsedLocalFunctionParameter() - { - await TestDiagnosticMissingAsync( - """ - class C + void M2(int y) { - void M(int y) - { - LocalFunction(y); - void LocalFunction(int [|p|]) - { - var x = p; - } - } + M(y, y); } - """); - } - - [Fact] - public async Task UsedLambdaParameter() - { - await TestDiagnosticMissingAsync( - """ - using System; + } + """); + } - class C + [Fact] + public async Task UsedLocalFunctionParameter() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int y) { - void M(int y) + LocalFunction(y); + void LocalFunction(int [|p|]) { - Action myLambda = [|p|] => - { - var x = p; - } - - myLambda(y); + var x = p; } } - """); - } + } + """); + } + + [Fact] + public async Task UsedLambdaParameter() + { + await TestDiagnosticMissingAsync( + """ + using System; - [Fact] - public async Task OptionalParameter_Used() - { - await TestDiagnosticMissingAsync( - """ - class C + class C + { + void M(int y) { - void M(int [|p = 0|]) + Action myLambda = [|p|] => { var x = p; } + + myLambda(y); } - """); - } + } + """); + } - [Fact] - public async Task InParameter() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task OptionalParameter_Used() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int [|p = 0|]) { - void M(in int [|p|]) - { - } + var x = p; } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """); + } - [Fact] - public async Task RefParameter_Unused() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task InParameter() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(in int [|p|]) { - void M(ref int [|p|]) - { - } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task RefParameter_WrittenOnly() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task RefParameter_Unused() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(ref int [|p|]) { - void M(ref int [|p|]) - { - p = 0; - } } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task RefParameter_ReadOnly() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task RefParameter_WrittenOnly() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(ref int [|p|]) { - void M(ref int [|p|]) - { - var x = p; - } + p = 0; } - """); - } + } + """); + } - [Fact] - public async Task RefParameter_ReadThenWritten() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task RefParameter_ReadOnly() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(ref int [|p|]) { - void M(ref int [|p|]) - { - var x = p; - p = 1; - } + var x = p; } - """); - } + } + """); + } - [Fact] - public async Task RefParameter_WrittenAndThenRead() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task RefParameter_ReadThenWritten() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(ref int [|p|]) { - void M(ref int [|p|]) - { - p = 1; - var x = p; - } + var x = p; + p = 1; } - """); - } + } + """); + } - [Fact] - public async Task RefParameter_WrittenTwiceNotRead() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task RefParameter_WrittenAndThenRead() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(ref int [|p|]) { - void M(ref int [|p|]) - { - p = 0; - p = 1; - } + p = 1; + var x = p; } - """); - } + } + """); + } - [Fact] - public async Task OutParameter_Unused() - { - await TestDiagnosticsAsync( - """ - class C + [Fact] + public async Task RefParameter_WrittenTwiceNotRead() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(ref int [|p|]) { - void M(out int [|p|]) - { - } + p = 0; + p = 1; } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """); + } - [Fact] - public async Task OutParameter_WrittenOnly() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task OutParameter_Unused() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(out int [|p|]) { - void M(out int [|p|]) - { - p = 0; - } } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact] - public async Task OutParameter_WrittenAndThenRead() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task OutParameter_WrittenOnly() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(out int [|p|]) { - void M(out int [|p|]) - { - p = 0; - var x = p; - } + p = 0; } - """); - } + } + """); + } - [Fact] - public async Task OutParameter_WrittenTwiceNotRead() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task OutParameter_WrittenAndThenRead() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(out int [|p|]) { - void M(out int [|p|]) - { - p = 0; - p = 1; - } + p = 0; + var x = p; } - """); - } + } + """); + } - [Fact] - public async Task Parameter_ExternMethod() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task OutParameter_WrittenTwiceNotRead() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(out int [|p|]) { - [System.Runtime.InteropServices.DllImport(nameof(M))] - static extern void M(int [|p|]); + p = 0; + p = 1; } - """); - } + } + """); + } + + [Fact] + public async Task Parameter_ExternMethod() + { + await TestDiagnosticMissingAsync( + """ + class C + { + [System.Runtime.InteropServices.DllImport(nameof(M))] + static extern void M(int [|p|]); + } + """); + } - [Fact] - public async Task Parameter_AbstractMethod() - { - await TestDiagnosticMissingAsync( - """ - abstract class C + [Fact] + public async Task Parameter_AbstractMethod() + { + await TestDiagnosticMissingAsync( + """ + abstract class C + { + protected abstract void M(int [|p|]); + } + """); + } + + [Fact] + public async Task Parameter_VirtualMethod() + { + await TestDiagnosticMissingAsync( + """ + class C + { + protected virtual void M(int [|p|]) { - protected abstract void M(int [|p|]); } - """); - } + } + """); + } - [Fact] - public async Task Parameter_VirtualMethod() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task Parameter_OverriddenMethod() + { + await TestDiagnosticMissingAsync( + """ + class C + { + protected virtual void M(int p) { - protected virtual void M(int [|p|]) - { - } + var x = p; } - """); - } + } - [Fact] - public async Task Parameter_OverriddenMethod() - { - await TestDiagnosticMissingAsync( - """ - class C + class D : C + { + protected override void M(int [|p|]) { - protected virtual void M(int p) - { - var x = p; - } } + } + """); + } + + [Fact] + public async Task Parameter_ImplicitInterfaceImplementationMethod() + { + await TestDiagnosticMissingAsync( + """ + interface I + { + void M(int p); + } + class C: I + { + public void M(int [|p|]) + { + } + } + """); + } + + [Fact] + public async Task Parameter_ExplicitInterfaceImplementationMethod() + { + await TestDiagnosticMissingAsync( + """ + interface I + { + void M(int p); + } + class C: I + { + void I.M(int [|p|]) + { + } + } + """); + } - class D : C + [Fact] + public async Task Parameter_IndexerMethod() + { + await TestDiagnosticMissingAsync( + """ + class C + { + int this[int [|p|]] { - protected override void M(int [|p|]) - { - } + get { return 0; } } - """); - } + } + """); + } - [Fact] - public async Task Parameter_ImplicitInterfaceImplementationMethod() - { - await TestDiagnosticMissingAsync( - """ - interface I + [Fact] + public async Task Parameter_ConditionalDirective() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int [|p|]) + { + #if DEBUG + System.Console.WriteLine(p); + #endif + } + } + """); + } + + [Fact] + public async Task Parameter_EventHandler_FirstParameter() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public void MyHandler(object [|obj|], System.EventArgs args) { - void M(int p); } - class C: I + } + """); + } + + [Fact] + public async Task Parameter_EventHandler_SecondParameter() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public void MyHandler(object obj, System.EventArgs [|args|]) { - public void M(int [|p|]) - { - } } - """); - } + } + """); + } + + [Fact] + public async Task Parameter_MethodUsedAsEventHandler() + { + await TestDiagnosticMissingAsync( + """ + using System; + + public delegate void MyDelegate(int x); + + class C + { + private event MyDelegate myDel; - [Fact] - public async Task Parameter_ExplicitInterfaceImplementationMethod() - { - await TestDiagnosticMissingAsync( - """ - interface I + void M(C c) { - void M(int p); + c.myDel += Handler; } - class C: I + + void Handler(int [|x|]) { - void I.M(int [|p|]) - { - } } - """); - } + } + """); + } - [Fact] - public async Task Parameter_IndexerMethod() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact] + public async Task Parameter_CustomEventArgs() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public class CustomEventArgs : System.EventArgs { - int this[int [|p|]] - { - get { return 0; } - } } - """); - } - [Fact] - public async Task Parameter_ConditionalDirective() - { - await TestDiagnosticMissingAsync( - """ - class C + public void MyHandler(object [|obj|], CustomEventArgs args) { - void M(int [|p|]) - { - #if DEBUG - System.Console.WriteLine(p); - #endif - } } - """); - } + } + """); + } - [Fact] - public async Task Parameter_EventHandler_FirstParameter() - { - await TestDiagnosticMissingAsync( - """ - class C + [Theory] + [InlineData(@"[System.Diagnostics.Conditional(nameof(M))]")] + [InlineData(@"[System.Obsolete]")] + [InlineData(@"[System.Runtime.Serialization.OnDeserializingAttribute]")] + [InlineData(@"[System.Runtime.Serialization.OnDeserializedAttribute]")] + [InlineData(@"[System.Runtime.Serialization.OnSerializingAttribute]")] + [InlineData(@"[System.Runtime.Serialization.OnSerializedAttribute]")] + public async Task Parameter_MethodsWithSpecialAttributes(string attribute) + { + await TestDiagnosticMissingAsync( + $$""" + class C + { + {{attribute}} + void M(int [|p|]) { - public void MyHandler(object [|obj|], System.EventArgs args) - { - } } - """); - } + } + """); + } - [Fact] - public async Task Parameter_EventHandler_SecondParameter() - { - await TestDiagnosticMissingAsync( - """ - class C + [Theory] + [InlineData("System.Composition", "ImportingConstructorAttribute")] + [InlineData("System.ComponentModel.Composition", "ImportingConstructorAttribute")] + public async Task Parameter_ConstructorsWithSpecialAttributes(string attributeNamespace, string attributeName) + { + await TestDiagnosticMissingAsync( + $$""" + namespace {{attributeNamespace}} + { + public class {{attributeName}} : System.Attribute { } + } + + class C + { + [{{attributeNamespace}}.{{attributeName}}()] + public C(int [|p|]) { - public void MyHandler(object obj, System.EventArgs [|args|]) - { - } } - """); - } + } + """); + } - [Fact] - public async Task Parameter_MethodUsedAsEventHandler() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32133")] + public async Task Parameter_SerializationConstructor() + { + await TestDiagnosticMissingAsync( + """ + using System; + using System.Runtime.Serialization; - public delegate void MyDelegate(int x); + internal sealed class NonSerializable + { + public NonSerializable(string value) => Value = value; - class C - { - private event MyDelegate myDel; + public string Value { get; set; } + } - void M(C c) - { - c.myDel += Handler; - } - - void Handler(int [|x|]) - { - } - } - """); - } + [Serializable] + internal sealed class CustomSerializingType : ISerializable + { + private readonly NonSerializable _nonSerializable; - [Fact] - public async Task Parameter_CustomEventArgs() - { - await TestDiagnosticMissingAsync( - """ - class C + public CustomSerializingType(SerializationInfo info, StreamingContext [|context|]) { - public class CustomEventArgs : System.EventArgs - { - } - - public void MyHandler(object [|obj|], CustomEventArgs args) - { - } + _nonSerializable = new NonSerializable(info.GetString("KEY")); } - """); - } - - [Theory] - [InlineData(@"[System.Diagnostics.Conditional(nameof(M))]")] - [InlineData(@"[System.Obsolete]")] - [InlineData(@"[System.Runtime.Serialization.OnDeserializingAttribute]")] - [InlineData(@"[System.Runtime.Serialization.OnDeserializedAttribute]")] - [InlineData(@"[System.Runtime.Serialization.OnSerializingAttribute]")] - [InlineData(@"[System.Runtime.Serialization.OnSerializedAttribute]")] - public async Task Parameter_MethodsWithSpecialAttributes(string attribute) - { - await TestDiagnosticMissingAsync( - $$""" - class C - { - {{attribute}} - void M(int [|p|]) - { - } - } - """); - } - [Theory] - [InlineData("System.Composition", "ImportingConstructorAttribute")] - [InlineData("System.ComponentModel.Composition", "ImportingConstructorAttribute")] - public async Task Parameter_ConstructorsWithSpecialAttributes(string attributeNamespace, string attributeName) - { - await TestDiagnosticMissingAsync( - $$""" - namespace {{attributeNamespace}} + public void GetObjectData(SerializationInfo info, StreamingContext context) { - public class {{attributeName}} : System.Attribute { } + info.AddValue("KEY", _nonSerializable.Value); } + } + """); + } - class C + [ConditionalFact(typeof(IsEnglishLocal))] + public async Task Parameter_DiagnosticMessages() + { + var source = + """ + public class C + { + // p1 is unused. + // p2 is written before read. + [|int M(int p1, int p2) + { + p2 = 0; + return p2; + } + + // p3 is unused parameter of a public API. + // p4 is written before read parameter of a public API. + public int M2(int p3, int p4) + { + p4 = 0; + return p4; + } + + void M3(int p5) + { + _ = nameof(p5); + }|] + } + """; + var testParameters = new TestParameters(retainNonFixableDiagnostics: true); + using var workspace = CreateWorkspaceFromOptions(source, testParameters); + var diagnostics = await GetDiagnosticsAsync(workspace, testParameters).ConfigureAwait(false); + diagnostics.Verify( + Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p1").WithLocation(5, 15), + Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p2").WithLocation(5, 23), + Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p3").WithLocation(13, 23), + Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p4").WithLocation(13, 31), + Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p5").WithLocation(19, 17)); + var sortedDiagnostics = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); + + Assert.Equal("Remove unused parameter 'p1'", sortedDiagnostics[0].GetMessage()); + Assert.Equal("Parameter 'p2' can be removed; its initial value is never used", sortedDiagnostics[1].GetMessage()); + Assert.Equal("Remove unused parameter 'p3' if it is not part of a shipped public API", sortedDiagnostics[2].GetMessage()); + Assert.Equal("Parameter 'p4' can be removed if it is not part of a shipped public API; its initial value is never used", sortedDiagnostics[3].GetMessage()); + Assert.Equal("Parameter 'p5' can be removed; its initial value is never used", sortedDiagnostics[4].GetMessage()); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32287")] + public async Task Parameter_DeclarationPatternWithNullDeclaredSymbol() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(object [|o|]) { - [{{attributeNamespace}}.{{attributeName}}()] - public C(int [|p|]) + if (o is int _) { } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32133")] - public async Task Parameter_SerializationConstructor() - { - await TestDiagnosticMissingAsync( - """ - using System; - using System.Runtime.Serialization; + } + """); + } - internal sealed class NonSerializable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32851")] + public async Task Parameter_Unused_SpecialNames() + { + await TestDiagnosticMissingAsync( + """ + class C + { + [|void M(int _, char _1, C _3)|] { - public NonSerializable(string value) => Value = value; - - public string Value { get; set; } } + } + """); + } - [Serializable] - internal sealed class CustomSerializingType : ISerializable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32851")] + public async Task Parameter_Used_SemanticError() + { + await TestDiagnosticMissingAsync( + """ + class C + { + void M(int [|x|]) { - private readonly NonSerializable _nonSerializable; + // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. + Invoke(() => x); - public CustomSerializingType(SerializationInfo info, StreamingContext [|context|]) - { - _nonSerializable = new NonSerializable(info.GetString("KEY")); - } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("KEY", _nonSerializable.Value); - } + T Invoke(Func a) { return a(); } } - """); - } + } + """); + } - [ConditionalFact(typeof(IsEnglishLocal))] - public async Task Parameter_DiagnosticMessages() - { - var source = - """ - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32851")] + public async Task Parameter_Unused_SemanticError() + { + await TestDiagnosticsAsync( + """ + class C + { + void M(int [|x|]) { - // p1 is unused. - // p2 is written before read. - [|int M(int p1, int p2) - { - p2 = 0; - return p2; - } + // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. + Invoke(() => 0); - // p3 is unused parameter of a public API. - // p4 is written before read parameter of a public API. - public int M2(int p3, int p4) - { - p4 = 0; - return p4; - } - - void M3(int p5) - { - _ = nameof(p5); - }|] - } - """; - var testParameters = new TestParameters(retainNonFixableDiagnostics: true); - using var workspace = CreateWorkspaceFromOptions(source, testParameters); - var diagnostics = await GetDiagnosticsAsync(workspace, testParameters).ConfigureAwait(false); - diagnostics.Verify( - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p1").WithLocation(5, 15), - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p2").WithLocation(5, 23), - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p3").WithLocation(13, 23), - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p4").WithLocation(13, 31), - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId, "p5").WithLocation(19, 17)); - var sortedDiagnostics = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); - - Assert.Equal("Remove unused parameter 'p1'", sortedDiagnostics[0].GetMessage()); - Assert.Equal("Parameter 'p2' can be removed; its initial value is never used", sortedDiagnostics[1].GetMessage()); - Assert.Equal("Remove unused parameter 'p3' if it is not part of a shipped public API", sortedDiagnostics[2].GetMessage()); - Assert.Equal("Parameter 'p4' can be removed if it is not part of a shipped public API; its initial value is never used", sortedDiagnostics[3].GetMessage()); - Assert.Equal("Parameter 'p5' can be removed; its initial value is never used", sortedDiagnostics[4].GetMessage()); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32287")] - public async Task Parameter_DeclarationPatternWithNullDeclaredSymbol() - { - await TestDiagnosticMissingAsync( - """ - class C - { - void M(object [|o|]) - { - if (o is int _) - { - } - } + T Invoke(Func a) { return a(); } } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32851")] - public async Task Parameter_Unused_SpecialNames() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32973")] + public async Task OutParameter_LocalFunction() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public static bool M(out int x) { - [|void M(int _, char _1, C _3)|] - { - } - } - """); - } + return LocalFunction(out x); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32851")] - public async Task Parameter_Used_SemanticError() - { - await TestDiagnosticMissingAsync( - """ - class C - { - void M(int [|x|]) + bool LocalFunction(out int [|y|]) { - // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. - Invoke(() => x); - - T Invoke(Func a) { return a(); } + y = 0; + return true; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32851")] - public async Task Parameter_Unused_SemanticError() - { - await TestDiagnosticsAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32973")] + public async Task RefParameter_Unused_LocalFunction() + { + await TestDiagnosticsAsync( + """ + class C + { + public static bool M(ref int x) { - void M(int [|x|]) - { - // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. - Invoke(() => 0); + return LocalFunction(ref x); - T Invoke(Func a) { return a(); } + bool LocalFunction(ref int [|y|]) + { + return true; } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32973")] - public async Task OutParameter_LocalFunction() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32973")] + public async Task RefParameter_Used_LocalFunction() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public static bool M(ref int x) { - public static bool M(out int x) - { - return LocalFunction(out x); + return LocalFunction(ref x); - bool LocalFunction(out int [|y|]) - { - y = 0; - return true; - } + bool LocalFunction(ref int [|y|]) + { + y = 0; + return true; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32973")] - public async Task RefParameter_Unused_LocalFunction() - { - await TestDiagnosticsAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] + public async Task NullCoalesceAssignment() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public static void M(C [|x|]) { - public static bool M(ref int x) - { - return LocalFunction(ref x); - - bool LocalFunction(ref int [|y|]) - { - return true; - } - } + x ??= new C(); } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32973")] - public async Task RefParameter_Used_LocalFunction() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34301")] + public async Task GenericLocalFunction() + { + await TestDiagnosticsAsync( + """ + class C + { + void M() { - public static bool M(ref int x) - { - return LocalFunction(ref x); + LocalFunc(0); - bool LocalFunction(ref int [|y|]) - { - y = 0; - return true; - } + void LocalFunc(T [|value|]) + { } } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] - public async Task NullCoalesceAssignment() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36715")] + public async Task GenericLocalFunction_02() + { + await TestDiagnosticsAsync( + """ + using System.Collections.Generic; + + class C + { + void M(object [|value|]) { - public static void M(C [|x|]) + try { - x ??= new C(); + value = LocalFunc(0); } - } - """, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34301")] - public async Task GenericLocalFunction() - { - await TestDiagnosticsAsync( - """ - class C - { - void M() + finally { - LocalFunc(0); - - void LocalFunc(T [|value|]) - { - } + value = LocalFunc(0); } - } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36715")] - public async Task GenericLocalFunction_02() - { - await TestDiagnosticsAsync( - """ - using System.Collections.Generic; + return; - class C - { - void M(object [|value|]) + IEnumerable LocalFunc(T value) { - try - { - value = LocalFunc(0); - } - finally - { - value = LocalFunc(0); - } - - return; - - IEnumerable LocalFunc(T value) - { - yield return value; - } + yield return value; } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36715")] - public async Task GenericLocalFunction_03() - { - await TestDiagnosticsAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36715")] + public async Task GenericLocalFunction_03() + { + await TestDiagnosticsAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + void M(object [|value|]) { - void M(object [|value|]) + Func> myDel = LocalFunc; + try { - Func> myDel = LocalFunc; - try - { - value = myDel(value); - } - finally - { - value = myDel(value); - } + value = myDel(value); + } + finally + { + value = myDel(value); + } - return; + return; - IEnumerable LocalFunc(T value) - { - yield return value; - } + IEnumerable LocalFunc(T value) + { + yield return value; } } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34830")] + public async Task RegressionTest_ShouldReportUnusedParameter() + { + var options = Option(CodeStyleOptions2.UnusedParameters, + new CodeStyleOption2(default, NotificationOption2.Suggestion)); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34830")] - public async Task RegressionTest_ShouldReportUnusedParameter() - { - var options = Option(CodeStyleOptions2.UnusedParameters, - new CodeStyleOption2(default, NotificationOption2.Suggestion)); + await TestDiagnosticMissingAsync( + """ + using System; + using System.Threading.Tasks; - await TestDiagnosticMissingAsync( - """ - using System; - using System.Threading.Tasks; + public interface I { event Action MyAction; } - public interface I { event Action MyAction; } + public sealed class C : IDisposable + { + private readonly Task task; - public sealed class C : IDisposable + public C(Task [|task|]) { - private readonly Task task; - - public C(Task [|task|]) - { - this.task = task; - Task.Run(async () => (await task).MyAction += myAction); - } + this.task = task; + Task.Run(async () => (await task).MyAction += myAction); + } - private void myAction() { } + private void myAction() { } - public void Dispose() => task.Result.MyAction -= myAction; - } - """, options); - } + public void Dispose() => task.Result.MyAction -= myAction; + } + """, options); + } #if !CODE_STYLE // Below test is not applicable for CodeStyle layer as attempting to fetch an editorconfig string representation for this invalid option fails. - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37326")] - public async Task RegressionTest_ShouldReportUnusedParameter_02() - { - var options = Option(CodeStyleOptions2.UnusedParameters, - new CodeStyleOption2((UnusedParametersPreference)2, NotificationOption2.Suggestion)); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37326")] + public async Task RegressionTest_ShouldReportUnusedParameter_02() + { + var options = Option(CodeStyleOptions2.UnusedParameters, + new CodeStyleOption2((UnusedParametersPreference)2, NotificationOption2.Suggestion)); - var parameters = new TestParameters(globalOptions: options, retainNonFixableDiagnostics: true); + var parameters = new TestParameters(globalOptions: options, retainNonFixableDiagnostics: true); - await TestDiagnosticMissingAsync( - """ - using System; - using System.Threading.Tasks; + await TestDiagnosticMissingAsync( + """ + using System; + using System.Threading.Tasks; - public interface I { event Action MyAction; } + public interface I { event Action MyAction; } - public sealed class C : IDisposable - { - private readonly Task task; + public sealed class C : IDisposable + { + private readonly Task task; - public C(Task [|task|]) - { - this.task = task; - Task.Run(async () => (await task).MyAction += myAction); - } + public C(Task [|task|]) + { + this.task = task; + Task.Run(async () => (await task).MyAction += myAction); + } - private void myAction() { } + private void myAction() { } - public void Dispose() => task.Result.MyAction -= myAction; - } - """, parameters); - } + public void Dispose() => task.Result.MyAction -= myAction; + } + """, parameters); + } #endif - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37483")] - public async Task MethodUsedAsDelegateInGeneratedCode_NoDiagnostic() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37483")] + public async Task MethodUsedAsDelegateInGeneratedCode_NoDiagnostic() + { + await TestDiagnosticMissingAsync( + """ + using System; - public partial class C + public partial class C + { + private void M(int [|x|]) { - private void M(int [|x|]) - { - } } + } - public partial class C + public partial class C + { + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + public void M2(out Action a) { - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - public void M2(out Action a) - { - a = M; - } + a = M; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37483")] - public async Task UnusedParameterInGeneratedCode_NoDiagnostic() - { - await TestDiagnosticMissingAsync( - """ - public partial class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37483")] + public async Task UnusedParameterInGeneratedCode_NoDiagnostic() + { + await TestDiagnosticMissingAsync( + """ + public partial class C + { + [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] + private void M(int [|x|]) { - [System.CodeDom.Compiler.GeneratedCodeAttribute("", "")] - private void M(int [|x|]) - { - } } - """); - } + } + """); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/57814")] - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedParameters)] - public async Task UnusedParameterInPartialMethodImplementation_NoDiagnostic() - { - await TestDiagnosticMissingAsync( - """ - public partial class C - { - public partial void M(int x); - } + [WorkItem("https://github.com/dotnet/roslyn/issues/57814")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedParameters)] + public async Task UnusedParameterInPartialMethodImplementation_NoDiagnostic() + { + await TestDiagnosticMissingAsync( + """ + public partial class C + { + public partial void M(int x); + } - public partial class C + public partial class C + { + public partial void M(int [|x|]) { - public partial void M(int [|x|]) - { - } } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedParameters)] - public async Task ParameterInPartialMethodDefinition_NoDiagnostic() - { - await TestDiagnosticMissingAsync( - """ - public partial class C - { - public partial void M(int [|x|]); - } - """); - } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedParameters)] + public async Task ParameterInPartialMethodDefinition_NoDiagnostic() + { + await TestDiagnosticMissingAsync( + """ + public partial class C + { + public partial void M(int [|x|]); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36817")] - public async Task ParameterWithoutName_NoDiagnostic() - { - await TestDiagnosticMissingAsync( - """ - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36817")] + public async Task ParameterWithoutName_NoDiagnostic() + { + await TestDiagnosticMissingAsync( + """ + public class C + { + public void M[|(int )|] { - public void M[|(int )|] - { - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] - public async Task NotImplementedException_NoDiagnostic1() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] + public async Task NotImplementedException_NoDiagnostic1() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + private void Goo(int [|i|]) { - private void Goo(int [|i|]) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] + public async Task NotImplementedException_NoDiagnostic2() + { + await TestDiagnosticMissingAsync( + """ + using System; + + class C + { + private void Goo(int [|i|]) + => throw new NotImplementedException(); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] - public async Task NotImplementedException_NoDiagnostic2() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] + public async Task NotImplementedException_NoDiagnostic3() + { + await TestDiagnosticMissingAsync( + """ + using System; + + class C + { + public C(int [|i|]) + => throw new NotImplementedException(); + } + """); + } - class C - { - private void Goo(int [|i|]) - => throw new NotImplementedException(); - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56317")] + public async Task NotImplementedException_NoDiagnostic4() + { + await TestDiagnosticMissingAsync( + """ + using System; + + class C + { + private int Goo(int [|i|]) + => throw new NotImplementedException(); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] - public async Task NotImplementedException_NoDiagnostic3() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56317")] + public async Task NotImplementedException_NoDiagnostic5() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + private int Goo(int [|i|]) { - public C(int [|i|]) - => throw new NotImplementedException(); + throw new NotImplementedException(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56317")] - public async Task NotImplementedException_NoDiagnostic4() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] + public async Task NotImplementedException_MultipleStatements1() + { + await TestDiagnosticsAsync( + """ + using System; - class C + class C + { + private void Goo(int [|i|]) { - private int Goo(int [|i|]) - => throw new NotImplementedException(); + throw new NotImplementedException(); + return; } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56317")] - public async Task NotImplementedException_NoDiagnostic5() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] + public async Task NotImplementedException_MultipleStatements2() + { + await TestDiagnosticsAsync( + """ + using System; - class C + class C + { + private void Goo(int [|i|]) { - private int Goo(int [|i|]) - { + if (true) throw new NotImplementedException(); - } } - """); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] - public async Task NotImplementedException_MultipleStatements1() - { - await TestDiagnosticsAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47142")] + public async Task Record_PrimaryConstructorParameter() + { + await TestMissingAsync( + @"record A(int [|X|]);"); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47142")] + public async Task Record_NonPrimaryConstructorParameter() + { + await TestDiagnosticsAsync( + """ + record A + { + public A(int [|X|]) { - private void Goo(int [|i|]) - { - throw new NotImplementedException(); - return; - } } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, +Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41236")] - public async Task NotImplementedException_MultipleStatements2() - { - await TestDiagnosticsAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47142")] + public async Task Record_DelegatingPrimaryConstructorParameter() + { + await TestDiagnosticMissingAsync( + """ + record A(int X); + record B(int X, int [|Y|]) : A(X); + """); + } - class C - { - private void Goo(int [|i|]) - { - if (true) - throw new NotImplementedException(); - } - } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47142")] - public async Task Record_PrimaryConstructorParameter() - { - await TestMissingAsync( - @"record A(int [|X|]);"); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47142")] - public async Task Record_NonPrimaryConstructorParameter() - { - await TestDiagnosticsAsync( - """ - record A - { - public A(int [|X|]) - { - } - } - """, - Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47142")] - public async Task Record_DelegatingPrimaryConstructorParameter() - { - await TestDiagnosticMissingAsync( - """ - record A(int X); - record B(int X, int [|Y|]) : A(X); - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47174")] - public async Task RecordPrimaryConstructorParameter_PublicRecord() - { - await TestDiagnosticMissingAsync( - """ - public record Base(int I) { } - public record Derived(string [|S|]) : Base(42) { } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45743")] - public async Task RequiredGetInstanceMethodByICustomMarshaler() - { - await TestDiagnosticMissingAsync(""" - using System; - using System.Runtime.InteropServices; - - - public class C : ICustomMarshaler - { - public void CleanUpManagedData(object ManagedObj) - => throw new NotImplementedException(); - - public void CleanUpNativeData(IntPtr pNativeData) - => throw new NotImplementedException(); - - public int GetNativeDataSize() - => throw new NotImplementedException(); - - public IntPtr MarshalManagedToNative(object ManagedObj) - => throw new NotImplementedException(); - - public object MarshalNativeToManaged(IntPtr pNativeData) - => throw new NotImplementedException(); - - public static ICustomMarshaler GetInstance(string [|s|]) - => null; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] - public async Task TestMethodWithUnusedParameterThrowsExpressionBody() - { - await TestDiagnosticMissingAsync( - """ - public class Class - { - public void Method(int [|x|]) => throw new System.Exception(); - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] - public async Task TestMethodWithUnusedParameterThrowsMethodBody() - { - await TestDiagnosticMissingAsync( - """ - public class Class - { - public void Method(int [|x|]) - { - throw new System.Exception(); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47174")] + public async Task RecordPrimaryConstructorParameter_PublicRecord() + { + await TestDiagnosticMissingAsync( + """ + public record Base(int I) { } + public record Derived(string [|S|]) : Base(42) { } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] - public async Task TestMethodWithUnusedParameterThrowsConstructorBody() - { - await TestDiagnosticMissingAsync( - """ - public class Class - { - public Class(int [|x|]) - { - throw new System.Exception(); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45743")] + public async Task RequiredGetInstanceMethodByICustomMarshaler() + { + await TestDiagnosticMissingAsync(""" + using System; + using System.Runtime.InteropServices; + + + public class C : ICustomMarshaler + { + public void CleanUpManagedData(object ManagedObj) + => throw new NotImplementedException(); + + public void CleanUpNativeData(IntPtr pNativeData) + => throw new NotImplementedException(); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] - public async Task TestMethodWithUnusedParameterThrowsConstructorExpressionBody() - { - await TestDiagnosticMissingAsync( - """ - public class Class + public int GetNativeDataSize() + => throw new NotImplementedException(); + + public IntPtr MarshalManagedToNative(object ManagedObj) + => throw new NotImplementedException(); + + public object MarshalNativeToManaged(IntPtr pNativeData) + => throw new NotImplementedException(); + + public static ICustomMarshaler GetInstance(string [|s|]) + => null; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] + public async Task TestMethodWithUnusedParameterThrowsExpressionBody() + { + await TestDiagnosticMissingAsync( + """ + public class Class + { + public void Method(int [|x|]) => throw new System.Exception(); + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] + public async Task TestMethodWithUnusedParameterThrowsMethodBody() + { + await TestDiagnosticMissingAsync( + """ + public class Class + { + public void Method(int [|x|]) { - public Class(int [|x|]) => throw new System.Exception(); + throw new System.Exception(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] - public async Task TestMethodWithUnusedParameterThrowsLocalFunctionExpressionBody() - { - await TestDiagnosticMissingAsync( - """ - public class Class + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] + public async Task TestMethodWithUnusedParameterThrowsConstructorBody() + { + await TestDiagnosticMissingAsync( + """ + public class Class + { + public Class(int [|x|]) { - public void Method() - { - void LocalMethod(int [|x|]) => throw new System.Exception(); - } + throw new System.Exception(); } - """); - } + } + """); + } - [Fact, WorkItem(67013, "https://github.com/dotnet/roslyn/issues/67013")] - public async Task Test_PrimaryConstructor1() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] + public async Task TestMethodWithUnusedParameterThrowsConstructorExpressionBody() + { + await TestDiagnosticMissingAsync( + """ + public class Class + { + public Class(int [|x|]) => throw new System.Exception(); + } + """); + } - class C(int [|a100|]) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/65275")] + public async Task TestMethodWithUnusedParameterThrowsLocalFunctionExpressionBody() + { + await TestDiagnosticMissingAsync( + """ + public class Class + { + public void Method() { + void LocalMethod(int [|x|]) => throw new System.Exception(); } - """); - } + } + """); + } - [Fact, WorkItem(67013, "https://github.com/dotnet/roslyn/issues/67013")] - public async Task Test_PrimaryConstructor2() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem(67013, "https://github.com/dotnet/roslyn/issues/67013")] + public async Task Test_PrimaryConstructor1() + { + await TestDiagnosticMissingAsync( + """ + using System; + + class C(int [|a100|]) + { + } + """); + } - class C(int [|a100|]) : Object() - { - int M1() => a100; - } - """); - } + [Fact, WorkItem(67013, "https://github.com/dotnet/roslyn/issues/67013")] + public async Task Test_PrimaryConstructor2() + { + await TestDiagnosticMissingAsync( + """ + using System; + + class C(int [|a100|]) : Object() + { + int M1() => a100; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70276")] - public async Task TestMethodWithNameOf() - { - await TestDiagnosticsAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70276")] + public async Task TestMethodWithNameOf() + { + await TestDiagnosticsAsync(""" + class C + { + void M(int [|x|]) { - void M(int [|x|]) - { - const string y = nameof(C); - } + const string y = nameof(C); } - """, Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); - } + } + """, Diagnostic(IDEDiagnosticIds.UnusedParameterDiagnosticId)); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs index 710a013428e3c..c80e2492244f8 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueAssignmentTests.cs @@ -16,508 +16,507 @@ using Xunit.Abstractions; using static Roslyn.Test.Utilities.TestHelpers; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpRemoveUnusedParametersAndValuesDiagnosticAnalyzer, - CSharpRemoveUnusedValuesCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpRemoveUnusedParametersAndValuesDiagnosticAnalyzer, + CSharpRemoveUnusedValuesCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] - public class RemoveUnusedValueAssignmentTests : RemoveUnusedValuesTestsBase +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] +public class RemoveUnusedValueAssignmentTests : RemoveUnusedValuesTestsBase +{ + public RemoveUnusedValueAssignmentTests(ITestOutputHelper logger) + : base(logger) { - public RemoveUnusedValueAssignmentTests(ITestOutputHelper logger) - : base(logger) - { - } + } - private protected override OptionsCollection PreferNone - => Option(CSharpCodeStyleOptions.UnusedValueAssignment, - new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.None)); + private protected override OptionsCollection PreferNone + => Option(CSharpCodeStyleOptions.UnusedValueAssignment, + new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.None)); - private protected override OptionsCollection PreferDiscard - => Option(CSharpCodeStyleOptions.UnusedValueAssignment, - new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.Suggestion)); + private protected override OptionsCollection PreferDiscard + => Option(CSharpCodeStyleOptions.UnusedValueAssignment, + new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.Suggestion)); - private protected override OptionsCollection PreferUnusedLocal - => Option(CSharpCodeStyleOptions.UnusedValueAssignment, - new CodeStyleOption2(UnusedValuePreference.UnusedLocalVariable, NotificationOption2.Suggestion)); + private protected override OptionsCollection PreferUnusedLocal + => Option(CSharpCodeStyleOptions.UnusedValueAssignment, + new CodeStyleOption2(UnusedValuePreference.UnusedLocalVariable, NotificationOption2.Suggestion)); - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); - [Fact] - public async Task Initialization_Suppressed() - { - var source = - """ - class C + [Fact] + public async Task Initialization_Suppressed() + { + var source = + """ + class C + { + int M() { - int M() - { - int x = 1; - x = 2; - return x; - } + int x = 1; + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + Options = { - TestCode = source, - FixedCode = source, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable, NotificationOption2.None }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable, NotificationOption2.None }, + }, + }.RunAsync(); + } - [Fact] - public async Task Assignment_Suppressed() - { - var source = - """ - class C + [Fact] + public async Task Assignment_Suppressed() + { + var source = + """ + class C + { + int M() { - int M() - { - int x; - x = 1; - x = 2; - return x; - } + int x; + x = 1; + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + Options = { - TestCode = source, - FixedCode = source, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable, NotificationOption2.None }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable, NotificationOption2.None }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Initialization_ConstantValue(object option) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Initialization_ConstantValue(object option) + { + var source = + """ + class C + { + int M() { - int M() - { - int {|IDE0059:x|} = 1; - x = 2; - return x; - } + int {|IDE0059:x|} = 1; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + int M() { - int M() - { - int x = 2; - return x; - } + int x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/48070")] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Initialization_ConstantValue_DoNotCopyLeadingTriviaDirectives(object option) - { - var source = - """ - class C { - void M() - { - #region - int value = 3; - #endregion + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/48070")] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Initialization_ConstantValue_DoNotCopyLeadingTriviaDirectives(object option) + { + var source = + """ + class C { + void M() + { + #region + int value = 3; + #endregion - int? {|IDE0059:x|} = null; - int y = value + value; + int? {|IDE0059:x|} = null; + int y = value + value; - x = y; - System.Console.WriteLine(x); - } + x = y; + System.Console.WriteLine(x); } - """; - var fixedSource = - """ - class C { - void M() - { - #region - int value = 3; + } + """; + var fixedSource = + """ + class C { + void M() + { + #region + int value = 3; - #endregion - int y = value + value; + #endregion + int y = value + value; - int? x = y; - System.Console.WriteLine(x); - } + int? x = y; + System.Console.WriteLine(x); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Fact] - public async Task Initialization_ConstantValue_RemoveUnusedParametersSuppressed() - { - var source = - """ - class C + [Fact] + public async Task Initialization_ConstantValue_RemoveUnusedParametersSuppressed() + { + var source = + """ + class C + { + int M() { - int M() - { - int {|IDE0059:x|} = 1; - x = 2; - return x; - } + int {|IDE0059:x|} = 1; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + int M() { - int M() - { - int x = 2; - return x; - } + int x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CodeStyleOptions2.UnusedParameters, UnusedParametersPreference.NonPublicMethods, NotificationOption2.None }, - }, - }.RunAsync(); - } + { CodeStyleOptions2.UnusedParameters, UnusedParametersPreference.NonPublicMethods, NotificationOption2.None }, + }, + }.RunAsync(); + } - [Fact] - public async Task Initialization_ConstantValue_RemoveUnusedParametersNotApplicable() - { - var source = - """ - class C + [Fact] + public async Task Initialization_ConstantValue_RemoveUnusedParametersNotApplicable() + { + var source = + """ + class C + { + public int M(int {|IDE0060:z|}) { - public int M(int {|IDE0060:z|}) - { - int {|IDE0059:x|} = 1; - x = 2; - return x; - } + int {|IDE0059:x|} = 1; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + public int M(int {|IDE0060:z|}) { - public int M(int {|IDE0060:z|}) - { - int x = 2; - return x; - } + int x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CodeStyleOptions2.UnusedParameters, UnusedParametersPreference.NonPublicMethods, NotificationOption2.Silent }, - }, - }.RunAsync(); - } + { CodeStyleOptions2.UnusedParameters, UnusedParametersPreference.NonPublicMethods, NotificationOption2.Silent }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Assignment_ConstantValue(object option) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Assignment_ConstantValue(object option) + { + var source = + """ + class C + { + int M() { - int M() - { - int x; - {|IDE0059:x|} = 1; - x = 2; - return x; - } + int x; + {|IDE0059:x|} = 1; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + int M() { - int M() - { - int x; - x = 2; - return x; - } + int x; + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Assignment_ConstantValue_NoReads(object option) - { - var source = - """ - class C - { - void M() - { - int x; - {|IDE0059:x|} = 1; - } - } - """; - var fixedSource = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Assignment_ConstantValue_NoReads(object option) + { + var source = + """ + class C + { + void M() { - void M() - { - } + int x; + {|IDE0059:x|} = 1; } - """; - - await new VerifyCS.Test + } + """; + var fixedSource = + """ + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + void M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + } + } + """; - [Fact] - public async Task Assignment_NonConstantValue_NoReads_PreferDiscard() + await new VerifyCS.Test { - var source = - """ - class C - { - void M() - { - int x; - {|IDE0059:x|} = M2(); - } + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - int M2() => 0; - } - """; - var fixedSource = - """ - class C + [Fact] + public async Task Assignment_NonConstantValue_NoReads_PreferDiscard() + { + var source = + """ + class C + { + void M() { - void M() - { - _ = M2(); - } - - int M2() => 0; + int x; + {|IDE0059:x|} = M2(); } - """; - await new VerifyCS.Test + int M2() => 0; + } + """; + var fixedSource = + """ + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + void M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } + _ = M2(); + } - [Fact] - public async Task Assignment_NonConstantValue_NoReads_PreferUnusedLocal() - { - var source = - """ - class C - { - void M() - { - int x; - x = M2(); - } + int M2() => 0; + } + """; - int M2() => 0; - } - """; + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task Assignment_NonConstantValue_NoReads_PreferUnusedLocal() + { + var source = + """ + class C { - TestCode = source, - FixedCode = source, - Options = + void M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.UnusedLocalVariable }, - }, - }.RunAsync(); - } + int x; + x = M2(); + } + + int M2() => 0; + } + """; - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Initialization_NonConstantValue_ParameterReference(object option) + await new VerifyCS.Test { - var source = - """ - class C + TestCode = source, + FixedCode = source, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.UnusedLocalVariable }, + }, + }.RunAsync(); + } + + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Initialization_NonConstantValue_ParameterReference(object option) + { + var source = + """ + class C + { + int M(int p) { - int M(int p) - { - int {|IDE0059:x|} = p; - x = 2; - return x; - } + int {|IDE0059:x|} = p; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + int M(int {|IDE0060:p|}) { - int M(int {|IDE0060:p|}) - { - int x = 2; - return x; - } + int x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Assignment_NonConstantValue_ParameterReference(object option) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Assignment_NonConstantValue_ParameterReference(object option) + { + var source = + """ + class C + { + int M(int p) { - int M(int p) - { - int x; - {|IDE0059:x|} = p; - x = 2; - return x; - } + int x; + {|IDE0059:x|} = p; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + int M(int {|IDE0060:p|}) { - int M(int {|IDE0060:p|}) - { - int x; - x = 2; - return x; - } + int x; + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task Initialization_NonConstantValue_LocalReference( - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) - { - var source = - """ - class C + [Theory, CombinatorialData] + public async Task Initialization_NonConstantValue_LocalReference( + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C + { + int M() { - int M() - { - int local = 0; - int {|IDE0059:x|} = local; - x = 2; - return x; - } + int local = 0; + int {|IDE0059:x|} = local; + x = 2; + return x; } - """; - var (fixedSource, iterations) = testBehaviors switch - { - CodeFixTestBehaviors.None => + } + """; + var (fixedSource, iterations) = testBehaviors switch + { + CodeFixTestBehaviors.None => (""" class C { @@ -528,7 +527,7 @@ int M() } } """, iterations: 2), - CodeFixTestBehaviors.FixOne => + CodeFixTestBehaviors.FixOne => (""" class C { @@ -540,46 +539,45 @@ int M() } } """, iterations: 1), - _ => throw ExceptionUtilities.Unreachable(), - }; + _ => throw ExceptionUtilities.Unreachable(), + }; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + CodeFixTestBehaviors = testBehaviors, + NumberOfIncrementalIterations = iterations, + NumberOfFixAllIterations = iterations, + Options = { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - CodeFixTestBehaviors = testBehaviors, - NumberOfIncrementalIterations = iterations, - NumberOfFixAllIterations = iterations, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [CombinatorialData] - public async Task Assignment_NonConstantValue_LocalReference( - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) - { - var source = - """ - class C + [Theory, CombinatorialData] + public async Task Assignment_NonConstantValue_LocalReference( + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C + { + int M() { - int M() - { - int local = 0; - int x; - {|IDE0059:x|} = local; - x = 2; - return x; - } + int local = 0; + int x; + {|IDE0059:x|} = local; + x = 2; + return x; } - """; - var (fixedSource, iterations) = testBehaviors switch - { - CodeFixTestBehaviors.None => + } + """; + var (fixedSource, iterations) = testBehaviors switch + { + CodeFixTestBehaviors.None => (""" class C { @@ -591,7 +589,7 @@ int M() } } """, iterations: 2), - CodeFixTestBehaviors.FixOne => + CodeFixTestBehaviors.FixOne => (""" class C { @@ -604,539 +602,538 @@ int M() } } """, iterations: 1), - _ => throw ExceptionUtilities.Unreachable(), - }; + _ => throw ExceptionUtilities.Unreachable(), + }; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + CodeFixTestBehaviors = testBehaviors, + NumberOfIncrementalIterations = iterations, + NumberOfFixAllIterations = iterations, + Options = { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - CodeFixTestBehaviors = testBehaviors, - NumberOfIncrementalIterations = iterations, - NumberOfFixAllIterations = iterations, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Initialization_NonConstantValue_DefaultExpression(object option) - { - var source = - """ - struct C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Initialization_NonConstantValue_DefaultExpression(object option) + { + var source = + """ + struct C + { + C M() { - C M() - { - C {|IDE0059:c|} = default(C); - c = new C(); - return c; - } + C {|IDE0059:c|} = default(C); + c = new C(); + return c; } - """; - var fixedSource = - """ - struct C + } + """; + var fixedSource = + """ + struct C + { + C M() { - C M() - { - C c = new C(); - return c; - } + C c = new C(); + return c; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Initialization_NonConstantValue_CastExpression(object option) - { - var source = - """ - struct C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Initialization_NonConstantValue_CastExpression(object option) + { + var source = + """ + struct C + { + C M(object obj) { - C M(object obj) - { - C {|IDE0059:c|} = (C)obj; - c = new C(); - return c; - } + C {|IDE0059:c|} = (C)obj; + c = new C(); + return c; } - """; - var fixedSource = - """ - struct C + } + """; + var fixedSource = + """ + struct C + { + C M(object {|IDE0060:obj|}) { - C M(object {|IDE0060:obj|}) - { - C c = new C(); - return c; - } + C c = new C(); + return c; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Initialization_NonConstantValue_FieldReferenceWithThisReceiver(object option) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Initialization_NonConstantValue_FieldReferenceWithThisReceiver(object option) + { + var source = + """ + class C + { + private int field; + int M() { - private int field; - int M() - { - int {|IDE0059:x|} = field; - x = 2; - return x; - } + int {|IDE0059:x|} = field; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + private int field; + int M() { - private int field; - int M() - { - int x = 2; - return x; - } + int x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Assignment_NonConstantValue_FieldReferenceWithNullReceiver(object option) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Assignment_NonConstantValue_FieldReferenceWithNullReceiver(object option) + { + var source = + """ + class C + { + private static int field; + int M() { - private static int field; - int M() - { - int x; - {|IDE0059:x|} = field; - x = 2; - return x; - } + int x; + {|IDE0059:x|} = field; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + private static int field; + int M() { - private static int field; - int M() - { - int x; - x = 2; - return x; - } + int x; + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable, "_")] - [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] - public async Task Assignment_NonConstantValue_FieldReferenceWithReceiver(object option, string fix) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable, "_")] + [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] + public async Task Assignment_NonConstantValue_FieldReferenceWithReceiver(object option, string fix) + { + var source = + """ + class C + { + private int field; + int M(C c) { - private int field; - int M(C c) - { - int x; - {|IDE0059:x|} = c.field; - x = 2; - return x; - } + int x; + {|IDE0059:x|} = c.field; + x = 2; + return x; } - """; - var fixedSource = - $$""" - class C + } + """; + var fixedSource = + $$""" + class C + { + private int field; + int M(C c) { - private int field; - int M(C c) - { - int x; - {{fix}} = c.field; - x = 2; - return x; - } + int x; + {{fix}} = c.field; + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable, "_")] - [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] - public async Task Initialization_NonConstantValue_PropertyReference(object option, string fix) - { - var source = - """ - class C - { - private int Property { get { throw new System.Exception(); } } - int M() - { - int x; - {|IDE0059:x|} = Property; - x = 2; - return x; - } - } - """; - var fixedSource = - $$""" - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable, "_")] + [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] + public async Task Initialization_NonConstantValue_PropertyReference(object option, string fix) + { + var source = + """ + class C + { + private int Property { get { throw new System.Exception(); } } + int M() { - private int Property { get { throw new System.Exception(); } } - int M() - { - int x; - {{fix}} = Property; - x = 2; - return x; - } + int x; + {|IDE0059:x|} = Property; + x = 2; + return x; } - """; - - await new VerifyCS.Test + } + """; + var fixedSource = + $$""" + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + private int Property { get { throw new System.Exception(); } } + int M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + int x; + {{fix}} = Property; + x = 2; + return x; + } + } + """; - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable, "_")] - [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] - public async Task Initialization_NonConstantValue_MethodInvocation(object option, string fix) + await new VerifyCS.Test { - var source = - """ - class C - { - int M() - { - int {|IDE0059:x|} = M2(); - x = 2; - return x; - } + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - int M2() => 0; - } - """; - var fixedSource = - $$""" - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable, "_")] + [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] + public async Task Initialization_NonConstantValue_MethodInvocation(object option, string fix) + { + var source = + """ + class C + { + int M() { - int M() - { - {{fix}} = M2(); - int x = 2; - return x; - } - - int M2() => 0; + int {|IDE0059:x|} = M2(); + x = 2; + return x; } - """; - await new VerifyCS.Test + int M2() => 0; + } + """; + var fixedSource = + $$""" + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + int M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + {{fix}} = M2(); + int x = 2; + return x; + } - [Fact] - public async Task Initialization_NonConstantValue_PreferDiscard_CSharp6() + int M2() => 0; + } + """; + + await new VerifyCS.Test { - // Discard not supported in C# 6.0, so we fallback to unused local variable. - var source = - """ - class C - { - int M() - { - int {|IDE0059:x|} = M2(); - x = 2; - return x; - } + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - int M2() => 0; - } - """; - var fixedSource = - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_PreferDiscard_CSharp6() + { + // Discard not supported in C# 6.0, so we fallback to unused local variable. + var source = + """ + class C + { + int M() { - int M() - { - int unused = M2(); - int x = 2; - return x; - } - - int M2() => 0; + int {|IDE0059:x|} = M2(); + x = 2; + return x; } - """; - await new VerifyCS.Test + int M2() => 0; + } + """; + var fixedSource = + """ + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + int M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp6, - }.RunAsync(); - } + int unused = M2(); + int x = 2; + return x; + } + + int M2() => 0; + } + """; - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable, "_")] - [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] - public async Task Assignment_NonConstantValue_MethodInvocation(object option, string fix) + await new VerifyCS.Test { - var source = - """ - class C - { - int M() - { - int x; - {|IDE0059:x|} = M2(); - x = 2; - return x; - } + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp6, + }.RunAsync(); + } - int M2() => 0; - } - """; - var fixedSource = - $$""" - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable, "_")] + [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] + public async Task Assignment_NonConstantValue_MethodInvocation(object option, string fix) + { + var source = + """ + class C + { + int M() { - int M() - { - int x; - {{fix}} = M2(); - x = 2; - return x; - } - - int M2() => 0; + int x; + {|IDE0059:x|} = M2(); + x = 2; + return x; } - """; - await new VerifyCS.Test + int M2() => 0; + } + """; + var fixedSource = + $$""" + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + int M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + int x; + {{fix}} = M2(); + x = 2; + return x; + } + + int M2() => 0; + } + """; - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task Assignment_NonConstantValue_ImplicitConversion(object option) + await new VerifyCS.Test { - var source = - """ - class C + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } + + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task Assignment_NonConstantValue_ImplicitConversion(object option) + { + var source = + """ + class C + { + int M(int {|IDE0060:x|}, short s) { - int M(int {|IDE0060:x|}, short s) - { - {|IDE0059:x|} = s; - x = 2; - return x; - } + {|IDE0059:x|} = s; + x = 2; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + int M(int {|IDE0060:x|}, short {|IDE0060:s|}) { - int M(int {|IDE0060:x|}, short {|IDE0060:s|}) - { - x = 2; - return x; - } + x = 2; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable, "_")] - [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] - public async Task Assignment_NonConstantValue_UserDefinedConversion(object option, string fix) - { - var source = - """ - class C + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable, "_")] + [InlineData(UnusedValuePreference.UnusedLocalVariable, "int unused")] + public async Task Assignment_NonConstantValue_UserDefinedConversion(object option, string fix) + { + var source = + """ + class C + { + int M(int {|IDE0060:x|}, C c) { - int M(int {|IDE0060:x|}, C c) - { - {|IDE0059:x|} = (int)c; - x = 2; - return x; - } + {|IDE0059:x|} = (int)c; + x = 2; + return x; + } - public static explicit operator int(C {|IDE0060:c|}) - { - return 0; - } + public static explicit operator int(C {|IDE0060:c|}) + { + return 0; + } - public static explicit operator C(int {|IDE0060:i|}) - { - return default(C); - } + public static explicit operator C(int {|IDE0060:i|}) + { + return default(C); } - """; - var fixedSource = - $$""" - class C + } + """; + var fixedSource = + $$""" + class C + { + int M(int {|IDE0060:x|}, C c) { - int M(int {|IDE0060:x|}, C c) - { - {{fix}} = (int)c; - x = 2; - return x; - } - - public static explicit operator int(C {|IDE0060:c|}) - { - return 0; - } + {{fix}} = (int)c; + x = 2; + return x; + } - public static explicit operator C(int {|IDE0060:i|}) - { - return default(C); - } + public static explicit operator int(C {|IDE0060:c|}) + { + return 0; } - """; - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - Options = + public static explicit operator C(int {|IDE0060:i|}) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + return default(C); + } + } + """; - [Theory] - [CombinatorialData] - public async Task NestedAssignment_ConstantValue( - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck)] CodeFixTestBehaviors testBehaviors) + await new VerifyCS.Test { - var source = - """ - class C + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } + + [Theory, CombinatorialData] + public async Task NestedAssignment_ConstantValue( + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C + { + int M(int {|IDE0060:x|}, int {|IDE0060:y|}) { - int M(int {|IDE0060:x|}, int {|IDE0060:y|}) - { - {|IDE0059:y|} = {|IDE0059:x|} = 1; - x = 2; - return x; - } + {|IDE0059:y|} = {|IDE0059:x|} = 1; + x = 2; + return x; } - """; + } + """; - var (fixedSource, iterations) = ((UnusedValuePreference)option, testBehaviors) switch - { - (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.None) => + var (fixedSource, iterations) = ((UnusedValuePreference)option, testBehaviors) switch + { + (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.None) => (""" class C { @@ -1148,7 +1145,7 @@ int M(int {|IDE0060:x|}, int {|IDE0060:y|}) } } """, iterations: 2), - (UnusedValuePreference.UnusedLocalVariable, CodeFixTestBehaviors.None) => + (UnusedValuePreference.UnusedLocalVariable, CodeFixTestBehaviors.None) => (""" class C { @@ -1159,7 +1156,7 @@ int M(int {|IDE0060:x|}, int {|IDE0060:y|}) } } """, iterations: 3), - (_, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => + (_, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => (""" class C { @@ -1171,1661 +1168,1651 @@ int M(int {|IDE0060:x|}, int {|IDE0060:y|}) } } """, iterations: 1), - _ => throw ExceptionUtilities.Unreachable(), - }; - - var test = new VerifyCS.Test - { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - CodeFixTestBehaviors = testBehaviors, - NumberOfIncrementalIterations = iterations, - NumberOfFixAllIterations = iterations, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }; + _ => throw ExceptionUtilities.Unreachable(), + }; - if (testBehaviors.HasFlag(CodeFixTestBehaviors.FixOne)) + var test = new VerifyCS.Test + { + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + CodeFixTestBehaviors = testBehaviors, + NumberOfIncrementalIterations = iterations, + NumberOfFixAllIterations = iterations, + Options = { - test.DiagnosticSelector = diagnostics => diagnostics[1]; - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }; - await test.RunAsync(); + if (testBehaviors.HasFlag(CodeFixTestBehaviors.FixOne)) + { + test.DiagnosticSelector = diagnostics => diagnostics[1]; } - [Theory] - [CombinatorialData] - public async Task NestedAssignment_NonConstantValue( - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck)] CodeFixTestBehaviors testBehaviors) - { - var source = - """ - class C - { - int M(int {|IDE0060:x|}, int {|IDE0060:y|}) - { - {|IDE0059:y|} = {|IDE0059:x|} = M2(); - x = 2; - return x; - } + await test.RunAsync(); + } - int M2() => 0; + [Theory, CombinatorialData] + public async Task NestedAssignment_NonConstantValue( + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C + { + int M(int {|IDE0060:x|}, int {|IDE0060:y|}) + { + {|IDE0059:y|} = {|IDE0059:x|} = M2(); + x = 2; + return x; } - """; - var fixedSource = ((UnusedValuePreference)option, testBehaviors) switch + int M2() => 0; + } + """; + + var fixedSource = ((UnusedValuePreference)option, testBehaviors) switch + { + (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.None) => + """ + class C { - (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.None) => - """ - class C + int M(int {|IDE0060:x|}, int {|IDE0060:y|}) { - int M(int {|IDE0060:x|}, int {|IDE0060:y|}) - { - _ = _ = M2(); - x = 2; - return x; - } - - int M2() => 0; + _ = _ = M2(); + x = 2; + return x; } - """, - (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => - """ - class C - { - int M(int {|IDE0060:x|}, int {|IDE0060:y|}) - { - {|IDE0059:y|} = _ = M2(); - x = 2; - return x; - } - int M2() => 0; - } - """, - (UnusedValuePreference.UnusedLocalVariable, CodeFixTestBehaviors.None) => - """ - class C + int M2() => 0; + } + """, + (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => + """ + class C + { + int M(int {|IDE0060:x|}, int {|IDE0060:y|}) { - int M(int {|IDE0060:x|}, int {|IDE0060:y|}) - { - int unused1; - int unused = unused1 = M2(); - x = 2; - return x; - } - - int M2() => 0; + {|IDE0059:y|} = _ = M2(); + x = 2; + return x; } - """, - (UnusedValuePreference.UnusedLocalVariable, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => - """ - class C - { - int M(int {|IDE0060:x|}, int {|IDE0060:y|}) - { - int unused; - {|IDE0059:y|} = unused = M2(); - x = 2; - return x; - } - int M2() => 0; + int M2() => 0; + } + """, + (UnusedValuePreference.UnusedLocalVariable, CodeFixTestBehaviors.None) => + """ + class C + { + int M(int {|IDE0060:x|}, int {|IDE0060:y|}) + { + int unused1; + int unused = unused1 = M2(); + x = 2; + return x; } - """, - _ => throw ExceptionUtilities.Unreachable(), - }; - var test = new VerifyCS.Test + int M2() => 0; + } + """, + (UnusedValuePreference.UnusedLocalVariable, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => + """ + class C { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - CodeFixTestBehaviors = testBehaviors, - Options = + int M(int {|IDE0060:x|}, int {|IDE0060:y|}) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }; + int unused; + {|IDE0059:y|} = unused = M2(); + x = 2; + return x; + } - if (testBehaviors.HasFlag(CodeFixTestBehaviors.FixOne)) - { - test.DiagnosticSelector = diagnostics => diagnostics[1]; + int M2() => 0; } + """, + _ => throw ExceptionUtilities.Unreachable(), + }; - await test.RunAsync(); - } - - [Theory] - [InlineData(UnusedValuePreference.DiscardVariable)] - [InlineData(UnusedValuePreference.UnusedLocalVariable)] - public async Task ReadAndWriteInSameExpression_MethodInvocation(object option) + var test = new VerifyCS.Test { - var source = - """ - class C - { - int M() - { - int x = 1; - x = M2(x); - return x; - } + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + CodeFixTestBehaviors = testBehaviors, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }; - int M2(int x) => x; - } - """; + if (testBehaviors.HasFlag(CodeFixTestBehaviors.FixOne)) + { + test.DiagnosticSelector = diagnostics => diagnostics[1]; + } + + await test.RunAsync(); + } - await new VerifyCS.Test + [Theory] + [InlineData(UnusedValuePreference.DiscardVariable)] + [InlineData(UnusedValuePreference.UnusedLocalVariable)] + public async Task ReadAndWriteInSameExpression_MethodInvocation(object option) + { + var source = + """ + class C { - TestCode = source, - FixedCode = source, - Options = + int M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + int x = 1; + x = M2(x); + return x; + } + + int M2(int x) => x; + } + """; - [Theory] - [CombinatorialData] - public async Task IncrementOrDecrementOperator_ValueUsed_SameStatement( - [CombinatorialValues("++", "--")] string @operator, - bool applyAsPrefix, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + await new VerifyCS.Test { - var (prefix, postfix) = applyAsPrefix ? (@operator, "") : ("", @operator); - var source = - $$""" - class C - { - void M(int x) - { - var {|#0:y|} = {{prefix}}x{{postfix}}; - } - } - """; + TestCode = source, + FixedCode = source, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - var fixedSource = (UnusedValuePreference)option switch + [Theory, CombinatorialData] + public async Task IncrementOrDecrementOperator_ValueUsed_SameStatement( + [CombinatorialValues("++", "--")] string @operator, + bool applyAsPrefix, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var (prefix, postfix) = applyAsPrefix ? (@operator, "") : ("", @operator); + var source = + $$""" + class C { - UnusedValuePreference.UnusedLocalVariable => source, - UnusedValuePreference.DiscardVariable => - $$""" - class C + void M(int x) { - void M(int x) - { - _ = {{prefix}}x{{postfix}}; - } + var {|#0:y|} = {{prefix}}x{{postfix}}; } - """, - _ => throw ExceptionUtilities.Unreachable(), - }; + } + """; - var test = new VerifyCS.Test + var fixedSource = (UnusedValuePreference)option switch + { + UnusedValuePreference.UnusedLocalVariable => source, + UnusedValuePreference.DiscardVariable => + $$""" + class C { - TestState = { Sources = { source } }, - FixedCode = fixedSource, - Options = + void M(int x) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }; + _ = {{prefix}}x{{postfix}}; + } + } + """, + _ => throw ExceptionUtilities.Unreachable(), + }; - if ((UnusedValuePreference)option == UnusedValuePreference.DiscardVariable) + var test = new VerifyCS.Test + { + TestState = { Sources = { source } }, + FixedCode = fixedSource, + Options = { - test.TestState.ExpectedDiagnostics.Add( - // /0/Test0.cs(5,13): info IDE0059: Unnecessary assignment of a value to 'y' - VerifyCS.Diagnostic("IDE0059").WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("y")); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }; - await test.RunAsync(); + if ((UnusedValuePreference)option == UnusedValuePreference.DiscardVariable) + { + test.TestState.ExpectedDiagnostics.Add( + // /0/Test0.cs(5,13): info IDE0059: Unnecessary assignment of a value to 'y' + VerifyCS.Diagnostic("IDE0059").WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("y")); } - [Theory] - [CombinatorialData] - public async Task IncrementOrDecrementOperator_ValueUsed_LaterStatement( - [CombinatorialValues("++", "--")] string @operator, - bool applyAsPrefix, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) - { - var (prefix, postfix) = applyAsPrefix ? (@operator, "") : ("", @operator); - var source = - $$""" - class C - { - int M(int x) - { - {{prefix}}x{{postfix}}; - return x; - } - } - """; + await test.RunAsync(); + } - await new VerifyCS.Test + [Theory, CombinatorialData] + public async Task IncrementOrDecrementOperator_ValueUsed_LaterStatement( + [CombinatorialValues("++", "--")] string @operator, + bool applyAsPrefix, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var (prefix, postfix) = applyAsPrefix ? (@operator, "") : ("", @operator); + var source = + $$""" + class C { - TestCode = source, - FixedCode = source, - Options = + int M(int x) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + {{prefix}}x{{postfix}}; + return x; + } + } + """; - [Theory] - [CombinatorialData] - public async Task IncrementOrDecrementOperator_ValueUnused( - [CombinatorialValues("++", "--")] string @operator, - bool applyAsPrefix, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + await new VerifyCS.Test { - var (prefix, postfix) = applyAsPrefix ? (@operator, "") : ("", @operator); - var source = - $$""" - class C + TestCode = source, + FixedCode = source, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } + + [Theory, CombinatorialData] + public async Task IncrementOrDecrementOperator_ValueUnused( + [CombinatorialValues("++", "--")] string @operator, + bool applyAsPrefix, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var (prefix, postfix) = applyAsPrefix ? (@operator, "") : ("", @operator); + var source = + $$""" + class C + { + void M(int x) { - void M(int x) - { - {{prefix}}{|IDE0059:x|}{{postfix}}; - } + {{prefix}}{|IDE0059:x|}{{postfix}}; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void M(int {|IDE0060:x|}) { - void M(int {|IDE0060:x|}) - { - } } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - await new VerifyCS.Test + [Theory, CombinatorialData] + public async Task CompoundAssignmentOperator_ValueUsed_SameStatement( + [CombinatorialValues("1" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var source = + $$""" + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + void M(int x) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + var {|#0:y|} = x += {{rightHandSide}}; + } + + int M2() => 0; + } + """; - [Theory] - [CombinatorialData] - public async Task CompoundAssignmentOperator_ValueUsed_SameStatement( - [CombinatorialValues("1" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + var fixedSource = (UnusedValuePreference)option switch { - var source = - $$""" - class C + UnusedValuePreference.UnusedLocalVariable => source, + UnusedValuePreference.DiscardVariable => + $$""" + class C + { + void M(int x) { - void M(int x) - { - var {|#0:y|} = x += {{rightHandSide}}; - } - - int M2() => 0; + _ = x += {{rightHandSide}}; } - """; - var fixedSource = (UnusedValuePreference)option switch + int M2() => 0; + } + """, + _ => throw ExceptionUtilities.Unreachable(), + }; + + var test = new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - UnusedValuePreference.UnusedLocalVariable => source, - UnusedValuePreference.DiscardVariable => - $$""" - class C - { - void M(int x) - { - _ = x += {{rightHandSide}}; - } + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }; - int M2() => 0; - } - """, - _ => throw ExceptionUtilities.Unreachable(), - }; + if ((UnusedValuePreference)option == UnusedValuePreference.DiscardVariable) + { + test.TestState.ExpectedDiagnostics.Add( + // /0/Test0.cs(5,13): info IDE0059: Unnecessary assignment of a value to 'y' + VerifyCS.Diagnostic("IDE0059").WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("y")); + } + + await test.RunAsync(); + } - var test = new VerifyCS.Test + [Theory, CombinatorialData] + public async Task CompoundAssignmentOperator_ValueUsed_LaterStatement( + [CombinatorialValues("1" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var source = + $$""" + class C { - TestCode = source, - FixedCode = fixedSource, - Options = + int M(int x) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }; + x += {{rightHandSide}}; + return x; + } - if ((UnusedValuePreference)option == UnusedValuePreference.DiscardVariable) - { - test.TestState.ExpectedDiagnostics.Add( - // /0/Test0.cs(5,13): info IDE0059: Unnecessary assignment of a value to 'y' - VerifyCS.Diagnostic("IDE0059").WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("y")); + int M2() => 0; } + """; - await test.RunAsync(); - } - - [Theory] - [CombinatorialData] - public async Task CompoundAssignmentOperator_ValueUsed_LaterStatement( - [CombinatorialValues("1" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + await new VerifyCS.Test { - var source = - $$""" - class C - { - int M(int x) - { - x += {{rightHandSide}}; - return x; - } + TestCode = source, + FixedCode = source, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - int M2() => 0; + [Theory, CombinatorialData] + public async Task CompoundLogicalOrOperator_ValueUsed_LaterStatement( + [CombinatorialValues("true" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var source = + $$""" + class C + { + bool M(bool x) + { + x |= {{rightHandSide}} && {{rightHandSide}}; + return x; } - """; - await new VerifyCS.Test + bool M2() => true; + } + """; + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } + + [Theory, CombinatorialData] + public async Task CompoundLogicalOrOperator_ValueUsed_LaterStatement_02( + [CombinatorialValues("true" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + { + var source = + $$""" + class C { - TestCode = source, - FixedCode = source, - Options = + bool M() { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + bool x = false; + x |= {{rightHandSide}} && {{rightHandSide}}; + return x; + } + + bool M2() => true; + } + """; - [Theory] - [CombinatorialData] - public async Task CompoundLogicalOrOperator_ValueUsed_LaterStatement( - [CombinatorialValues("true" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) + await new VerifyCS.Test { - var source = - $$""" - class C - { - bool M(bool x) - { - x |= {{rightHandSide}} && {{rightHandSide}}; - return x; - } + TestCode = source, + FixedCode = source, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }.RunAsync(); + } - bool M2() => true; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task CompoundAssignmentOperator_ValueNotUsed_ConstantValue(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(int x) + { + [|x|] += 1; } - """; - - await new VerifyCS.Test + } + """, + """ + class C { - TestCode = source, - FixedCode = source, - Options = + int M(int x) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + } + } + """, optionName); + } - [Theory] - [CombinatorialData] - public async Task CompoundLogicalOrOperator_ValueUsed_LaterStatement_02( - [CombinatorialValues("true" /*Constant*/, "M2()" /*Non-constant*/)] string rightHandSide, - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option) - { - var source = - $$""" - class C + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "int unused")] + public async Task CompoundAssignmentOperator_ValueNotUsed_NonConstantValue(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + $$""" + class C + { + int M(int x) { - bool M() - { - bool x = false; - x |= {{rightHandSide}} && {{rightHandSide}}; - return x; - } - - bool M2() => true; + [|x|] += M2(); } - """; - await new VerifyCS.Test + int M2() => 0; + } + """, + $$""" + class C { - TestCode = source, - FixedCode = source, - Options = + int M(int x) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }.RunAsync(); - } + {{fix}} = M2(); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task CompoundAssignmentOperator_ValueNotUsed_ConstantValue(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NullCoalescing_ReadWrite(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M() { - int M(int x) - { - [|x|] += 1; - } + C [|x|] = M2(); + x = x ?? new C(); + return x; } - """, - """ - class C + + C M2() => null; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task LValueFlowCapture_Assignment_ControlFlowInAssignedTarget(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M(C y) { - int M(int x) - { - } + C [|x|] = M2(); + (x ?? y) = y; + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "int unused")] - public async Task CompoundAssignmentOperator_ValueNotUsed_NonConstantValue(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - $$""" - class C - { - int M(int x) - { - [|x|] += M2(); - } + C M2() => null; + } + """, optionName); + } - int M2() => 0; - } - """, - $$""" - class C + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused")] + public async Task LValueFlowCapture_Assignment_ControlFlowInAssignedValue_01(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + C M(C y, C z) { - int M(int x) - { - {{fix}} = M2(); - } - - int M2() => 0; + var [|x|] = M2(); + x = y ?? z; + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NullCoalescing_ReadWrite(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + C M2() => null; + } + """, + $$""" + class C + { + C M(C y, C z) { - C M() - { - C [|x|] = M2(); - x = x ?? new C(); - return x; - } - - C M2() => null; + {{fix}} = M2(); + C x = y ?? z; + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task LValueFlowCapture_Assignment_ControlFlowInAssignedTarget(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - C M(C y) - { - C [|x|] = M2(); - (x ?? y) = y; - return x; - } + C M2() => null; + } + """, optionName); + } - C M2() => null; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task LValueFlowCapture_Assignment_ControlFlowInAssignedValue_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M(C y, C z) + { + C [|x|] = M2(); + x = y ?? (x ?? z); + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused")] - public async Task LValueFlowCapture_Assignment_ControlFlowInAssignedValue_01(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C - { - C M(C y, C z) - { - var [|x|] = M2(); - x = y ?? z; - return x; - } + C M2() => null; + } + """, optionName); + } - C M2() => null; - } - """, - $$""" - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task LValueFlowCapture_DeconstructionAssignment_ControlFlowInAssignedTarget(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M(C y) { - C M(C y, C z) - { - {{fix}} = M2(); - C x = y ?? z; - return x; - } - - C M2() => null; + C [|x|] = M2(); + ((x ?? y), _) = (y, y); + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task LValueFlowCapture_Assignment_ControlFlowInAssignedValue_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - C M(C y, C z) - { - C [|x|] = M2(); - x = y ?? (x ?? z); - return x; - } + C M2() => null; + } + """, optionName); + } - C M2() => null; + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused")] + public async Task LValueFlowCapture_DeconstructionAssignment_ControlFlowInAssignedValue_01(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + C M(C y, C z) + { + var [|x|] = M2(); + (x, y) = (y ?? z, z); + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task LValueFlowCapture_DeconstructionAssignment_ControlFlowInAssignedTarget(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + C M2() => null; + } + """, + $$""" + class C + { + C M(C y, C z) { - C M(C y) - { - C [|x|] = M2(); - ((x ?? y), _) = (y, y); - return x; - } - - C M2() => null; + {{fix}} = M2(); + C x; + (x, y) = (y ?? z, z); + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused")] - public async Task LValueFlowCapture_DeconstructionAssignment_ControlFlowInAssignedValue_01(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C - { - C M(C y, C z) - { - var [|x|] = M2(); - (x, y) = (y ?? z, z); - return x; - } + C M2() => null; + } + """, optionName); + } - C M2() => null; - } - """, - $$""" - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task LValueFlowCapture_DeconstructionAssignment_ControlFlowInAssignedValue_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M(C y, C z) { - C M(C y, C z) - { - {{fix}} = M2(); - C x; - (x, y) = (y ?? z, z); - return x; - } - - C M2() => null; + C [|x|] = M2(); + (x, y) = (y ?? x, z); + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task LValueFlowCapture_DeconstructionAssignment_ControlFlowInAssignedValue_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - C M(C y, C z) - { - C [|x|] = M2(); - (x, y) = (y ?? x, z); - return x; - } + C M2() => null; + } + """, optionName); + } - C M2() => null; + [Fact] + public async Task Initialization_NonConstantValue_NoReferences_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + int [|x|] = M2(); } - """, optionName); - } - [Fact] - public async Task Initialization_NonConstantValue_NoReferences_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + void M() { - void M() - { - int [|x|] = M2(); - } - - int M2() => 0; + _ = M2(); } - """, - """ - class C - { - void M() - { - _ = M2(); - } - int M2() => 0; - } - """, options: PreferDiscard); - } + int M2() => 0; + } + """, options: PreferDiscard); + } - [Fact] - public async Task Initialization_NonConstantValue_NoReferences_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_NoReferences_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - int [|x|] = M2(); - } - - int M2() => 0; + int [|x|] = M2(); } - """, new TestParameters(options: PreferUnusedLocal)); - } - [Fact] - public async Task Initialization_NonConstantValue_NoReadReferences_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int [|x|] = M2(); - x = 0; - } + int M2() => 0; + } + """, new TestParameters(options: PreferUnusedLocal)); + } - int M2() => 0; - } - """, - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_NoReadReferences_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - _ = M2(); - int x = 0; - } - - int M2() => 0; + int [|x|] = M2(); + x = 0; } - """, options: PreferDiscard); - } - [Fact] - public async Task Initialization_NonConstantValue_NoReadReferences_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + void M() { - void M() - { - int [|x|] = M2(); - x = 0; - } + _ = M2(); + int x = 0; + } + + int M2() => 0; + } + """, options: PreferDiscard); + } - int M2() => 0; + [Fact] + public async Task Initialization_NonConstantValue_NoReadReferences_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + int [|x|] = M2(); + x = 0; } - """, new TestParameters(options: PreferUnusedLocal)); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task Initialization_ConstantValue_FirstField(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, new TestParameters(options: PreferUnusedLocal)); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task Initialization_ConstantValue_FirstField(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int [|x|] = 1, y = 2; - x = 2; - return x; - } + int [|x|] = 1, y = 2; + x = 2; + return x; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { - int y = 2; - int x = 2; - return x; - } + int y = 2; + int x = 2; + return x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task Initialization_ConstantValue_MiddleField(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task Initialization_ConstantValue_MiddleField(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int i = 0, [|x|] = 1, y = 2; - x = 2; - return x; - } + int i = 0, [|x|] = 1, y = 2; + x = 2; + return x; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { - int i = 0, y = 2; - int x = 2; - return x; - } + int i = 0, y = 2; + int x = 2; + return x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task Initialization_ConstantValue_LastField(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task Initialization_ConstantValue_LastField(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int i = 0, y = 2, [|x|] = 1; - x = 2; - return x; - } + int i = 0, y = 2, [|x|] = 1; + x = 2; + return x; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { - int i = 0, y = 2; - int x = 2; - return x; - } + int i = 0, y = 2; + int x = 2; + return x; } - """, optionName); - } + } + """, optionName); + } - [Fact] - public async Task Initialization_NonConstantValue_FirstField_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_FirstField_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int [|x|] = M2(), y = 2; - x = 2; - return x; - } - - void M2() => 0; + int [|x|] = M2(), y = 2; + x = 2; + return x; } - """, - """ - class C - { - int M() - { - _ = M2(); - int y = 2; - int x = 2; - return x; - } - void M2() => 0; + void M2() => 0; + } + """, + """ + class C + { + int M() + { + _ = M2(); + int y = 2; + int x = 2; + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task Initialization_NonConstantValue_FirstField_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M() - { - int [|x|] = M2(), y = 2; - x = 2; - return x; - } + void M2() => 0; + } + """, options: PreferDiscard); + } - void M2() => 0; - } - """, - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_FirstField_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int unused = M2(), y = 2; - int x = 2; - return x; - } - - void M2() => 0; + int [|x|] = M2(), y = 2; + x = 2; + return x; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task Initialization_NonConstantValue_MiddleField_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2() => 0; + } + """, + """ + class C + { + int M() { - int M() - { - int i = 0, [|x|] = M2(), y = 2; - x = 2; - return x; - } - - void M2() => 0; + int unused = M2(), y = 2; + int x = 2; + return x; } - """, - """ - class C - { - int M() - { - int i = 0; - _ = M2(); - int y = 2; - int x = 2; - return x; - } - void M2() => 0; - } - """, options: PreferDiscard); - } + void M2() => 0; + } + """, options: PreferUnusedLocal); + } - [Fact] - public async Task Initialization_NonConstantValue_MiddleField_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_MiddleField_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int i = 0, [|x|] = M2(), y = 2; - x = 2; - return x; - } - - void M2() => 0; + int i = 0, [|x|] = M2(), y = 2; + x = 2; + return x; } - """, - """ - class C - { - int M() - { - int i = 0, unused = M2(), y = 2; - int x = 2; - return x; - } - void M2() => 0; + void M2() => 0; + } + """, + """ + class C + { + int M() + { + int i = 0; + _ = M2(); + int y = 2; + int x = 2; + return x; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task Initialization_NonConstantValue_LastField_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M() - { - int i = 0, y = 2, [|x|] = M2(); - x = 2; - return x; - } + void M2() => 0; + } + """, options: PreferDiscard); + } - void M2() => 0; - } - """, - """ - class C + [Fact] + public async Task Initialization_NonConstantValue_MiddleField_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int i = 0, y = 2; - _ = M2(); - int x = 2; - return x; - } - - void M2() => 0; + int i = 0, [|x|] = M2(), y = 2; + x = 2; + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task Initialization_NonConstantValue_LastField_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2() => 0; + } + """, + """ + class C + { + int M() { - int M() - { - int i = 0, y = 2, [|x|] = M2(); - x = 2; - return x; - } - - void M2() => 0; + int i = 0, unused = M2(), y = 2; + int x = 2; + return x; } - """, - """ - class C - { - int M() - { - int i = 0, y = 2, unused = M2(); - int x = 2; - return x; - } - void M2() => 0; + void M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task Initialization_NonConstantValue_LastField_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() + { + int i = 0, y = 2, [|x|] = M2(); + x = 2; + return x; } - """, options: PreferUnusedLocal); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task Assignment_BeforeUseAsOutArgument(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + void M2() => 0; + } + """, + """ + class C + { + int M() { - int M() - { - int x; - [|x|] = 1; - M2(out x); - return x; - } + int i = 0, y = 2; + _ = M2(); + int x = 2; + return x; + } + + void M2() => 0; + } + """, options: PreferDiscard); + } - void M2(out int x) => x = 0; + [Fact] + public async Task Initialization_NonConstantValue_LastField_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() + { + int i = 0, y = 2, [|x|] = M2(); + x = 2; + return x; } - """, - """ - class C + + void M2() => 0; + } + """, + """ + class C + { + int M() { - int M() - { - int x; - M2(out x); - return x; - } + int i = 0, y = 2, unused = M2(); + int x = 2; + return x; + } + + void M2() => 0; + } + """, options: PreferUnusedLocal); + } - void M2(out int x) => x = 0; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task Assignment_BeforeUseAsOutArgument(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() + { + int x; + [|x|] = 1; + M2(out x); + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NonRedundantAssignment_BeforeUseAsRefArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M2(out int x) => x = 0; + } + """, + """ + class C + { + int M() { - int M() - { - int x; - [|x|] = 1; - M2(ref x); - return x; - } + int x; + M2(out x); + return x; + } - void M2(ref int x) => x = 0; + void M2(out int x) => x = 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NonRedundantAssignment_BeforeUseAsRefArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() + { + int x; + [|x|] = 1; + M2(ref x); + return x; } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40717")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NonRedundantAssignment_AfterUseAsRefArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(ref int x) => x = 0; + } + """, optionName); + } - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40717")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NonRedundantAssignment_AfterUseAsRefArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + static int Example() { - static int Example() - { - int value = 1; + int value = 1; - Span valueSpan = M(ref value); + Span valueSpan = M(ref value); - [|value = 2;|] + [|value = 2;|] - return valueSpan[0]; - } + return valueSpan[0]; + } - static Span M(ref int value) - { - return default; - } + static Span M(ref int value) + { + return default; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40483")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NonRedundantAssignment_AfterUseAsRefArgument_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40483")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NonRedundantAssignment_AfterUseAsRefArgument_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class P + class P + { + public ref bool f(ref bool z, ref bool q) { - public ref bool f(ref bool z, ref bool q) - { - z = ref q; - return ref z; - } + z = ref q; + return ref z; } + } - class Q + class Q + { + static void F() { - static void F() - { - bool a = true; - bool b = false; - ref var r = ref new P().f(ref a, ref b); - [|b = true|]; + bool a = true; + bool b = false; + ref var r = ref new P().f(ref a, ref b); + [|b = true|]; - Console.WriteLine(r); - } + Console.WriteLine(r); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NonRedundantAssignment_BeforeUseAsInArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NonRedundantAssignment_BeforeUseAsInArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int x; - [|x|] = 1; - M2(in x); - return x; - } - - void M2(in int x) { } + int x; + [|x|] = 1; + M2(in x); + return x; } - """, optionName); - } - [Fact] - public async Task OutArgument_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M() - { - int x; - M2(out [|x|]); - x = 1; - return x; - } + void M2(in int x) { } + } + """, optionName); + } - void M2(out int x) => x = 0; - } - """, - """ - class C + [Fact] + public async Task OutArgument_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int x; - M2(out _); - x = 1; - return x; - } - - void M2(out int x) => x = 0; + int x; + M2(out [|x|]); + x = 1; + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task OutArgument_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2(out int x) => x = 0; + } + """, + """ + class C + { + int M() { - int M() - { - int x; - M2(out [|x|]); - x = 1; - return x; - } - - void M2(out int x) => x = 0; + int x; + M2(out _); + x = 1; + return x; } - """, - """ - class C - { - int M() - { - int x; - int unused; - M2(out unused); - x = 1; - return x; - } - void M2(out int x) => x = 0; - } - """, options: PreferUnusedLocal); - } + void M2(out int x) => x = 0; + } + """, options: PreferDiscard); + } - [Fact] - public async Task OutVarArgument_ExpressionBody_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task OutArgument_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - void M() => M2(out var [|x|]); - void M2(out int x) => x = 0; + int x; + M2(out [|x|]); + x = 1; + return x; } - """, - """ - class C + + void M2(out int x) => x = 0; + } + """, + """ + class C + { + int M() { - void M() => M2(out _); - void M2(out int x) => x = 0; + int x; + int unused; + M2(out unused); + x = 1; + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task OutArgument_NoReads_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - int x; - M2(out [|x|]); + void M2(out int x) => x = 0; + } + """, options: PreferUnusedLocal); + } - // Unrelated, unused local should not be removed. - int unused; - } + [Fact] + public async Task OutVarArgument_ExpressionBody_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() => M2(out var [|x|]); + void M2(out int x) => x = 0; + } + """, + """ + class C + { + void M() => M2(out _); + void M2(out int x) => x = 0; + } + """, options: PreferDiscard); + } - void M2(out int x) => x = 0; - } - """, - """ - class C + [Fact] + public async Task OutArgument_NoReads_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - M2(out _); + int x; + M2(out [|x|]); - // Unrelated, unused local should not be removed. - int unused; - } - - void M2(out int x) => x = 0; + // Unrelated, unused local should not be removed. + int unused; } - """, options: PreferDiscard); - } - [Fact] - public async Task OutArgument_NoReads_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M2(out int x) => x = 0; + } + """, + """ + class C + { + void M() { - void M() - { - int x; - M2(out [|x|]); - } + M2(out _); - void M2(out int x) => x = 0; + // Unrelated, unused local should not be removed. + int unused; } - """, options: PreferUnusedLocal); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused")] - public async Task OutDeclarationExpressionArgument(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M() - { - M2(out var [|x|]); - x = 1; - return x; - } + void M2(out int x) => x = 0; + } + """, options: PreferDiscard); + } - void M2(out int x) => x = 0; - } - """, - $$""" - class C + [Fact] + public async Task OutArgument_NoReads_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - int M() - { - M2(out {{fix}}); - int x = 1; - return x; - } - - void M2(out int x) => x = 0; + int x; + M2(out [|x|]); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NonRedundantRefArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M2(out int x) => x = 0; + } + """, options: PreferUnusedLocal); + } + + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused")] + public async Task OutDeclarationExpressionArgument(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M(int x) - { - M2(ref [|x|]); - x = 1; - return x; - } + M2(out var [|x|]); + x = 1; + return x; + } - void M2(ref int x) => x = 0; + void M2(out int x) => x = 0; + } + """, + $$""" + class C + { + int M() + { + M2(out {{fix}}); + int x = 1; + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NonRedundantInArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M2(out int x) => x = 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NonRedundantRefArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M(int x) { - int M(int x) - { - M2(in [|x|]); - x = 1; - return x; - } + M2(ref [|x|]); + x = 1; + return x; + } - void M2(in int x) { } + void M2(ref int x) => x = 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NonRedundantInArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M(int x) + { + M2(in [|x|]); + x = 1; + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "unused")] - public async Task DeconstructionDeclarationExpression(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + void M2(in int x) { } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "unused")] + public async Task DeconstructionDeclarationExpression(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - var ([|x|], y) = (1, 1); - x = 1; - return x; - } + var ([|x|], y) = (1, 1); + x = 1; + return x; } - """, - $$""" - class C + } + """, + $$""" + class C + { + int M() { - int M() - { - var ({{fix}}, y) = (1, 1); - int x = 1; - return x; - } + var ({{fix}}, y) = (1, 1); + int x = 1; + return x; } - """, optionName); - } + } + """, optionName); + } - [Fact] - public async Task DeconstructionAssignment_01_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeconstructionAssignment_01_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int x, y; - ([|x|], y) = (1, 1); - x = 1; - return x; - } + int x, y; + ([|x|], y) = (1, 1); + x = 1; + return x; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { - int x, y; - (_, y) = (1, 1); - x = 1; - return x; - } + int x, y; + (_, y) = (1, 1); + x = 1; + return x; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact] - public async Task DeconstructionAssignment_01_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeconstructionAssignment_01_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int x, y; - ([|x|], y) = (1, 1); - x = 1; - return x; - } + int x, y; + ([|x|], y) = (1, 1); + x = 1; + return x; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { - int x, y; - int unused; - (unused, y) = (1, 1); - x = 1; - return x; - } + int x, y; + int unused; + (unused, y) = (1, 1); + x = 1; + return x; } - """, options: PreferUnusedLocal); - } + } + """, options: PreferUnusedLocal); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task DeconstructionAssignment_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task DeconstructionAssignment_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int [|x|] = 0, y = 0; - (x, y) = (x, y); - return x; - } + int [|x|] = 0, y = 0; + (x, y) = (x, y); + return x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused")] - public async Task TupleExpressionWithDeclarationExpressions(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused")] + public async Task TupleExpressionWithDeclarationExpressions(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - (var [|x|], var y) = (1, 1); - x = 1; - return x; - } + (var [|x|], var y) = (1, 1); + x = 1; + return x; } - """, - $$""" - class C + } + """, + $$""" + class C + { + int M() { - int M() - { - ({{fix}}, var y) = (1, 1); - int x = 1; - return x; - } + ({{fix}}, var y) = (1, 1); + int x = 1; + return x; } - """, optionName); - } + } + """, optionName); + } - [Fact] - public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int [|x|]: - x = 1; - break; - }; - } + case int [|x|]: + x = 1; + break; + }; } - """, - """ - class C + } + """, + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int _: - int x = 1; - break; - }; - } + case int _: + int x = 1; + break; + }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact] - public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_PreferDiscard_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_PreferDiscard_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int [|x|]: - x = 1; - break; - }; - } + case int [|x|]: + x = 1; + break; + }; } - """, - """ - class C + } + """, + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int: - int x = 1; - break; - }; - } + case int: + int x = 1; + break; + }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp9)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp9)); + } - [Theory] - [CombinatorialData] - public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_PreferUnusedLocal( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory, CombinatorialData] + public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_PreferUnusedLocal( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int [|x|]: - x = 1; - break; - }; - } + case int [|x|]: + x = 1; + break; + }; } - """, new TestParameters(options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion))); - } + } + """, new TestParameters(options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion))); + } - [Theory] - [CombinatorialData] - public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_TypePattern( - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) - { - var source = - """ - class C + [Theory, CombinatorialData] + public async Task DeclarationPatternInSwitchCase_WithOnlyWriteReference_TypePattern( + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int {|IDE0059:x|}: - {|IDE0059:x|} = 1; - break; - }; - } + case int {|IDE0059:x|}: + {|IDE0059:x|} = 1; + break; + }; } - """; - var (fixedSource, iterations) = testBehaviors switch - { - CodeFixTestBehaviors.None => + } + """; + var (fixedSource, iterations) = testBehaviors switch + { + CodeFixTestBehaviors.None => (""" class C { @@ -2839,7 +2826,7 @@ void M(object p) } } """, iterations: 2), - CodeFixTestBehaviors.FixOne => + CodeFixTestBehaviors.FixOne => (""" class C { @@ -2854,2885 +2841,2914 @@ void M(object p) } } """, iterations: 1), - _ => throw ExceptionUtilities.Unreachable(), - }; - - await new VerifyCS.Test - { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - LanguageVersion = LanguageVersion.CSharp9, - CodeFixTestBehaviors = testBehaviors, - NumberOfIncrementalIterations = iterations, - NumberOfFixAllIterations = iterations, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } + _ => throw ExceptionUtilities.Unreachable(), + }; - [Fact] - public async Task DeclarationPatternInIsPattern_WithNoReference_PreferDiscard() + await new VerifyCS.Test { - await TestInRegularAndScriptAsync( - """ - class C + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + LanguageVersion = LanguageVersion.CSharp9, + CodeFixTestBehaviors = testBehaviors, + NumberOfIncrementalIterations = iterations, + NumberOfFixAllIterations = iterations, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } + + [Fact] + public async Task DeclarationPatternInIsPattern_WithNoReference_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + if (p is C [|x|]) { - if (p is C [|x|]) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M(object p) { - void M(object p) + if (p is C) { - if (p is C) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact] - public async Task DeclarationPatternInIsPattern_WithNoReference_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeclarationPatternInIsPattern_WithNoReference_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + if (p is C [|x|]) { - if (p is C [|x|]) - { - } } } - """, options: PreferUnusedLocal); - } + } + """, options: PreferUnusedLocal); + } - [Fact] - public async Task DeclarationPatternInIsPattern_WithOnlyWriteReference_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeclarationPatternInIsPattern_WithOnlyWriteReference_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + if (p is C [|x|]) { - if (p is C [|x|]) - { - x = null; - } + x = null; } } - """, - """ - class C + } + """, + """ + class C + { + void M(object p) { - void M(object p) + if (p is C) { - if (p is C) - { - C x = null; - } + C x = null; } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact] - public async Task DeclarationPatternInIsPattern_WithOnlyWriteReference_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DeclarationPatternInIsPattern_WithOnlyWriteReference_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + if (p is C [|x|]) { - if (p is C [|x|]) - { - x = null; - } + x = null; } } - """, options: PreferUnusedLocal); - } + } + """, options: PreferUnusedLocal); + } - [Theory] - [InlineData(nameof(PreferDiscard), "C")] - [InlineData(nameof(PreferUnusedLocal), "C unused")] - public async Task DeclarationPatternInIsPattern_WithReadAndWriteReference(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard), "C")] + [InlineData(nameof(PreferUnusedLocal), "C unused")] + public async Task DeclarationPatternInIsPattern_WithReadAndWriteReference(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + if (p is C [|x|]) { - if (p is C [|x|]) - { - x = null; - p = x; - } + x = null; + p = x; } } - """, - $$""" - class C + } + """, + $$""" + class C + { + void M(object p) { - void M(object p) + if (p is {{fix}}) { - if (p is {{fix}}) - { - C x = null; - p = x; - } + C x = null; + p = x; } } - """, optionName: optionName); - } + } + """, optionName: optionName); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - public async Task DeclarationPatternInRecursivePattern_WithNoReference_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => false }; - } - } - """, - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + public async Task DeclarationPatternInRecursivePattern_WithNoReference_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p1, object p2) { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int _, int x2) => false }; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => false }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [CombinatorialData] - public async Task DeclarationPatternInRecursivePattern_WithNoReference_PreferUnusedLocal( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """, + """ + class C + { + void M(object p1, object p2) { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => false }; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int _, int x2) => false }; } - """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [CombinatorialData] - public async Task DeclarationPatternInRecursivePattern_WithNoReference_TypePattern( - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) - { - var source = - """ - class C - { - bool M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int {|IDE0059:x1|}, int {|IDE0059:x2|}) => false }; - return isZero; - } - } - """; - var batchFixedSource = - """ - class C - { - bool M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int, int) => false }; - return isZero; - } - } - """; - var fixedSource = testBehaviors switch + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [CombinatorialData] + public async Task DeclarationPatternInRecursivePattern_WithNoReference_PreferUnusedLocal( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestMissingInRegularAndScriptAsync( + """ + class C { - CodeFixTestBehaviors.None => batchFixedSource, - CodeFixTestBehaviors.FixOne => - """ - class C + void M(object p1, object p2) { - bool M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int, int {|IDE0059:x2|}) => false }; - return isZero; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => false }; } - """, - _ => throw ExceptionUtilities.Unreachable() - }; + } + """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion)); + } - await new VerifyCS.Test + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [CombinatorialData] + public async Task DeclarationPatternInRecursivePattern_WithNoReference_TypePattern( + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - BatchFixedCode = batchFixedSource, - LanguageVersion = LanguageVersion.CSharp9, - CodeFixTestBehaviors = testBehaviors, - Options = + bool M(object p1, object p2) { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - public async Task DeclarationPatternInRecursivePattern_WithOnlyWriteReference_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(out x1) }; - } - - bool M2(out int x) - { - x = 0; - return false; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int {|IDE0059:x1|}, int {|IDE0059:x2|}) => false }; + return isZero; } - """, - """ - class C + } + """; + var batchFixedSource = + """ + class C + { + bool M(object p1, object p2) { - void M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int _, int x2) => M2(out x1) }; - } - - bool M2(out int x) - { - x = 0; - return false; - } - } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [CombinatorialData] - public async Task DeclarationPatternInRecursivePattern_WithOnlyWriteReference_PreferUnusedLocal( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + var isZero = (p1, p2) switch { (0, 0) => true, (int, int) => false }; + return isZero; + } + } + """; + var fixedSource = testBehaviors switch { - await TestMissingInRegularAndScriptAsync( - """ - class C + CodeFixTestBehaviors.None => batchFixedSource, + CodeFixTestBehaviors.FixOne => + """ + class C + { + bool M(object p1, object p2) { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(out x1) }; - } - - bool M2(out int x) - { - x = 0; - return false; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int, int {|IDE0059:x2|}) => false }; + return isZero; } - """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion)); - } + } + """, + _ => throw ExceptionUtilities.Unreachable() + }; - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [CombinatorialData] - public async Task DeclarationPatternInRecursivePattern_WithOnlyWriteReference_TypePattern( - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + await new VerifyCS.Test { - var source = - """ - class C + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + BatchFixedCode = batchFixedSource, + LanguageVersion = LanguageVersion.CSharp9, + CodeFixTestBehaviors = testBehaviors, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + public async Task DeclarationPatternInRecursivePattern_WithOnlyWriteReference_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p1, object p2) { - bool M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int {|IDE0059:x1|}, int {|IDE0059:x2|}) => M2(out {|IDE0059:x1|}) }; - return isZero; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(out x1) }; + } - bool M2(out int x) - { - x = 0; - return false; - } + bool M2(out int x) + { + x = 0; + return false; } - """; - var batchFixedSource = - """ - class C + } + """, + """ + class C + { + void M(object p1, object p2) { - bool M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int, int) => M2(out _) }; - return isZero; - } + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int _, int x2) => M2(out x1) }; + } - bool M2(out int x) - { - x = 0; - return false; - } + bool M2(out int x) + { + x = 0; + return false; } - """; - var fixedSource = testBehaviors switch + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [CombinatorialData] + public async Task DeclarationPatternInRecursivePattern_WithOnlyWriteReference_PreferUnusedLocal( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestMissingInRegularAndScriptAsync( + """ + class C { - CodeFixTestBehaviors.None => batchFixedSource, - CodeFixTestBehaviors.FixOne => - """ - class C + void M(object p1, object p2) { - bool M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int, int {|IDE0059:x2|}) => M2(out {|IDE0059:x1|}) }; - return isZero; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(out x1) }; + } - bool M2(out int x) - { - x = 0; - return false; - } + bool M2(out int x) + { + x = 0; + return false; } - """, - _ => throw ExceptionUtilities.Unreachable(), - }; + } + """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion)); + } - await new VerifyCS.Test + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [CombinatorialData] + public async Task DeclarationPatternInRecursivePattern_WithOnlyWriteReference_TypePattern( + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - BatchFixedCode = batchFixedSource, - LanguageVersion = LanguageVersion.CSharp9, - CodeFixTestBehaviors = testBehaviors, - Options = + bool M(object p1, object p2) { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } + var isZero = (p1, p2) switch { (0, 0) => true, (int {|IDE0059:x1|}, int {|IDE0059:x2|}) => M2(out {|IDE0059:x1|}) }; + return isZero; + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "unused")] - public async Task DeclarationPatternInRecursivePattern_WithReadAndWriteReference(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(x1 = 0) && M2(x1) }; - } - - bool M2(int x) - { - return false; - } + x = 0; + return false; } - """, - $$""" - class C + } + """; + var batchFixedSource = + """ + class C + { + bool M(object p1, object p2) { - void M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int {{fix}}, int x2) => M2(x1 = 0) && M2(x1) }; - } - - bool M2(int x) - { - return false; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int, int) => M2(out _) }; + return isZero; } - """, optionName: optionName, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [InlineData(nameof(PreferDiscard), "")] - [InlineData(nameof(PreferUnusedLocal), " unused")] - public async Task DeclarationPatternInRecursivePattern_WithReadAndWriteReference_TypePatternxxxxxxxxxxxxxxxxxxxxxx(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) { - void M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(x1 = 0) && M2(x1) }; - } - - bool M2(int x) - { - return false; - } + x = 0; + return false; } - """, - $$""" - class C + } + """; + var fixedSource = testBehaviors switch + { + CodeFixTestBehaviors.None => batchFixedSource, + CodeFixTestBehaviors.FixOne => + """ + class C + { + bool M(object p1, object p2) { - void M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int{{fix}}, int x2) => M2(x1 = 0) && M2(x1) }; - } + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int, int {|IDE0059:x2|}) => M2(out {|IDE0059:x1|}) }; + return isZero; + } - bool M2(int x) - { - return false; - } + bool M2(out int x) + { + x = 0; + return false; } - """, optionName: optionName, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp9)); - } + } + """, + _ => throw ExceptionUtilities.Unreachable(), + }; - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] - [CombinatorialData] - public async Task DeclarationPatternInRecursivePattern_WithReadAndWriteReference_TypePattern( - [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck)] CodeFixTestBehaviors testBehaviors) + await new VerifyCS.Test { - var source = - """ - class C - { - bool M(object p1, object p2) - { - var isZero = (p1, p2) switch { (0, 0) => true, (int {|IDE0059:x1|}, int {|#0:x2|}) => M2(x1 = 0) && M2(x1) }; - return isZero; - } + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + BatchFixedCode = batchFixedSource, + LanguageVersion = LanguageVersion.CSharp9, + CodeFixTestBehaviors = testBehaviors, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } - bool M2(int {|IDE0060:x|}) - { - return false; - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "unused")] + public async Task DeclarationPatternInRecursivePattern_WithReadAndWriteReference(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p1, object p2) + { + var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(x1 = 0) && M2(x1) }; } - """; - var fixedSource = ((UnusedValuePreference)option, testBehaviors) switch + bool M2(int x) + { + return false; + } + } + """, + $$""" + class C { - (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.None) => - """ - class C + void M(object p1, object p2) { - bool M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int, int) => M2(x1 = 0) && M2(x1) }; - return isZero; - } + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int {{fix}}, int x2) => M2(x1 = 0) && M2(x1) }; + } - bool M2(int {|IDE0060:x|}) - { - return false; - } + bool M2(int x) + { + return false; } - """, - (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => - """ - class C + } + """, optionName: optionName, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [InlineData(nameof(PreferDiscard), "")] + [InlineData(nameof(PreferUnusedLocal), " unused")] + public async Task DeclarationPatternInRecursivePattern_WithReadAndWriteReference_TypePatternxxxxxxxxxxxxxxxxxxxxxx(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p1, object p2) { - bool M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int, int {|IDE0059:x2|}) => M2(x1 = 0) && M2(x1) }; - return isZero; - } + var isZero = (p1, p2) switch { (0, 0) => true, (int [|x1|], int x2) => M2(x1 = 0) && M2(x1) }; + } - bool M2(int {|IDE0060:x|}) - { - return false; - } + bool M2(int x) + { + return false; } - """, - (UnusedValuePreference.UnusedLocalVariable, _) => - """ - class C + } + """, + $$""" + class C + { + void M(object p1, object p2) { - bool M(object p1, object p2) - { - int x1; - var isZero = (p1, p2) switch { (0, 0) => true, (int unused, int x2) => M2(x1 = 0) && M2(x1) }; - return isZero; - } + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int{{fix}}, int x2) => M2(x1 = 0) && M2(x1) }; + } - bool M2(int {|IDE0060:x|}) - { - return false; - } + bool M2(int x) + { + return false; } - """, - _ => throw ExceptionUtilities.Unreachable(), - }; + } + """, optionName: optionName, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp9)); + } - var test = new VerifyCS.Test + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32271")] + [CombinatorialData] + public async Task DeclarationPatternInRecursivePattern_WithReadAndWriteReference_TypePattern( + [CombinatorialValues(UnusedValuePreference.DiscardVariable, UnusedValuePreference.UnusedLocalVariable)] object option, + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - LanguageVersion = LanguageVersion.CSharp9, - CodeFixTestBehaviors = testBehaviors, - Options = + bool M(object p1, object p2) { - { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, - }, - }; + var isZero = (p1, p2) switch { (0, 0) => true, (int {|IDE0059:x1|}, int {|#0:x2|}) => M2(x1 = 0) && M2(x1) }; + return isZero; + } - if ((UnusedValuePreference)option == UnusedValuePreference.DiscardVariable) - { - test.TestState.ExpectedDiagnostics.Add( - // /0/Test0.cs(5,69): info IDE0059: Unnecessary assignment of a value to 'x2' - VerifyCS.Diagnostic("IDE0059").WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("x2")); + bool M2(int {|IDE0060:x|}) + { + return false; + } } + """; - await test.RunAsync(); - } - - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_WithInvocation(string optionName) + var fixedSource = ((UnusedValuePreference)option, testBehaviors) switch { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C + (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.None) => + """ + class C + { + bool M(object p1, object p2) { - void M(object p) - { - Action lambda = () => - { - var x = p; - }; - - [|p|] = null; - lambda(); - } + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int, int) => M2(x1 = 0) && M2(x1) }; + return isZero; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_WithInvocation_DefinedAtStart(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C + bool M2(int {|IDE0060:x|}) { - void M(object p) - { - void LocalFunction() - { - var x = p; - } - - [|p|] = null; - LocalFunction(); - } + return false; } - """, optionName); - } - - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_WithInvocation_DefinedAtEnd(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C + } + """, + (UnusedValuePreference.DiscardVariable, CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck) => + """ + class C + { + bool M(object p1, object p2) { - void M(object p) - { - [|p|] = null; - LocalFunction(); - - void LocalFunction() - { - var x = p; - } - } + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int, int {|IDE0059:x2|}) => M2(x1 = 0) && M2(x1) }; + return isZero; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_WithoutInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; - - class C + bool M2(int {|IDE0060:x|}) { - void M(object p) - { - [|p|] = null; - Action lambda = () => - { - var x = p; - }; - } + return false; + } + } + """, + (UnusedValuePreference.UnusedLocalVariable, _) => + """ + class C + { + bool M(object p1, object p2) + { + int x1; + var isZero = (p1, p2) switch { (0, 0) => true, (int unused, int x2) => M2(x1 = 0) && M2(x1) }; + return isZero; } - """, - """ - using System; - class C + bool M2(int {|IDE0060:x|}) { - void M(object p) - { - Action lambda = () => - { - var x = p; - }; - } + return false; } - """, optionName); - } + } + """, + _ => throw ExceptionUtilities.Unreachable(), + }; - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_WithoutInvocation_DefinedAtStart(string optionName) + var test = new VerifyCS.Test { - await TestInRegularAndScriptAsync( - """ - using System; + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + LanguageVersion = LanguageVersion.CSharp9, + CodeFixTestBehaviors = testBehaviors, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, (UnusedValuePreference)option }, + }, + }; - class C - { - void M(object p) - { - void LocalFunction() - { - var x = p; - } - [|p|] = null; - } - } - """, - """ - using System; + if ((UnusedValuePreference)option == UnusedValuePreference.DiscardVariable) + { + test.TestState.ExpectedDiagnostics.Add( + // /0/Test0.cs(5,69): info IDE0059: Unnecessary assignment of a value to 'x2' + VerifyCS.Diagnostic("IDE0059").WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("x2")); + } + + await test.RunAsync(); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_WithInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - void LocalFunction() - { - var x = p; - } - } + var x = p; + }; + + [|p|] = null; + lambda(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_WithoutInvocation_DefinedAtEnd(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_WithInvocation_DefinedAtStart(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - [|p|] = null; - void LocalFunction() - { - var x = p; - } + var x = p; } + + [|p|] = null; + LocalFunction(); } - """, - """ - using System; + } + """, optionName); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_WithInvocation_DefinedAtEnd(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + LocalFunction(); + + void LocalFunction() { - void LocalFunction() - { - var x = p; - } + var x = p; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUseInLambda_WithInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_WithoutInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + Action lambda = () => { - Action lambda = () => - { - }; - [|p|] = null; - lambda(); - } + var x = p; + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - Action lambda = () => - { - }; - lambda(); - } + var x = p; + }; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUseInLocalFunction_WithInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_WithoutInvocation_DefinedAtStart(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - [|p|] = null; - LocalFunction(); - void LocalFunction() - { - } + var x = p; } + [|p|] = null; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - LocalFunction(); - void LocalFunction() - { - } + var x = p; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUseInLambda_WithoutInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_WithoutInvocation_DefinedAtEnd(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + void LocalFunction() { - [|p|] = null; - Action lambda = () => - { - }; + var x = p; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - Action lambda = () => - { - }; + var x = p; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUseInLocalFunction_WithoutInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUseInLambda_WithInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - [|p|] = null; - void LocalFunction() - { - } - } + }; + [|p|] = null; + lambda(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - void LocalFunction() - { - } - } + }; + lambda(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task RedundantWriteInLambda_WithInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUseInLocalFunction_WithInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + LocalFunction(); + void LocalFunction() { - Action lambda = () => - { - [|p|] = null; - }; - lambda(); } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + LocalFunction(); + void LocalFunction() { - Action lambda = () => - { - }; - lambda(); } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task RedundantWriteInLocalFunction_WithInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUseInLambda_WithoutInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + Action lambda = () => { - LocalFunction(); - void LocalFunction() - { - [|p|] = null; - } - } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - LocalFunction(); - void LocalFunction() - { - } - } + }; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task WriteThenReadInLambda_WithInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUseInLocalFunction_WithoutInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + void LocalFunction() { - Action lambda = () => - { - [|p|] = null; - var x = p; - }; - lambda(); } } - """, optionName); - } - - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task WriteThenReadInLocalFunction_WithInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - LocalFunction(); - void LocalFunction() - { - [|p|] = null; - var x = p; - } } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task RedundantWriteInLambda_WithoutInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task RedundantWriteInLambda_WithInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - Action lambda = () => - { - [|p|] = null; - }; - } + [|p|] = null; + }; + lambda(); } - """, optionName); - } - - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task RedundantWriteInLocalFunction_WithoutInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - void LocalFunction() - { - [|p|] = null; - } - } + }; + lambda(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_Nested(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task RedundantWriteInLocalFunction_WithInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + LocalFunction(); + void LocalFunction() { - Action outerLambda = () => - { - Action innerLambda = () => - { - var x = p; - }; - - innerLambda(); - }); - [|p|] = null; - outerLambda(); } + } + } + """, + """ + using System; - void M2(Action a) => a(); + class C + { + void M(object p) + { + LocalFunction(); + void LocalFunction() + { + } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_NestedLocalFunction(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task WriteThenReadInLambda_WithInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { [|p|] = null; - OuterLocalFunction(); - - void OuterLocalFunction() - { - InnerLocalFunction(); - - void InnerLocalFunction() - { - var x = p; - } - }); - } - - void M2(Action a) => a(); + var x = p; + }; + lambda(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_NestedLocalFunction(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task WriteThenReadInLocalFunction_WithInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p, Action outerDelegate) + LocalFunction(); + void LocalFunction() { [|p|] = null; - outerDelegate(() => - { - InnerLocalFunction(); - void InnerLocalFunction() - { - var x = p; - } - }); + var x = p; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_NestedLambda(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task RedundantWriteInLambda_WithoutInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p, Action myDelegate) + Action lambda = () => { [|p|] = null; - OuterLocalFunction(); - - void OuterLocalFunction() - { - myDelegate(() => - { - var x = p; - }); - } - } + }; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInNestedLambda_InvokedInOuterFunction(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task RedundantWriteInLocalFunction_WithoutInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p, Action myDelegate) + void LocalFunction() { [|p|] = null; - OuterLocalFunction(); - myDelegate(); - - void OuterLocalFunction() - { - myDelegate = () => - { - var x = p; - }; - } } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInNestedLocalFunction_InvokedInOuterFunction(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_Nested(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p, Action myDelegate) + Action outerLambda = () => { - [|p|] = null; - OuterLocalFunction(); - myDelegate(); - - void OuterLocalFunction() + Action innerLambda = () => { - myDelegate = NestedLocalFunction; - void NestedLocalFunction() - { - var x = p; - } - } - } + var x = p; + }; + + innerLambda(); + }); + + [|p|] = null; + outerLambda(); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_ArgumentToLambda(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_NestedLocalFunction(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p, Action myDelegate) + [|p|] = null; + OuterLocalFunction(); + + void OuterLocalFunction() { - [|p|] = null; - myDelegate(p); - } + InnerLocalFunction(); + + void InnerLocalFunction() + { + var x = p; + } + }); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_ArgumentToLambda_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_NestedLocalFunction(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p, Action outerDelegate) { - Action M(object p, Action myDelegate) + [|p|] = null; + outerDelegate(() => { - [|p|] = null; - return d => { myDelegate(0); }; - } + InnerLocalFunction(); + void InnerLocalFunction() + { + var x = p; + } + }); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_PassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_NestedLambda(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, Action myDelegate) { - void M(object p) + [|p|] = null; + OuterLocalFunction(); + + void OuterLocalFunction() { - [|p|] = null; - M2(() => + myDelegate(() => { var x = p; }); } - - void M2(Action a) => a(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_PassedAsArgument_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInNestedLambda_InvokedInOuterFunction(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, Action myDelegate) { - public C(bool flag) - { - Flag = flag; - } + [|p|] = null; + OuterLocalFunction(); + myDelegate(); - public bool Flag { get; } - public static bool M() + void OuterLocalFunction() { - bool flag = true; - var c = Create(() => flag); - - M2(c); - [|flag|] = false; - return M2(c); + myDelegate = () => + { + var x = p; + }; } - - private static C Create(Func isFlagTrue) { return new C(isFlagTrue()); } - private static bool M2(C c) => c.Flag; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_PassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInNestedLocalFunction_InvokedInOuterFunction(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, Action myDelegate) { - void M(object p) - { - [|p|] = null; - M2(LocalFunction); + [|p|] = null; + OuterLocalFunction(); + myDelegate(); - void LocalFunction() + void OuterLocalFunction() + { + myDelegate = NestedLocalFunction; + void NestedLocalFunction() { var x = p; } } + } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_ArgumentToLambda(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - void M2(Action a) => a(); + class C + { + void M(object p, Action myDelegate) + { + [|p|] = null; + myDelegate(p); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_PassedAsArgument_CustomDelegate(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_ArgumentToLambda_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + Action M(object p, Action myDelegate) + { + [|p|] = null; + return d => { myDelegate(0); }; + } + } + """, optionName); + } - public delegate void MyAction(); + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_PassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + M2(() => { - [|p|] = null; - M2(() => - { - var x = p; - }); - } - - void M2(MyAction a) => a(); + var x = p; + }); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_PassedAsArgument_CustomDelegate(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } - public delegate void MyAction(); + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_PassedAsArgument_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public C(bool flag) { - void M(object p) - { - [|p|] = null; - M2(LocalFunction); + Flag = flag; + } - void LocalFunction() - { - var x = p; - } - } + public bool Flag { get; } + public static bool M() + { + bool flag = true; + var c = Create(() => flag); - void M2(MyAction a) => a(); + M2(c); + [|flag|] = false; + return M2(c); } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UnusedInExpressionTree_PassedAsArgument(string optionName) - { - // Currently we bail out of analysis in presence of expression trees. - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; + private static C Create(Func isFlagTrue) { return new C(isFlagTrue()); } + private static bool M2(C c) => c.Flag; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_PassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - public static void M1() + [|p|] = null; + M2(LocalFunction); + + void LocalFunction() { - object [|p|] = null; - M2(x => x.M3()); + var x = p; } - - private static C M2(Expression> a) { return null; } - private int M3() { return 0; } } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ReadInExpressionTree_PassedAsArgument(string optionName) - { - // Currently we bail out of analysis in presence of expression trees. - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_PassedAsArgument_CustomDelegate(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + public delegate void MyAction(); + + class C + { + void M(object p) { - public static void M1() + [|p|] = null; + M2(() => { - object [|p|] = null; - M2(x => x.M3(p)); - } - - private static C M2(Expression> a) { return null; } - private int M3(object o) { return 0; } + var x = p; + }); } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task OnlyWrittenInExpressionTree_PassedAsArgument(string optionName) - { - // Currently we bail out of analysis in presence of expression trees. - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; + void M2(MyAction a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_PassedAsArgument_CustomDelegate(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + public delegate void MyAction(); - class C + class C + { + void M(object p) { - public static void M1() + [|p|] = null; + M2(LocalFunction); + + void LocalFunction() { - object [|p|] = null; - M2(x => x.M3(out p)); + var x = p; } + } + + void M2(MyAction a) => a(); + } + """, optionName); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UnusedInExpressionTree_PassedAsArgument(string optionName) + { + // Currently we bail out of analysis in presence of expression trees. + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; - private static C M2(Expression> a) { return null; } - private int M3(out object o) { o = null; return 0; } + class C + { + public static void M1() + { + object [|p|] = null; + M2(x => x.M3()); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_PassedAsArgument_CastFromDelegateType(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + private static C M2(Expression> a) { return null; } + private int M3() { return 0; } + } + """, optionName); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ReadInExpressionTree_PassedAsArgument(string optionName) + { + // Currently we bail out of analysis in presence of expression trees. + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; - class C + class C + { + public static void M1() { - void M(object p) - { - Action a = () => - { - var x = p; - }; + object [|p|] = null; + M2(x => x.M3(p)); + } - object o = a; - [|p|] = null; - M2(o); - } + private static C M2(Expression> a) { return null; } + private int M3(object o) { return 0; } + } + """, optionName); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31744")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task OnlyWrittenInExpressionTree_PassedAsArgument(string optionName) + { + // Currently we bail out of analysis in presence of expression trees. + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; - void M2(object a) => ((Action)a)(); + class C + { + public static void M1() + { + object [|p|] = null; + M2(x => x.M3(out p)); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_PassedAsArgument_CastFromDelegateType(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + private static C M2(Expression> a) { return null; } + private int M3(out object o) { o = null; return 0; } + } + """, optionName); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_PassedAsArgument_CastFromDelegateType(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p) { - void M(object p) + Action a = () => { - object o = (Action)LocalFunction; - [|p|] = null; - M2(o); - - void LocalFunction() - { - var x = p; - } - } + var x = p; + }; - void M2(object a) => ((Action)a)(); + object o = a; + [|p|] = null; + M2(o); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_DelegateCreationPassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(object a) => ((Action)a)(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_PassedAsArgument_CastFromDelegateType(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + object o = (Action)LocalFunction; + [|p|] = null; + M2(o); + + void LocalFunction() { - [|p|] = null; - M2(new Action(() => - { - var x = p; - })); + var x = p; } - - void M2(Action a) => a(); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_DelegateCreationPassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(object a) => ((Action)a)(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_DelegateCreationPassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + [|p|] = null; + M2(new Action(() => { - [|p|] = null; - M2(new Action(LocalFunction)); - - void LocalFunction() - { - var x = p; - } - } - - void M2(Action a) => a(); + var x = p; + })); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_DelegatePassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_DelegateCreationPassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) - { - Action local = () => - { - var x = p; - }; + [|p|] = null; + M2(new Action(LocalFunction)); - [|p|] = null; - M2(local); + void LocalFunction() + { + var x = p; } - - void M2(Action a) => a(); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_DelegatePassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_DelegatePassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action local = () => { - Action local = LocalFunction; - [|p|] = null; - M2(local); - - void LocalFunction() - { - var x = p; - } - } + var x = p; + }; - void M2(Action a) => a(); + [|p|] = null; + M2(local); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task WrittenInLambda_DelegatePassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_DelegatePassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p) { - void M(object p, object p2) + Action local = LocalFunction; + [|p|] = null; + M2(local); + + void LocalFunction() { - Action local = () => - { - p = p2; - }; + var x = p; + } + } - [|p|] = null; - M2(local); + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task WrittenInLambda_DelegatePassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p, object p2) + { + Action local = () => + { + p = p2; + }; - var x = p; - } + [|p|] = null; + M2(local); - void M2(Action a) => a(); + var x = p; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task WrittenInLocalFunction_DelegatePassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task WrittenInLocalFunction_DelegatePassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, object p2) { - void M(object p, object p2) - { - Action local = LocalFunction; - [|p|] = null; - M2(local); - var x = p; + Action local = LocalFunction; + [|p|] = null; + M2(local); + var x = p; - void LocalFunction() - { - p = p2; - } + void LocalFunction() + { + p = p2; } - - void M2(Action a) => a(); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task WrittenInLambdaAndLocalFunctionTargets_DelegatePassedAsArgument(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task WrittenInLambdaAndLocalFunctionTargets_DelegatePassedAsArgument(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p, object p2) { - void M(object p, object p2) + Action lambda = () => { - Action lambda = () => - { - p = p2; - }; + p = p2; + }; - Action myDelegate; - if (p2 != null) - { - myDelegate = lambda; - } - else - { - myDelegate = LocalFunction; - } + Action myDelegate; + if (p2 != null) + { + myDelegate = lambda; + } + else + { + myDelegate = LocalFunction; + } - [|p|] = null; - M2(myDelegate); + [|p|] = null; + M2(myDelegate); - var x = p; + var x = p; - void LocalFunction() - { - p = p2; - } + void LocalFunction() + { + p = p2; } - - void M2(Action a) => a(); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_ReturnedDelegateCreation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) => a(); + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_ReturnedDelegateCreation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + Action M(object p) { - Action M(object p) + [|p|] = null; + return new Action(() => { - [|p|] = null; - return new Action(() => - { - var x = p; - }); - } + var x = p; + }); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_ReturnedDelegateCreation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_ReturnedDelegateCreation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + Action M(object p) { - Action M(object p) - { - [|p|] = null; - return new Action(LocalFunction); + [|p|] = null; + return new Action(LocalFunction); - void LocalFunction() - { - var x = p; - }; - } + void LocalFunction() + { + var x = p; + }; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_ReturnedDelegate(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_ReturnedDelegate(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + Action M(object p) { - Action M(object p) + Action local = () => { - Action local = () => - { - var x = p; - }; + var x = p; + }; - [|p|] = null; - return local; - } + [|p|] = null; + return local; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_ReturnedDelegate(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_ReturnedDelegate(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + Action M(object p) { - Action M(object p) - { - [|p|] = null; - return LocalFunction; + [|p|] = null; + return LocalFunction; - void LocalFunction() - { - var x = p; - } + void LocalFunction() + { + var x = p; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_InvokedDelegate_ControlFlow(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_InvokedDelegate_ControlFlow(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, bool flag) { - void M(object p, bool flag) + Action local1 = () => { - Action local1 = () => - { - var x = p; - }; + var x = p; + }; - Action local2 = () => { }; + Action local2 = () => { }; - [|p|] = null; - var y = flag ? local1 : local2; - y(); - } + [|p|] = null; + var y = flag ? local1 : local2; + y(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_InvokedDelegate_ControlFlow(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_InvokedDelegate_ControlFlow(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, bool flag) { - void M(object p, bool flag) - { - [|p|] = null; - (flag ? LocalFunction1 : (Action)LocalFunction2)(); + [|p|] = null; + (flag ? LocalFunction1 : (Action)LocalFunction2)(); - void LocalFunction1() - { - var x = p; - } + void LocalFunction1() + { + var x = p; + } - void LocalFunction2() - { - } + void LocalFunction2() + { } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_LambdaAndLocalFunctionTargets(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_LambdaAndLocalFunctionTargets(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, bool flag, bool flag2) { - void M(object p, bool flag, bool flag2) + Action lambda = () => { - Action lambda = () => - { - var x = p; - }; - - [|p|] = null; - var y = flag ? lambda : (flag2 ? (Action)LocalFunction : M2); - y(); + var x = p; + }; - void LocalFunction() { } - } + [|p|] = null; + var y = flag ? lambda : (flag2 ? (Action)LocalFunction : M2); + y(); - void M2() { } + void LocalFunction() { } } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUsed_LambdaAndLocalFunctionTargets(string optionName) - { - // Below should be changed to verify diagnostic/fix once we - // perform points-to-analysis for accurate delegate target tracking. - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2() { } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUsed_LambdaAndLocalFunctionTargets(string optionName) + { + // Below should be changed to verify diagnostic/fix once we + // perform points-to-analysis for accurate delegate target tracking. + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, bool flag, bool flag2) { - void M(object p, bool flag, bool flag2) + Action lambda = () => { - Action lambda = () => - { - }; - - [|p|] = null; - var y = flag ? lambda : (flag2 ? (Action)LocalFunction : M2); - y(); + }; - void LocalFunction() { } - } + [|p|] = null; + var y = flag ? lambda : (flag2 ? (Action)LocalFunction : M2); + y(); - void M2() { } + void LocalFunction() { } } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_LambdaAndLocalFunctionTargets_ThroughLocalsAndParameters(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2() { } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_LambdaAndLocalFunctionTargets_ThroughLocalsAndParameters(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, bool flag, bool flag2, Action param) { - void M(object p, bool flag, bool flag2, Action param) + Action lambda = () => { - Action lambda = () => - { - var x = p; - }; + var x = p; + }; - [|p|] = null; + [|p|] = null; - Action y; - if (flag) + Action y; + if (flag) + { + if (flag2) { - if (flag2) - { - y = (Action)LocalFunction; - } - else - { - y = M2; - } + y = (Action)LocalFunction; } else { - y = null; - if (flag2) - { - param = lambda; - } - else - { - param = M2; - } + y = M2; } - - Action z; - if (y != null) + } + else + { + y = null; + if (flag2) { - z = y; + param = lambda; } else { - z = param; + param = M2; } + } - z(); - - void LocalFunction() { } + Action z; + if (y != null) + { + z = y; + } + else + { + z = param; } - void M2() { } + z(); + + void LocalFunction() { } } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUsed_LambdaAndLocalFunctionTargets_ThroughLocalsAndParameters(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + void M2() { } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUsed_LambdaAndLocalFunctionTargets_ThroughLocalsAndParameters(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p, bool flag, bool flag2, Action param) { - void M(object p, bool flag, bool flag2, Action param) + Action lambda = () => { - Action lambda = () => - { - }; + }; - [|p|] = null; + [|p|] = null; - Action y; - if (flag) + Action y; + if (flag) + { + if (flag2) { - if (flag2) - { - y = (Action)LocalFunction; - } - else - { - y = M2; - } + y = (Action)LocalFunction; } else { - y = null; - if (flag2) - { - param = lambda; - } - else - { - param = M2; - } + y = M2; } - - Action z; - if (y != null) + } + else + { + y = null; + if (flag2) { - z = y; + param = lambda; } else { - z = param; + param = M2; } + } - z(); - - void LocalFunction() { } + Action z; + if (y != null) + { + z = y; + } + else + { + z = param; } - void M2() { } + z(); + + void LocalFunction() { } } - """, - """ - using System; - class C + void M2() { } + } + """, + """ + using System; + + class C + { + void M(object p, bool flag, bool flag2, Action param) { - void M(object p, bool flag, bool flag2, Action param) + Action lambda = () => { - Action lambda = () => - { - }; - Action y; - if (flag) + }; + Action y; + if (flag) + { + if (flag2) { - if (flag2) - { - y = (Action)LocalFunction; - } - else - { - y = M2; - } + y = (Action)LocalFunction; } else { - y = null; - if (flag2) - { - param = lambda; - } - else - { - param = M2; - } + y = M2; } - - Action z; - if (y != null) + } + else + { + y = null; + if (flag2) { - z = y; + param = lambda; } else { - z = param; + param = M2; } + } - z(); - - void LocalFunction() { } + Action z; + if (y != null) + { + z = y; + } + else + { + z = param; } - void M2() { } + z(); + + void LocalFunction() { } } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLambda_UsedAfterInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2() { } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLambda_UsedAfterInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + int M(int x) { - int M(int x) + Action a = () => { - Action a = () => - { - [|x|] = 1; - }; - a(); + [|x|] = 1; + }; + a(); - return x; - } + return x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLocalFunction_UsedAfterInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLocalFunction_UsedAfterInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + int M(int x) { - int M(int x) - { - a(); + a(); - return x; + return x; - void a() - { - [|x|] = 1; - } + void a() + { + [|x|] = 1; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLambda_UsedAfterSecondInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLambda_UsedAfterSecondInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + int M(int x) { - int M(int x) - { - Action a = () => - { - [|x|] = 1; - }; + Action a = () => + { + [|x|] = 1; + }; - a(); - a(); + a(); + a(); - return x; - } + return x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLocalFunction_UsedAfterSecondInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLocalFunction_UsedAfterSecondInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + int M(int x) { - int M(int x) - { - a(); - a(); + a(); + a(); - return x; + return x; - void a() - { - [|x|] = 1; - } + void a() + { + [|x|] = 1; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLambda_MayBeUsedAfterOneOfTheInvocations(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLambda_MayBeUsedAfterOneOfTheInvocations(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + int M(int x, bool flag, bool flag2) { - int M(int x, bool flag, bool flag2) + Action a = () => { - Action a = () => - { - [|x|] = 1; - }; + [|x|] = 1; + }; - a(); + a(); - if (flag) + if (flag) + { + a(); + if (flag2) { - a(); - if (flag2) - { - return x; - } + return x; } - - return 0; } + + return 0; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLocalFunction_MayBeUsedAfterOneOfTheInvocations(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLocalFunction_MayBeUsedAfterOneOfTheInvocations(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + int M(int x, bool flag, bool flag2) { - int M(int x, bool flag, bool flag2) + a(); + + if (flag) { a(); - - if (flag) + if (flag2) { - a(); - if (flag2) - { - return x; - } + return x; } + } - return 0; + return 0; - void a() - { - [|x|] = 1; - } + void a() + { + [|x|] = 1; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLambda_NotUsedAfterInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLambda_NotUsedAfterInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + Action a = () => { - Action a = () => - { - [|x|] = 1; - }; - a(); - } + [|x|] = 1; + }; + a(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + Action a = () => { - Action a = () => - { - }; - a(); - } + }; + a(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInLocalFunction_NotUsedAfterInvocation(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInLocalFunction_NotUsedAfterInvocation(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) - { - a(); + a(); - void a() - { - [|x|] = 1; - } + void a() + { + [|x|] = 1; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) - { - a(); + a(); - void a() - { - } + void a() + { } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_WithRecursiveInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_WithRecursiveInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - void LocalFunction() - { - var x = p; - LocalFunction(); - } - - [|p|] = null; + var x = p; LocalFunction(); } + + [|p|] = null; + LocalFunction(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task NotUseInLocalFunction_WithRecursiveInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task NotUseInLocalFunction_WithRecursiveInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + void LocalFunction() { - void LocalFunction() - { - LocalFunction(); - } - - [|p|] = null; LocalFunction(); } + + [|p|] = null; + LocalFunction(); } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task Lambda_WithNonReachableExit(string optionName) - { - // We bail out from analysis for delegate passed an argument. - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task Lambda_WithNonReachableExit(string optionName) + { + // We bail out from analysis for delegate passed an argument. + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action throwEx = () => { - Action throwEx = () => - { - throw new Exception(); - }; - - [|p|] = null; - M2(throwEx); - } + throw new Exception(); + }; - void M2(Action a) { } + [|p|] = null; + M2(throwEx); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task Lambda_WithMultipleInvocations(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void M2(Action a) { } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task Lambda_WithMultipleInvocations(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + Action lambda = () => { - Action lambda = () => - { - var x = p; - [|p|] = null; // This write is read on next invocation of lambda. - }; + var x = p; + [|p|] = null; // This write is read on next invocation of lambda. + }; - M2(lambda); - } + M2(lambda); + } - void M2(Action a) - { - a(); - a(); - } + void M2(Action a) + { + a(); + a(); } - """, optionName); - } + } + """, optionName); + } - [Fact] - public async Task UnusedValue_DelegateTypeOptionalParameter_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UnusedValue_DelegateTypeOptionalParameter_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - var [|x|] = M2(); - } - - C M2(Action c = null) => null; + var [|x|] = M2(); } - """, - """ - using System; - class C - { - void M() - { - _ = M2(); - } + C M2(Action c = null) => null; + } + """, + """ + using System; - C M2(Action c = null) => null; + class C + { + void M() + { + _ = M2(); } - """, options: PreferDiscard); - } - [Fact] - public async Task UnusedValue_DelegateTypeOptionalParameter_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + C M2(Action c = null) => null; + } + """, options: PreferDiscard); + } - class C - { - void M() - { - var [|x|] = M2(); - } + [Fact] + public async Task UnusedValue_DelegateTypeOptionalParameter_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - C M2(Action c = null) => null; + class C + { + void M() + { + var [|x|] = M2(); } - """, options: PreferUnusedLocal); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLocalFunction_NestedInvocation(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + C M2(Action c = null) => null; + } + """, options: PreferUnusedLocal); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLocalFunction_NestedInvocation(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + LocalFunction(); + + bool LocalFunction2() { - LocalFunction(); + return true; + } - bool LocalFunction2() + void LocalFunction() + { + object [|p|] = null; + if (LocalFunction2()) { - return true; } - void LocalFunction() + if (p != null) { - object [|p|] = null; - if (LocalFunction2()) - { - } - - if (p != null) - { - } } } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "unused")] - public async Task DeclarationPatternInSwitchCase_WithReadAndWriteReferences(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "unused")] + public async Task DeclarationPatternInSwitchCase_WithReadAndWriteReferences(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int [|x|]: - x = 1; - p = x; - break; - } + case int [|x|]: + x = 1; + p = x; + break; } } - """, - $$""" - class C + } + """, + $$""" + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case int {{fix}}: - int x = 1; - p = x; - break; - } + case int {{fix}}: + int x = 1; + p = x; + break; } } - """, optionName, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, optionName, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact] - public async Task CatchClause_ExceptionVariable_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task CatchClause_ExceptionVariable_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + try + { + } + catch (Exception [|ex|]) { - try - { - } - catch (Exception [|ex|]) - { - } } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + try + { + } + catch (Exception) { - try - { - } - catch (Exception) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact] - public async Task CatchClause_ExceptionVariable_PreferUnusedLocal_01() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task CatchClause_ExceptionVariable_PreferUnusedLocal_01() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(object p) + { + try + { + } + catch (Exception [|ex|]) + { + } + } + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task CatchClause_ExceptionVariable_PreferUnusedLocal_02() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + try { - try - { - } - catch (Exception [|ex|]) - { - } + } + catch (Exception [|ex|]) + { + ex = null; + var x = ex; } } - """, options: PreferUnusedLocal); - } - - [Fact] - public async Task CatchClause_ExceptionVariable_PreferUnusedLocal_02() - { - await TestInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object p) { - void M(object p) + try { - try - { - } - catch (Exception [|ex|]) - { - ex = null; - var x = ex; - } + } + catch (Exception unused) + { + Exception ex = null; + var x = ex; } } - """, - """ - using System; + } + """, options: PreferUnusedLocal); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedOutsideTry_UsedOnlyInCatchClause(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(object p) + [|x|] = 0; + try { - try - { - } - catch (Exception unused) - { - Exception ex = null; - var x = ex; - } + } + catch (Exception) + { + var y = x; } } - """, options: PreferUnusedLocal); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedOutsideTry_UsedOnlyInCatchClause(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedOutsideTry_UsedOnlyInCatchFilter(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + [|x|] = 0; + try + { + } + catch (Exception) when (x != 0) { - [|x|] = 0; - try - { - } - catch (Exception) - { - var y = x; - } } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedOutsideTry_UsedOnlyInCatchFilter(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedOutsideTry_UsedOnlyInFinally(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + [|x|] = 0; + try { - [|x|] = 0; - try - { - } - catch (Exception) when (x != 0) - { - } + } + finally + { + var y = x; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedOutsideTry_UsedOnlyInFinally(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInsideTry_UsedOnlyInCatchClause(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { [|x|] = 0; - try - { - } - finally - { - var y = x; - } + } + catch (Exception) + { + var y = x; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInsideTry_UsedOnlyInCatchClause(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInsideNestedBlockInTry_UsedOnlyInCatchClause(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { - try + if (x > 0) { [|x|] = 0; } - catch (Exception) - { - var y = x; - } + } + catch (Exception) + { + var y = x; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInsideNestedBlockInTry_UsedOnlyInCatchClause(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInCatchClause_UsedAfterTryCatch(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { - try - { - if (x > 0) - { - [|x|] = 0; - } - } - catch (Exception) - { - var y = x; - } } + catch (Exception) + { + [|x|] = 0; + } + + var y = x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInCatchClause_UsedAfterTryCatch(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInNestedCatchClause_UsedInOuterFinally(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { try { @@ -5741,114 +5757,114 @@ void M(int x) { [|x|] = 0; } - + } + finally + { var y = x; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInNestedCatchClause_UsedInOuterFinally(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInCatchClause_UsedInFinally(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { - try - { - try - { - } - catch (Exception) - { - [|x|] = 0; - } - } - finally - { - var y = x; - } + } + catch (Exception) + { + [|x|] = 0; + } + finally + { + var y = x; } } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInCatchClause_UsedInFinally(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInCatchFilter_UsedAfterTryCatch(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try + { + } + catch (Exception) when (M2(out [|x|])) { - try - { - } - catch (Exception) - { - [|x|] = 0; - } - finally - { - var y = x; - } } + + var y = x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInCatchFilter_UsedAfterTryCatch(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + bool M2(out int x) { x = 0; return true; } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInFinally_UsedAfterTryFinally(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { - try - { - } - catch (Exception) when (M2(out [|x|])) - { - } - - var y = x; + } + finally + { + [|x|] = 0; } - bool M2(out int x) { x = 0; return true; } + var y = x; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInFinally_UsedAfterTryFinally(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInNestedFinally_UsedInOuterFinally(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int x) { - void M(int x) + try { try { @@ -5857,2681 +5873,2652 @@ void M(int x) { [|x|] = 0; } - + } + finally + { var y = x; } } - """, optionName); - } - - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInNestedFinally_UsedInOuterFinally(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, optionName); + } - class C + [Fact] + public async Task IfElse_AssignedInCondition_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(bool flag) { - void M(int x) + int x; + if (M2(out [|x|])) { - try - { - try - { - } - finally - { - [|x|] = 0; - } - } - finally - { - var y = x; - } + x = 2; + } + else + { + x = 3; } } - """, optionName); - } - [Fact] - public async Task IfElse_AssignedInCondition_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) => x = 0; + } + """, + """ + class C + { + void M(bool flag) { - void M(bool flag) + int x; + if (M2(out _)) { - int x; - if (M2(out [|x|])) - { - x = 2; - } - else - { - x = 3; - } + x = 2; + } + else + { + x = 3; } - - bool M2(out int x) => x = 0; } - """, - """ - class C + + bool M2(out int x) => x = 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task IfElse_DeclaredInCondition_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(bool flag) { - void M(bool flag) + if (M2(out var [|x|])) { - int x; - if (M2(out _)) - { - x = 2; - } - else - { - x = 3; - } + x = 2; } + else + { + x = 3; + } + } - bool M2(out int x) => x = 0; + bool M2(out int x) => x = 0; + } + """, + """ + class C + { + void M(bool flag) + { + int x; + if (M2(out _)) + { + x = 2; + } + else + { + x = 3; + } } - """, options: PreferDiscard); - } - [Fact] - public async Task IfElse_DeclaredInCondition_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) => x = 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task IfElseAssignedInCondition_ReadAfter_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(bool flag) { - void M(bool flag) + int x; + if (M2(out [|x|])) { - if (M2(out var [|x|])) - { - x = 2; - } - else - { - x = 3; - } + x = 2; } - - bool M2(out int x) => x = 0; - } - """, - """ - class C - { - void M(bool flag) + else { - int x; - if (M2(out _)) - { - x = 2; - } - else - { - x = 3; - } + x = 3; } - bool M2(out int x) => x = 0; + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task IfElseAssignedInCondition_ReadAfter_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) => x = 0; + } + """, + """ + class C + { + int M(bool flag) { - int M(bool flag) + int x; + int unused; + if (M2(out unused)) { - int x; - if (M2(out [|x|])) - { - x = 2; - } - else - { - x = 3; - } - - return x; + x = 2; } - - bool M2(out int x) => x = 0; - } - """, - """ - class C - { - int M(bool flag) + else { - int x; - int unused; - if (M2(out unused)) - { - x = 2; - } - else - { - x = 3; - } - - return x; + x = 3; } - bool M2(out int x) => x = 0; + return x; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task IfElse_AssignedInCondition_NoReads_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + bool M2(out int x) => x = 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task IfElse_AssignedInCondition_NoReads_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(bool flag) { - void M(bool flag) + int x; + if (M2(out [|x|])) { - int x; - if (M2(out [|x|])) - { - x = 2; - } - else - { - x = 3; - } + x = 2; + } + else + { + x = 3; } - - bool M2(out int x) => x = 0; } - """, new TestParameters(options: PreferUnusedLocal)); - } - [Fact] - public async Task IfElse_DeclaredInCondition_ReadAfter_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) => x = 0; + } + """, new TestParameters(options: PreferUnusedLocal)); + } + + [Fact] + public async Task IfElse_DeclaredInCondition_ReadAfter_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(bool flag) { - int M(bool flag) + if (M2(out var [|x|])) { - if (M2(out var [|x|])) - { - x = 2; - } - else - { - x = 3; - } - - return x; + x = 2; } - - bool M2(out int x) => x = 0; - } - """, - """ - class C - { - int M(bool flag) + else { - int x; - if (M2(out var unused)) - { - x = 2; - } - else - { - x = 3; - } - - return x; + x = 3; } - bool M2(out int x) => x = 0; + return x; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task IfElse_DeclaredInCondition_NoReads_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + bool M2(out int x) => x = 0; + } + """, + """ + class C + { + int M(bool flag) { - void M(bool flag) + int x; + if (M2(out var unused)) { - if (M2(out var [|x|])) - { - x = 2; - } - else - { - x = 3; - } + x = 2; + } + else + { + x = 3; } - bool M2(out int x) => x = 0; + return x; } - """, new TestParameters(options: PreferUnusedLocal)); - } - [Theory] - // Simple if-else. - [InlineData("x = 1;", "x = 2;")] - // Nested if-else. - [InlineData("if(flag) { x = 1; } else { x = 2; }", - "x = 3;")] - // Multiple nested paths. - [InlineData("if(flag) { x = 1; } else { x = 2; }", - "if(flag) { x = 3; } else { x = 4; }")] - // Nested if-elseif-else. - [InlineData("if(flag) { x = 1; } else if(flag2) { x = 2; } else { x = 3; }", - "if(flag) { x = 5; } else { x = 6; }")] - //Multi-level nesting. - [InlineData(@"if(flag) { x = 1; } else { if(flag2) { if(flag3) { x = 2; } else { x = 3; } } else { x = 4; } }", - @"x = 5;")] - public async Task IfElse_OverwrittenInAllControlFlowPaths(string ifBranchCode, string elseBranchCode) - { - await TestInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + bool M2(out int x) => x = 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task IfElse_DeclaredInCondition_NoReads_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(bool flag) { - int M(bool flag, bool flag2, bool flag3) + if (M2(out var [|x|])) { - int [|x|] = 1; - if (flag4) - { - {{ifBranchCode}} - } - else - { - {{elseBranchCode}} - } - - return x; + x = 2; } - } - """, - $$""" - class C - { - int M(bool flag, bool flag2, bool flag3) + else { - int x; - if (flag4) - { - {{ifBranchCode}} - } - else - { - {{elseBranchCode}} - } - - return x; + x = 3; } } - """); - } - [Theory] - // Overwrite missing in if path. - [InlineData(";", "x = 2;")] - // Overwrite missing in else path. - [InlineData("x = 2;", "")] - // Overwrite missing in nested else path. - [InlineData("if(flag) { x = 1; }", - "x = 2;")] - // Overwrite missing in multiple nested paths. - [InlineData("if(flag) { x = 1; }", - "if(flag) { x = 2; }")] - // Overwrite missing with nested if-elseif-else. - [InlineData("if(flag) { x = 1; } else if(flag2) { x = 2; }", - "if(flag) { x = 3; } else { x = 4; }")] - // Overwrite missing in one path with multi-level nesting. - [InlineData(@"if(flag) { x = 1; } else { if(flag2) { if(flag3) { x = 2; } } else { x = 3; } }", - @"x = 4;")] - public async Task IfElse_OverwrittenInSomeControlFlowPaths(string ifBranchCode, string elseBranchCode) - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + bool M2(out int x) => x = 0; + } + """, new TestParameters(options: PreferUnusedLocal)); + } + + [Theory] + // Simple if-else. + [InlineData("x = 1;", "x = 2;")] + // Nested if-else. + [InlineData("if(flag) { x = 1; } else { x = 2; }", + "x = 3;")] + // Multiple nested paths. + [InlineData("if(flag) { x = 1; } else { x = 2; }", + "if(flag) { x = 3; } else { x = 4; }")] + // Nested if-elseif-else. + [InlineData("if(flag) { x = 1; } else if(flag2) { x = 2; } else { x = 3; }", + "if(flag) { x = 5; } else { x = 6; }")] + //Multi-level nesting. + [InlineData(@"if(flag) { x = 1; } else { if(flag2) { if(flag3) { x = 2; } else { x = 3; } } else { x = 4; } }", + @"x = 5;")] + public async Task IfElse_OverwrittenInAllControlFlowPaths(string ifBranchCode, string elseBranchCode) + { + await TestInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(bool flag, bool flag2, bool flag3) { - int M(bool flag, bool flag2, bool flag3) + int [|x|] = 1; + if (flag4) { - int [|x|] = 1; - if (flag4) - { - {{ifBranchCode}} - } - else - { - {{elseBranchCode}} - } - - return x; + {{ifBranchCode}} } - } - """); - } - - [Theory] - // Overitten in condition when true, overwritten in else code block when false. - [InlineData("flag && M2(out x)", ";", "x = 2;")] - // Overitten in condition when false, overwritten in if code block when true. - [InlineData("flag || M2(out x)", "x = 2;", ";")] - public async Task IfElse_Overwritten_CodeInOneBranch_ConditionInOtherBranch(string condition, string ifBranchCode, string elseBranchCode) - { - await TestInRegularAndScriptWithAllOptionsAsync( - $$""" - class C - { - int M(bool flag) + else { - int [|x|] = 1; - if ({{condition}}) - { - {{ifBranchCode}} - } - else - { - {{elseBranchCode}} - } - - return x; + {{elseBranchCode}} } - bool M2(out int x) { x = 0; return true; } - int M3() => 0; + return x; } - """, - $$""" - class C + } + """, + $$""" + class C + { + int M(bool flag, bool flag2, bool flag3) { - int M(bool flag) + int x; + if (flag4) { - int x; - if ({{condition}}) - { - {{ifBranchCode}} - } - else - { - {{elseBranchCode}} - } - - return x; + {{ifBranchCode}} + } + else + { + {{elseBranchCode}} } - bool M2(out int x) { x = 0; return true; } - int M3() => 0; + return x; } - """); - } + } + """); + } - [Theory] - // Overwrite missing in condition when left of || is true. - [InlineData("flag || M2(out x)")] - // Overwrite missing in condition when left of && is true. - [InlineData("flag && M2(out x)")] - // Overwrite missing in condition when left of || is true, but both both sides of && have an overwrite. - [InlineData("flag || M2(out x) && (x = M3()) > 0")] - public async Task IfElse_MayBeOverwrittenInCondition_LogicalOperators(string condition) - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + [Theory] + // Overwrite missing in if path. + [InlineData(";", "x = 2;")] + // Overwrite missing in else path. + [InlineData("x = 2;", "")] + // Overwrite missing in nested else path. + [InlineData("if(flag) { x = 1; }", + "x = 2;")] + // Overwrite missing in multiple nested paths. + [InlineData("if(flag) { x = 1; }", + "if(flag) { x = 2; }")] + // Overwrite missing with nested if-elseif-else. + [InlineData("if(flag) { x = 1; } else if(flag2) { x = 2; }", + "if(flag) { x = 3; } else { x = 4; }")] + // Overwrite missing in one path with multi-level nesting. + [InlineData(@"if(flag) { x = 1; } else { if(flag2) { if(flag3) { x = 2; } } else { x = 3; } }", + @"x = 4;")] + public async Task IfElse_OverwrittenInSomeControlFlowPaths(string ifBranchCode, string elseBranchCode) + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(bool flag, bool flag2, bool flag3) { - int M(bool flag) + int [|x|] = 1; + if (flag4) { - int [|x|] = 1; - if ({{condition}}) - { - } - else - { - } - - return x; + {{ifBranchCode}} + } + else + { + {{elseBranchCode}} } - bool M2(out int x) { x = 0; return true; } - int M3() => 0; + return x; } - """); - } + } + """); + } - [Theory] - [InlineData("M2(out x) || flag")] - [InlineData("M2(out x) && flag")] - [InlineData("M2(out x) || M2(out x)")] - [InlineData("M2(out x) && M2(out x)")] - [InlineData("flag && M2(out x) || (x = M3()) > 0")] - [InlineData("(flag || M2(out x)) && (x = M3()) > 0")] - [InlineData("M2(out x) && flag || (x = M3()) > 0")] - [InlineData("flag && M2(out x) || (x = M3()) > 0 && flag")] - public async Task IfElse_OverwrittenInCondition_LogicalOperators(string condition) - { - await TestInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + [Theory] + // Overitten in condition when true, overwritten in else code block when false. + [InlineData("flag && M2(out x)", ";", "x = 2;")] + // Overitten in condition when false, overwritten in if code block when true. + [InlineData("flag || M2(out x)", "x = 2;", ";")] + public async Task IfElse_Overwritten_CodeInOneBranch_ConditionInOtherBranch(string condition, string ifBranchCode, string elseBranchCode) + { + await TestInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(bool flag) { - int M(bool flag) + int [|x|] = 1; + if ({{condition}}) { - int [|x|] = 1; - if ({{condition}}) - { - } - else - { - } - - return x; + {{ifBranchCode}} + } + else + { + {{elseBranchCode}} } - bool M2(out int x) { x = 0; return true; } - int M3() => 0; + return x; } - """, - $$""" - class C - { - int M(bool flag) + + bool M2(out int x) { x = 0; return true; } + int M3() => 0; + } + """, + $$""" + class C { - int x; - if ({{condition}}) + int M(bool flag) { + int x; + if ({{condition}}) + { + {{ifBranchCode}} + } + else + { + {{elseBranchCode}} + } + + return x; } - else + + bool M2(out int x) { x = 0; return true; } + int M3() => 0; + } + """); + } + + [Theory] + // Overwrite missing in condition when left of || is true. + [InlineData("flag || M2(out x)")] + // Overwrite missing in condition when left of && is true. + [InlineData("flag && M2(out x)")] + // Overwrite missing in condition when left of || is true, but both both sides of && have an overwrite. + [InlineData("flag || M2(out x) && (x = M3()) > 0")] + public async Task IfElse_MayBeOverwrittenInCondition_LogicalOperators(string condition) + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(bool flag) { + int [|x|] = 1; + if ({{condition}}) + { + } + else + { + } + + return x; } - return x; + bool M2(out int x) { x = 0; return true; } + int M3() => 0; } + """); + } - bool M2(out int x) { x = 0; return true; } - int M3() => 0; - } - """); - } - - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ElselessIf(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData("M2(out x) || flag")] + [InlineData("M2(out x) && flag")] + [InlineData("M2(out x) || M2(out x)")] + [InlineData("M2(out x) && M2(out x)")] + [InlineData("flag && M2(out x) || (x = M3()) > 0")] + [InlineData("(flag || M2(out x)) && (x = M3()) > 0")] + [InlineData("M2(out x) && flag || (x = M3()) > 0")] + [InlineData("flag && M2(out x) || (x = M3()) > 0 && flag")] + public async Task IfElse_OverwrittenInCondition_LogicalOperators(string condition) + { + await TestInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(bool flag) { - int M(bool flag) + int [|x|] = 1; + if ({{condition}}) + { + } + else { - int [|x|] = 1; - if (flag) - { - x = 1; - } - - return x; } + + return x; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UnusedDefinition_NotFlagged_InUnreachableBlock(string optionName) + bool M2(out int x) { x = 0; return true; } + int M3() => 0; + } + """, + $$""" + class C + { + int M(bool flag) { - await TestMissingInRegularAndScriptAsync( - """ - class C + int x; + if ({{condition}}) + { + } + else + { + } + + return x; + } + + bool M2(out int x) { x = 0; return true; } + int M3() => 0; + } + """); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ElselessIf(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M(bool flag) { - void M() + int [|x|] = 1; + if (flag) { - int x; - if (true) - { - x = 0; - } - else - { - [|x|] = 1; - } - - return x; + x = 1; } - } - bool M2(out int x) { x = 0; return true; } + return x; } - """, optionName); - } + } + """, optionName); + } - [Fact] - public async Task SwitchCase_UnusedValueWithOnlyWrite_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UnusedDefinition_NotFlagged_InUnreachableBlock(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - int M(int flag) + int x; + if (true) { - switch(flag) - { - case 0: - int [|x|] = M2(); - return 0; - - default: - return flag; - } + x = 0; + } + else + { + [|x|] = 1; } - int M2() => 0; + return x; } - """, - """ - class C + } + + bool M2(out int x) { x = 0; return true; } + } + """, optionName); + } + + [Fact] + public async Task SwitchCase_UnusedValueWithOnlyWrite_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(int flag) { - int M(int flag) + switch(flag) { - switch(flag) - { - case 0: - _ = M2(); - return 0; + case 0: + int [|x|] = M2(); + return 0; - default: - return flag; - } + default: + return flag; } - - int M2() => 0; } - """, options: PreferDiscard); - } - [Fact] - public async Task SwitchCase_UnusedValueWithOnlyWrite_PreferUnusedLocal() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + int M(int flag) { - int M(int flag) + switch(flag) { - switch(flag) - { - case 0: - int [|x|] = M2(); - return 0; + case 0: + _ = M2(); + return 0; - default: - return flag; - } + default: + return flag; } - - int M2() => 0; } - """, options: PreferUnusedLocal); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task SwitchCase_UnusedConstantValue_WithReadsAndWrites(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task SwitchCase_UnusedValueWithOnlyWrite_PreferUnusedLocal() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M(int flag) { - int M(int flag) + switch(flag) { - switch(flag) - { - case 0: - int [|x|] = 0; - x = 1; - return x; + case 0: + int [|x|] = M2(); + return 0; - default: - return flag; - } + default: + return flag; } - - int M2() => 0; } - """, - """ - class C + + int M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task SwitchCase_UnusedConstantValue_WithReadsAndWrites(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(int flag) { - int M(int flag) + switch(flag) { - switch(flag) - { - case 0: - int x = 1; - return x; + case 0: + int [|x|] = 0; + x = 1; + return x; - default: - return flag; - } + default: + return flag; } - - int M2() => 0; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "int unused")] - public async Task SwitchCase_UnusedNonConstantValue_WithReadsAndWrites(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + int M(int flag) { - int M(int flag) + switch(flag) { - switch(flag) - { - case 0: - int [|x|] = M2(); - x = 1; - return x; + case 0: + int x = 1; + return x; - default: - return flag; - } + default: + return flag; } - - int M2() => 0; } - """, - $$""" - class C + + int M2() => 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "int unused")] + public async Task SwitchCase_UnusedNonConstantValue_WithReadsAndWrites(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(int flag) { - int M(int flag) + switch(flag) { - switch(flag) - { - case 0: - {{fix}} = M2(); - int x = 1; - return x; + case 0: + int [|x|] = M2(); + x = 1; + return x; - default: - return flag; - } + default: + return flag; } - - int M2() => 0; } - """, optionName); - } - [Theory] - // For loop, assignment in body, read on back edge. - [InlineData("for(i = 1; i < 10; i--)", - "M2(x); [|x|] = 1;")] - // While loop, assignment in body, read on back edge. - [InlineData("while(i++ < 10)", - "M2(x); [|x|] = 1;")] - // Do loop, assignment in body, read on back edge. - [InlineData("do", - "M2(x); [|x|] = 1;", - "while(i++ < 10);")] - // Continue, read on back edge. - [InlineData("while(i++ < 10)", - "M2(x); [|x|] = 1; if (flag) continue; x = 2;")] - // Break. - [InlineData(""" - x = 0; - while(i++ < 10) - """, - "[|x|] = 1; if (flag) break; x = 2;")] - // Assignment before loop, no overwrite on path where loop is never entered. - [InlineData(""" - [|x|] = 1; - while(i++ < 10) + int M2() => 0; + } """, - "x = 2;")] - public async Task Loops_Overwritten_InSomeControlFlowPaths( - string loopHeader, string loopBody, string? loopFooter = null) - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + $$""" + class C + { + int M(int flag) { - int M(int i, int x, bool flag) + switch(flag) { - {{loopHeader}} - { - {{loopBody}} - } - {{loopFooter ?? string.Empty}} + case 0: + {{fix}} = M2(); + int x = 1; + return x; - return x; + default: + return flag; } - - void M2(int x) { } } - """); - } - [Theory] - // For loop, assignment in body, re-assigned on back edge before read in loop and re-assigned at loop exit. - [InlineData("for(i = 1; i < 10; i--)", - "x = 1; M2(x); [|x|] = 2;", - "x = 3;", - // Fixed code. - "for(i = 1; i < 10; i--)", - "x = 1; M2(x);", - "x = 3;")] - // While loop, assignment in body, re-assigned on condition before read in loop and re-assigned at loop exit. - [InlineData("while(i++ < (x = 10))", - "M2(x); [|x|] = 2;", - "x = 3;", - // Fixed code. - "while(i++ < (x = 10))", - "M2(x);", - "x = 3;")] - // Assigned before loop, Re-assigned in continue, break paths and loop exit. - [InlineData(""" - [|x|] = 1; - i = 1; - while(i++ < 10) - """, - """ - if(flag) - { x = 2; continue; } - else if(i < 5) - { break; } - else - { x = 3; } - M2(x); - """, - "x = 4;", - // Fixed code. - """ - i = 1; - while(i++ < 10) - """, - """ - if(flag) - { x = 2; continue; } - else if(i < 5) - { break; } - else - { x = 3; } - M2(x); - """, - "x = 4;")] - public async Task Loops_Overwritten_InAllControlFlowPaths( - string loopHeader, string loopBody, string loopFooter, - string fixedLoopHeader, string fixedLoopBody, string fixedLoopFooter) - { - await TestInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + int M2() => 0; + } + """, optionName); + } + + [Theory] + // For loop, assignment in body, read on back edge. + [InlineData("for(i = 1; i < 10; i--)", + "M2(x); [|x|] = 1;")] + // While loop, assignment in body, read on back edge. + [InlineData("while(i++ < 10)", + "M2(x); [|x|] = 1;")] + // Do loop, assignment in body, read on back edge. + [InlineData("do", + "M2(x); [|x|] = 1;", + "while(i++ < 10);")] + // Continue, read on back edge. + [InlineData("while(i++ < 10)", + "M2(x); [|x|] = 1; if (flag) continue; x = 2;")] + // Break. + [InlineData(""" + x = 0; + while(i++ < 10) + """, + "[|x|] = 1; if (flag) break; x = 2;")] + // Assignment before loop, no overwrite on path where loop is never entered. + [InlineData(""" + [|x|] = 1; + while(i++ < 10) + """, + "x = 2;")] + public async Task Loops_Overwritten_InSomeControlFlowPaths( + string loopHeader, string loopBody, string? loopFooter = null) + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(int i, int x, bool flag) { - int M(int i, int x, bool flag) + {{loopHeader}} { - {{loopHeader}} - { - {{loopBody}} - } - {{loopFooter}} - - return x; + {{loopBody}} } + {{loopFooter ?? string.Empty}} - void M2(int x) { } + return x; } + + void M2(int x) { } + } + """); + } + + [Theory] + // For loop, assignment in body, re-assigned on back edge before read in loop and re-assigned at loop exit. + [InlineData("for(i = 1; i < 10; i--)", + "x = 1; M2(x); [|x|] = 2;", + "x = 3;", + // Fixed code. + "for(i = 1; i < 10; i--)", + "x = 1; M2(x);", + "x = 3;")] + // While loop, assignment in body, re-assigned on condition before read in loop and re-assigned at loop exit. + [InlineData("while(i++ < (x = 10))", + "M2(x); [|x|] = 2;", + "x = 3;", + // Fixed code. + "while(i++ < (x = 10))", + "M2(x);", + "x = 3;")] + // Assigned before loop, Re-assigned in continue, break paths and loop exit. + [InlineData(""" + [|x|] = 1; + i = 1; + while(i++ < 10) + """, + """ + if(flag) + { x = 2; continue; } + else if(i < 5) + { break; } + else + { x = 3; } + M2(x); + """, + "x = 4;", + // Fixed code. + """ + i = 1; + while(i++ < 10) """, - $$""" - class C + """ + if(flag) + { x = 2; continue; } + else if(i < 5) + { break; } + else + { x = 3; } + M2(x); + """, + "x = 4;")] + public async Task Loops_Overwritten_InAllControlFlowPaths( + string loopHeader, string loopBody, string loopFooter, + string fixedLoopHeader, string fixedLoopBody, string fixedLoopFooter) + { + await TestInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(int i, int x, bool flag) { - int M(int i, int x, bool flag) + {{loopHeader}} { - {{fixedLoopHeader}} - { - {{fixedLoopBody}} - } - {{fixedLoopFooter}} - - return x; + {{loopBody}} } + {{loopFooter}} - void M2(int x) { } + return x; } - """); - } - [Fact] - public async Task FixAll_NonConstantValue_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2(int x) { } + } + """, + $$""" + class C + { + int M(int i, int x, bool flag) { - public C() + {{fixedLoopHeader}} { - // Different code block - int x = M2(); + {{fixedLoopBody}} } + {{fixedLoopFooter}} - int M(bool flag) - { - // Trigger diagostic - {|FixAllInDocument:int x = M2()|}; + return x; + } - // Unused out assignment - M2(out x); + void M2(int x) { } + } + """); + } - // Used Assignment - x = 0; - System.Console.WriteLine(x); + [Fact] + public async Task FixAll_NonConstantValue_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C() + { + // Different code block + int x = M2(); + } - // Unused constant assignment. - // Not fixed as we have a different code fix 'Remove redundant assignment' - x = 1; + int M(bool flag) + { + // Trigger diagostic + {|FixAllInDocument:int x = M2()|}; - // Unused initialization with only def/use in nested block. - // Declaration for 'y' should be moved inside the if block. - int y = M2(); - if (flag) - { - y = 2; - System.Console.WriteLine(y); - } - else - { - } + // Unused out assignment + M2(out x); - x = M2(); - return x; - } + // Used Assignment + x = 0; + System.Console.WriteLine(x); - bool M2(out int x) { x = 0; return true; } - int M2() => 0; - } - """, - """ - class C - { - public C() + // Unused constant assignment. + // Not fixed as we have a different code fix 'Remove redundant assignment' + x = 1; + + // Unused initialization with only def/use in nested block. + // Declaration for 'y' should be moved inside the if block. + int y = M2(); + if (flag) { - // Different code block - _ = M2(); + y = 2; + System.Console.WriteLine(y); } - - int M(bool flag) + else { - // Trigger diagostic - _ = M2(); - - // Unused out assignment - M2(out _); - - // Used Assignment - int x = 0; - System.Console.WriteLine(x); - - // Unused constant assignment. - // Not fixed as we have a different code fix 'Remove redundant assignment' - x = 1; - - // Unused initialization with only def/use in nested block. - // Declaration for 'y' should be moved inside the if block. - _ = M2(); - if (flag) - { - int y = 2; - System.Console.WriteLine(y); - } - else - { - } - - x = M2(); - return x; } - bool M2(out int x) { x = 0; return true; } - int M2() => 0; + x = M2(); + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task FixAll_NonConstantValue_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) { x = 0; return true; } + int M2() => 0; + } + """, + """ + class C + { + public C() { - public C() - { - // Different code block - int x = M2(); - x = 0; - System.Console.WriteLine(x); - } - - int M(bool flag) - { - // Trigger diagostic - {|FixAllInDocument:int x = M2()|}; + // Different code block + _ = M2(); + } - // Unused out assignment - M2(out x); + int M(bool flag) + { + // Trigger diagostic + _ = M2(); - // Used Assignment, declaration for 'x' should move here - x = 0; - System.Console.WriteLine(x); + // Unused out assignment + M2(out _); - // Unused constant assignment. - // Not fixed as we have a different code fix 'Remove redundant assignment' - x = 1; + // Used Assignment + int x = 0; + System.Console.WriteLine(x); - // Unused initialization with only def/use in nested block. - // Declaration for 'y' should be moved inside the if block. - int y = M2(); - if (flag) - { - y = 2; - System.Console.WriteLine(y); - } - else - { - } + // Unused constant assignment. + // Not fixed as we have a different code fix 'Remove redundant assignment' + x = 1; - x = M2(); - return x; + // Unused initialization with only def/use in nested block. + // Declaration for 'y' should be moved inside the if block. + _ = M2(); + if (flag) + { + int y = 2; + System.Console.WriteLine(y); } - - bool M2(out int x) { x = 0; return true; } - int M2() => 0; - } - """, - """ - class C - { - public C() + else { - // Different code block - int unused = M2(); - int x = 0; - System.Console.WriteLine(x); } - int M(bool flag) - { - // Trigger diagostic - int unused = M2(); - int unused1; + x = M2(); + return x; + } - // Unused out assignment - M2(out unused1); + bool M2(out int x) { x = 0; return true; } + int M2() => 0; + } + """, options: PreferDiscard); + } - // Used Assignment, declaration for 'x' should move here - int x = 0; - System.Console.WriteLine(x); + [Fact] + public async Task FixAll_NonConstantValue_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C() + { + // Different code block + int x = M2(); + x = 0; + System.Console.WriteLine(x); + } - // Unused constant assignment. - // Not fixed as we have a different code fix 'Remove redundant assignment' - x = 1; + int M(bool flag) + { + // Trigger diagostic + {|FixAllInDocument:int x = M2()|}; - // Unused initialization with only def/use in nested block. - // Declaration for 'y' should be moved inside the if block. - int unused2 = M2(); - if (flag) - { - int y = 2; - System.Console.WriteLine(y); - } - else - { - } + // Unused out assignment + M2(out x); - x = M2(); - return x; - } + // Used Assignment, declaration for 'x' should move here + x = 0; + System.Console.WriteLine(x); - bool M2(out int x) { x = 0; return true; } - int M2() => 0; - } - """, options: PreferUnusedLocal); - } + // Unused constant assignment. + // Not fixed as we have a different code fix 'Remove redundant assignment' + x = 1; - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task FixAll_ConstantValue_RemoveRedundantAssignments(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C - { - public C() + // Unused initialization with only def/use in nested block. + // Declaration for 'y' should be moved inside the if block. + int y = M2(); + if (flag) { - // Different code block - int x = 1; + y = 2; + System.Console.WriteLine(y); } - - int M(bool flag, int p) + else { - // Trigger diagostic - {|FixAllInDocument:int x = 0|}; + } - // Unused assignment from parameter, should be removed. - x = p; + x = M2(); + return x; + } - // Unused assignment from local, should be removed. - int local = 3; - x = local; + bool M2(out int x) { x = 0; return true; } + int M2() => 0; + } + """, + """ + class C + { + public C() + { + // Different code block + int unused = M2(); + int x = 0; + System.Console.WriteLine(x); + } - // Used assignment, declaration for 'x' should move here - x = 0; - System.Console.WriteLine(x); + int M(bool flag) + { + // Trigger diagostic + int unused = M2(); + int unused1; - // Unused non-constant 'out' assignment - // Not fixed as we have a different code fix 'Use discard' for it. - M2(out x); + // Unused out assignment + M2(out unused1); - // Unused initialization with only def/use in nested block. - // Declaration for 'y' should be moved inside the if block. - int y = 1; - if (flag) - { - y = 2; - System.Console.WriteLine(y); - } - else - { - } + // Used Assignment, declaration for 'x' should move here + int x = 0; + System.Console.WriteLine(x); - x = M2(); - return x; - } + // Unused constant assignment. + // Not fixed as we have a different code fix 'Remove redundant assignment' + x = 1; - bool M2(out int x) { x = 0; return true; } - int M2() => 0; - } - """, - """ - class C - { - public C() + // Unused initialization with only def/use in nested block. + // Declaration for 'y' should be moved inside the if block. + int unused2 = M2(); + if (flag) { - // Different code block + int y = 2; + System.Console.WriteLine(y); } - - int M(bool flag, int p) + else { - - // Unused assignment from parameter, should be removed. - - // Unused assignment from local, should be removed. - int local = 3; - - // Trigger diagostic - // Used assignment, declaration for 'x' should move here - int x = 0; - System.Console.WriteLine(x); - - // Unused non-constant 'out' assignment - // Not fixed as we have a different code fix 'Use discard' for it. - M2(out x); - if (flag) - { - // Unused initialization with only def/use in nested block. - // Declaration for 'y' should be moved inside the if block. - int y = 2; - System.Console.WriteLine(y); - } - else - { - } - - x = M2(); - return x; } - bool M2(out int x) { x = 0; return true; } - int M2() => 0; + x = M2(); + return x; } - """, optionName); - } - - [Fact] - public async Task FixAll_MoveMultipleVariableDeclarations_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M(bool flag, int p) - { - // Multiple unused variable declarations (x and y) moved below to start of if-else block - // Used declaration (z1) and evaluation (_ = M2()) retained. - // Completely unused declaration (z2) removed. - {|FixAllInDocument:int x = 0|}; - int z1 = 1, _ = M2(), y = 0, z2 = 2; - - if (flag) - { - x = 1; - y = 1; - } - else - { - x = 2; - y = 2; - } - return x + y + z1; - } + bool M2(out int x) { x = 0; return true; } + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - int M2() => 0; + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task FixAll_ConstantValue_RemoveRedundantAssignments(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C() + { + // Different code block + int x = 1; } - """, - """ - class C + + int M(bool flag, int p) { - int M(bool flag, int p) - { - int z1 = 1; - _ = M2(); + // Trigger diagostic + {|FixAllInDocument:int x = 0|}; - // Multiple unused variable declarations (x and y) moved below to start of if-else block - // Used declaration (z1) and evaluation (_ = M2()) retained. - // Completely unused declaration (z2) removed. - int x; - int y; - if (flag) - { - x = 1; - y = 1; - } - else - { - x = 2; - y = 2; - } + // Unused assignment from parameter, should be removed. + x = p; + + // Unused assignment from local, should be removed. + int local = 3; + x = local; + + // Used assignment, declaration for 'x' should move here + x = 0; + System.Console.WriteLine(x); + + // Unused non-constant 'out' assignment + // Not fixed as we have a different code fix 'Use discard' for it. + M2(out x); - return x + y + z1; + // Unused initialization with only def/use in nested block. + // Declaration for 'y' should be moved inside the if block. + int y = 1; + if (flag) + { + y = 2; + System.Console.WriteLine(y); + } + else + { } - int M2() => 0; + x = M2(); + return x; } - """, options: PreferDiscard); - } - [Fact] - public async Task FixAll_MoveMultipleVariableDeclarations_PreferUnusedLocal() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) { x = 0; return true; } + int M2() => 0; + } + """, + """ + class C + { + public C() { - int M(bool flag, int p) - { - // Multiple unused variable declarations (x and y) moved below to start of if-else block - // Used declaration (z1) and evaluation (_ = M2()) retained. - // Completely unused declaration (z2) removed. - {|FixAllInDocument:int x = 0|}; - int z1 = 1, _ = M2(), y = 0, z2 = 2; + // Different code block + } - if (flag) - { - x = 1; - y = 1; - } - else - { - x = 2; - y = 2; - } + int M(bool flag, int p) + { - return x + y + z1; - } + // Unused assignment from parameter, should be removed. - int M2() => 0; - } - """, - """ - class C - { - int M(bool flag, int p) - { - int z1 = 1, _ = M2(); + // Unused assignment from local, should be removed. + int local = 3; - // Multiple unused variable declarations (x and y) moved below to start of if-else block - // Used declaration (z1) and evaluation (_ = M2()) retained. - // Completely unused declaration (z2) removed. - int x; - int y; - if (flag) - { - x = 1; - y = 1; - } - else - { - x = 2; - y = 2; - } + // Trigger diagostic + // Used assignment, declaration for 'x' should move here + int x = 0; + System.Console.WriteLine(x); - return x + y + z1; + // Unused non-constant 'out' assignment + // Not fixed as we have a different code fix 'Use discard' for it. + M2(out x); + if (flag) + { + // Unused initialization with only def/use in nested block. + // Declaration for 'y' should be moved inside the if block. + int y = 2; + System.Console.WriteLine(y); + } + else + { } - int M2() => 0; + x = M2(); + return x; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task NonConstantValue_Trivia_PreferDiscard_01() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2(out int x) { x = 0; return true; } + int M2() => 0; + } + """, optionName); + } + + [Fact] + public async Task FixAll_MoveMultipleVariableDeclarations_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(bool flag, int p) { - int M() - { - // C1 - [|int x = M2()|], y = M2(); // C2 - // C3 + // Multiple unused variable declarations (x and y) moved below to start of if-else block + // Used declaration (z1) and evaluation (_ = M2()) retained. + // Completely unused declaration (z2) removed. + {|FixAllInDocument:int x = 0|}; + int z1 = 1, _ = M2(), y = 0, z2 = 2; - return y; + if (flag) + { + x = 1; + y = 1; } - - int M2() => 0; - } - """, - """ - class C - { - int M() + else { - // C1 - _ = M2(); - // C1 - int y = M2(); // C2 - // C3 - - return y; + x = 2; + y = 2; } - int M2() => 0; + return x + y + z1; } - """, options: PreferDiscard); - } - [Fact] - public async Task NonConstantValue_Trivia_PreferDiscard_02() - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + int M(bool flag, int p) { - int M() - { - /*C1*/ - /*C2*/[|int/*C3*/ /*C4*/x/*C5*/ = /*C6*/M2()|]/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 - /*C11*/ + int z1 = 1; + _ = M2(); - return y; + // Multiple unused variable declarations (x and y) moved below to start of if-else block + // Used declaration (z1) and evaluation (_ = M2()) retained. + // Completely unused declaration (z2) removed. + int x; + int y; + if (flag) + { + x = 1; + y = 1; } - - int M2() => 0; - } - """, - """ - class C - { - int M() + else { - /*C1*/ - /*C2*//*C3*/ /*C4*/ - _/*C5*/ = /*C6*/M2()/*C7*/; - /*C1*/ - /*C2*/ - int/*C3*/ /*C4*/y/*C8*/ = M2()/*C9*/; // C10 - /*C11*/ - - return y; + x = 2; + y = 2; } - int M2() => 0; + return x + y + z1; } - """, options: PreferDiscard); - } - [Fact] - public async Task NonConstantValue_Trivia_PreferUnusedLocal_01() - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task FixAll_MoveMultipleVariableDeclarations_PreferUnusedLocal() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M(bool flag, int p) { - int M() - { - // C1 - [|int x = M2()|], y = M2(); // C2 - // C3 + // Multiple unused variable declarations (x and y) moved below to start of if-else block + // Used declaration (z1) and evaluation (_ = M2()) retained. + // Completely unused declaration (z2) removed. + {|FixAllInDocument:int x = 0|}; + int z1 = 1, _ = M2(), y = 0, z2 = 2; - // C4 + if (flag) + { x = 1; - return x + y; + y = 1; } - - int M2() => 0; - } - """, - """ - class C - { - int M() + else { - // C1 - int unused = M2(), y = M2(); // C2 - // C3 - - // C4 - int x = 1; - return x + y; + x = 2; + y = 2; } - int M2() => 0; + return x + y + z1; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task NonConstantValue_Trivia_PreferUnusedLocal_02() - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + int M(bool flag, int p) { - int M() - { - /*C1*/ - /*C2*/[|int/*C3*/ /*C4*/x/*C5*/ = /*C6*/M2()|]/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 - /*C11*/ + int z1 = 1, _ = M2(); - // C12 + // Multiple unused variable declarations (x and y) moved below to start of if-else block + // Used declaration (z1) and evaluation (_ = M2()) retained. + // Completely unused declaration (z2) removed. + int x; + int y; + if (flag) + { x = 1; - return x + y; + y = 1; } - - int M2() => 0; - } - """, - """ - class C - { - int M() + else { - /*C1*/ - /*C2*/ - int/*C3*/ /*C4*/unused/*C5*/ = /*C6*/M2()/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 - /*C11*/ - - // C12 - int x = 1; - return x + y; + x = 2; + y = 2; } - int M2() => 0; + return x + y + z1; } - """, options: PreferUnusedLocal); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ConstantValue_Trivia_01(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task NonConstantValue_Trivia_PreferDiscard_01() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - // C1 - [|int x = 0|], y = M2(); // C2 - // C3 + // C1 + [|int x = M2()|], y = M2(); // C2 + // C3 - // C4 - x = 1; - return x + y; - } + return y; + } + + int M2() => 0; + } + """, + """ + class C + { + int M() + { + // C1 + _ = M2(); + // C1 + int y = M2(); // C2 + // C3 - int M2() => 0; + return y; } - """, - """ - class C + + int M2() => 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task NonConstantValue_Trivia_PreferDiscard_02() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - // C1 - int y = M2(); // C2 - // C3 + /*C1*/ + /*C2*/[|int/*C3*/ /*C4*/x/*C5*/ = /*C6*/M2()|]/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 + /*C11*/ - // C4 - int x = 1; - return x + y; - } + return y; + } + + int M2() => 0; + } + """, + """ + class C + { + int M() + { + /*C1*/ + /*C2*//*C3*/ /*C4*/ + _/*C5*/ = /*C6*/M2()/*C7*/; + /*C1*/ + /*C2*/ + int/*C3*/ /*C4*/y/*C8*/ = M2()/*C9*/; // C10 + /*C11*/ - int M2() => 0; + return y; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ConstantValue_Trivia_02(string optionName) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task NonConstantValue_Trivia_PreferUnusedLocal_01() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - /*C1*/ - /*C2*/[|int/*C3*/ /*C4*/x/*C5*/ = /*C6*/0|]/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 - /*C11*/ + // C1 + [|int x = M2()|], y = M2(); // C2 + // C3 - // C12 - x = 1; - return x + y; - } + // C4 + x = 1; + return x + y; + } - int M2() => 0; + int M2() => 0; + } + """, + """ + class C + { + int M() + { + // C1 + int unused = M2(), y = M2(); // C2 + // C3 + + // C4 + int x = 1; + return x + y; } - """, - """ - class C + + int M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task NonConstantValue_Trivia_PreferUnusedLocal_02() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - /*C1*/ - /*C2*/ - int/*C3*/ /*C4*/y/*C8*/ = M2()/*C9*/; // C10 - /*C11*/ + /*C1*/ + /*C2*/[|int/*C3*/ /*C4*/x/*C5*/ = /*C6*/M2()|]/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 + /*C11*/ - // C12 - int x = 1; - return x + y; - } + // C12 + x = 1; + return x + y; + } - int M2() => 0; + int M2() => 0; + } + """, + """ + class C + { + int M() + { + /*C1*/ + /*C2*/ + int/*C3*/ /*C4*/unused/*C5*/ = /*C6*/M2()/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 + /*C11*/ + + // C12 + int x = 1; + return x + y; } - """, optionName); - } - [Fact] - public async Task ExistingDiscardDeclarationInLambda_UseOutsideLambda() - { - await TestInRegularAndScriptAsync( - """ - using System; + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ConstantValue_Trivia_01(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - void M() - { - int [|x|] = M2(); - Action a = () => - { - var _ = M2(); - }; + // C1 + [|int x = 0|], y = M2(); // C2 + // C3 - a(); - } + // C4 + x = 1; + return x + y; + } + + int M2() => 0; + } + """, + """ + class C + { + int M() + { + // C1 + int y = M2(); // C2 + // C3 - int M2() => 0; + // C4 + int x = 1; + return x + y; } - """, - """ - using System; - class C + int M2() => 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ConstantValue_Trivia_02(string optionName) + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - void M() - { - _ = M2(); - Action a = () => - { - _ = M2(); - }; + /*C1*/ + /*C2*/[|int/*C3*/ /*C4*/x/*C5*/ = /*C6*/0|]/*C7*/, y/*C8*/ = M2()/*C9*/; // C10 + /*C11*/ - a(); - } + // C12 + x = 1; + return x + y; + } + + int M2() => 0; + } + """, + """ + class C + { + int M() + { + /*C1*/ + /*C2*/ + int/*C3*/ /*C4*/y/*C8*/ = M2()/*C9*/; // C10 + /*C11*/ - int M2() => 0; + // C12 + int x = 1; + return x + y; } - """, options: PreferDiscard); - } - [Fact] - public async Task ExistingDiscardDeclarationInLambda_UseInsideLambda() - { - await TestInRegularAndScriptAsync( - """ - using System; + int M2() => 0; + } + """, optionName); + } + + [Fact] + public async Task ExistingDiscardDeclarationInLambda_UseOutsideLambda() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() + int [|x|] = M2(); + Action a = () => { - Action a = () => - { - int [|x|] = M2(); - var _ = M2(); - }; - - a(); - } + var _ = M2(); + }; - int M2() => 0; + a(); } - """, - """ - using System; - class C + int M2() => 0; + } + """, + """ + using System; + + class C + { + void M() { - void M() + _ = M2(); + Action a = () => { - Action a = () => - { - _ = M2(); - _ = M2(); - }; - - a(); - } + _ = M2(); + }; - int M2() => 0; + a(); } - """, options: PreferDiscard); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ValueOverwrittenByOutVar_ConditionalAndExpression(string optionName) - { - await TestInRegularAndScriptAsync( - """ - using System; + int M2() => 0; + } + """, options: PreferDiscard); + } + + [Fact] + public async Task ExistingDiscardDeclarationInLambda_UseInsideLambda() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Action a = () => { - int {|FixAllInDocument:x1|} = -1, x2 = -1; - if (M2(x: out x1) && - M2(x: out x2)) - { - x1 = 0; - x2 = 0; - } - else - { - Console.WriteLine(x1); - } - - Console.WriteLine(x1 + x2); - } + int [|x|] = M2(); + var _ = M2(); + }; - bool M2(out int x) - { - x = 0; - return true; - } + a(); } - """, - """ - using System; - class C + int M2() => 0; + } + """, + """ + using System; + + class C + { + void M() { - void M() + Action a = () => { - int x2 = -1; - int x1; - if (M2(x: out x1) && - M2(x: out x2)) - { - x1 = 0; - x2 = 0; - } - else - { - Console.WriteLine(x1); - } - - Console.WriteLine(x1 + x2); - } + _ = M2(); + _ = M2(); + }; - bool M2(out int x) - { - x = 0; - return true; - } + a(); } - """, optionName); - } - [Theory] - [InlineData("var")] - [InlineData("int")] - public async Task UnusedOutVariableDeclaration_PreferDiscard(string typeName) - { - await TestInRegularAndScriptAsync( - $$""" - class C + int M2() => 0; + } + """, options: PreferDiscard); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ValueOverwrittenByOutVar_ConditionalAndExpression(string optionName) + { + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + void M() { - void M() + int {|FixAllInDocument:x1|} = -1, x2 = -1; + if (M2(x: out x1) && + M2(x: out x2)) { - if (M2(out {{typeName}} [|x|])) - { - } + x1 = 0; + x2 = 0; } - - bool M2(out int x) + else { - x = 0; - return true; + Console.WriteLine(x1); } + + Console.WriteLine(x1 + x2); } - """, - """ - class C - { - void M() - { - if (M2(out _)) - { - } - } - bool M2(out int x) - { - x = 0; - return true; - } + bool M2(out int x) + { + x = 0; + return true; } - """, options: PreferDiscard); - } + } + """, + """ + using System; - [Fact] - public async Task UnusedOutVariableDeclaration_MethodOverloads_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + class C + { + void M() { - void M() + int x2 = -1; + int x1; + if (M2(x: out x1) && + M2(x: out x2)) { - if (M2(out int [|x|])) - { - } + x1 = 0; + x2 = 0; } - - bool M2(out int x) + else { - x = 0; - return true; + Console.WriteLine(x1); } - bool M2(out char x) - { - x = 'c'; - return true; - } + Console.WriteLine(x1 + x2); } - """, - """ - class C + + bool M2(out int x) { - void M() - { - if (M2(out int _)) - { - } - } + x = 0; + return true; + } + } + """, optionName); + } - bool M2(out int x) + [Theory] + [InlineData("var")] + [InlineData("int")] + public async Task UnusedOutVariableDeclaration_PreferDiscard(string typeName) + { + await TestInRegularAndScriptAsync( + $$""" + class C + { + void M() + { + if (M2(out {{typeName}} [|x|])) { - x = 0; - return true; } + } - bool M2(out char x) + bool M2(out int x) + { + x = 0; + return true; + } + } + """, + """ + class C + { + void M() + { + if (M2(out _)) { - x = 'c'; - return true; } } - """, options: PreferDiscard); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31583")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task MissingImports(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + bool M2(out int x) + { + x = 0; + return true; + } + } + """, options: PreferDiscard); + } + + [Fact] + public async Task UnusedOutVariableDeclaration_MethodOverloads_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (M2(out int [|x|])) { - List [|x|] = null; } } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31583")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UsedAssignment_ConditionalPreprocessorDirective(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - #define DEBUG + bool M2(out int x) + { + x = 0; + return true; + } - class C + bool M2(out char x) + { + x = 'c'; + return true; + } + } + """, + """ + class C + { + void M() { - int M() + if (M2(out int _)) { - int [|x|] = 0; - #if DEBUG - x = 1; - #endif - return x; } } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32855")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task RefLocalInitialization(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class Test + bool M2(out int x) { - int[] data = { 0 }; - - void Method() - { - ref int [|target|] = ref data[0]; - target = 1; - } + x = 0; + return true; } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32855")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task RefLocalAssignment(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class Test + bool M2(out char x) { - int[] data = { 0 }; + x = 'c'; + return true; + } + } + """, options: PreferDiscard); + } - int Method() - { - ref int target = ref data[0]; - [|target|] = 1; - return data[0]; - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31583")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task MissingImports(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + List [|x|] = null; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32903")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task DelegateCreationWrappedInATuple_UsedInReturnedLambda(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31583")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UsedAssignment_ConditionalPreprocessorDirective(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + #define DEBUG - public class C + class C + { + int M() { - private (int, int) createTuple() => (1, 1); + int [|x|] = 0; + #if DEBUG + x = 1; + #endif + return x; + } + } + """, optionName); + } - public (Func, bool) M() - { - var ([|value1, value2|]) = createTuple(); + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32855")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task RefLocalInitialization(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class Test + { + int[] data = { 0 }; - int LocalFunction() => value1 + value2; + void Method() + { + ref int [|target|] = ref data[0]; + target = 1; + } + } + """, optionName); + } - return (LocalFunction, true); - } - } - """, optionName); - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32855")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task RefLocalAssignment(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class Test + { + int[] data = { 0 }; + + int Method() + { + ref int target = ref data[0]; + [|target|] = 1; + return data[0]; + } + } + """, optionName); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32923")] - public async Task UnusedLocal_ForEach() - { - await TestDiagnosticsAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32903")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task DelegateCreationWrappedInATuple_UsedInReturnedLambda(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + public class C + { + private (int, int) createTuple() => (1, 1); - public struct S + public (Func, bool) M() { - public Enumerator GetEnumerator() => throw new NotImplementedException(); + var ([|value1, value2|]) = createTuple(); - public struct Enumerator - { - public Enumerator(S sequence) => throw new NotImplementedException(); - public int Current => throw new NotImplementedException(); - public bool MoveNext() => throw new NotImplementedException(); - } + int LocalFunction() => value1 + value2; + + return (LocalFunction, true); + } + } + """, optionName); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32923")] + public async Task UnusedLocal_ForEach() + { + await TestDiagnosticsAsync( + """ + using System; + + public struct S + { + public Enumerator GetEnumerator() => throw new NotImplementedException(); + + public struct Enumerator + { + public Enumerator(S sequence) => throw new NotImplementedException(); + public int Current => throw new NotImplementedException(); + public bool MoveNext() => throw new NotImplementedException(); } + } - class C + class C + { + void M(S s) { - void M(S s) + foreach (var [|x|] in s) { - foreach (var [|x|] in s) - { - } } } - """, new TestParameters(options: PreferDiscard, retainNonFixableDiagnostics: true), - Diagnostic("IDE0059")); - } + } + """, new TestParameters(options: PreferDiscard, retainNonFixableDiagnostics: true), +Diagnostic("IDE0059")); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60030")] - public async Task UnusedLocal_ForEach_TopLevelStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - var items = new[] { new { x = 1 } }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60030")] + public async Task UnusedLocal_ForEach_TopLevelStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + var items = new[] { new { x = 1 } }; - foreach (var [|item|] in items) - { - } - """, PreferDiscard, new CSharpParseOptions(LanguageVersion.CSharp9)); - } + foreach (var [|item|] in items) + { + } + """, PreferDiscard, new CSharpParseOptions(LanguageVersion.CSharp9)); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32923")] - [InlineData("_", nameof(PreferDiscard))] - [InlineData("_", nameof(PreferUnusedLocal))] - [InlineData("_1", nameof(PreferDiscard))] - [InlineData("_1", nameof(PreferUnusedLocal))] - public async Task UnusedLocal_SpecialName_01(string variableName, string optionName) - { - await TestDiagnosticMissingAsync( - $$""" - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32923")] + [InlineData("_", nameof(PreferDiscard))] + [InlineData("_", nameof(PreferUnusedLocal))] + [InlineData("_1", nameof(PreferDiscard))] + [InlineData("_1", nameof(PreferUnusedLocal))] + public async Task UnusedLocal_SpecialName_01(string variableName, string optionName) + { + await TestDiagnosticMissingAsync( + $$""" + using System; - public struct S - { - public Enumerator GetEnumerator() => throw new NotImplementedException(); + public struct S + { + public Enumerator GetEnumerator() => throw new NotImplementedException(); - public struct Enumerator - { - public Enumerator(S sequence) => throw new NotImplementedException(); - public int Current => throw new NotImplementedException(); - public bool MoveNext() => throw new NotImplementedException(); - } + public struct Enumerator + { + public Enumerator(S sequence) => throw new NotImplementedException(); + public int Current => throw new NotImplementedException(); + public bool MoveNext() => throw new NotImplementedException(); } + } - class C + class C + { + void M(S s) { - void M(S s) + foreach (var [|{{variableName}}|] in s) { - foreach (var [|{{variableName}}|] in s) - { - } } } - """, new TestParameters(options: GetOptions(optionName), retainNonFixableDiagnostics: true)); - } + } + """, new TestParameters(options: GetOptions(optionName), retainNonFixableDiagnostics: true)); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32923")] - [InlineData("_", nameof(PreferDiscard))] - [InlineData("_", nameof(PreferUnusedLocal))] - [InlineData("_3", nameof(PreferDiscard))] - [InlineData("_3", nameof(PreferUnusedLocal))] - public async Task UnusedLocal_SpecialName_02(string variableName, string optionName) - { - await TestMissingInRegularAndScriptAsync( - $$""" - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32923")] + [InlineData("_", nameof(PreferDiscard))] + [InlineData("_", nameof(PreferUnusedLocal))] + [InlineData("_3", nameof(PreferDiscard))] + [InlineData("_3", nameof(PreferUnusedLocal))] + public async Task UnusedLocal_SpecialName_02(string variableName, string optionName) + { + await TestMissingInRegularAndScriptAsync( + $$""" + using System; - public class C + public class C + { + public void M(int p) { - public void M(int p) - { - var [|{{variableName}}|] = p; - } + var [|{{variableName}}|] = p; } - """, optionName); - } + } + """, optionName); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32959")] - public async Task UsedVariable_BailOutOnSemanticError() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32959")] + public async Task UsedVariable_BailOutOnSemanticError() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - int [|x|] = 1; + int [|x|] = 1; - // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. - Invoke(() => x); + // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. + Invoke(() => x); - T Invoke(Func a) { return a(); } - } + T Invoke(Func a) { return a(); } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32959")] - public async Task UnusedVariable_BailOutOnSemanticError() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32959")] + public async Task UnusedVariable_BailOutOnSemanticError() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - int [|x|] = 1; + int [|x|] = 1; - // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. - Invoke(() => 0); + // CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type. + Invoke(() => 0); - T Invoke(Func a) { return a(); } - } + T Invoke(Func a) { return a(); } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] - public async Task DelegateEscape_01() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] + public async Task DelegateEscape_01() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + Action[] M() { - Action[] M() - { - var [|j|] = 0; - return new Action[1] { () => Console.WriteLine(j) }; - } + var [|j|] = 0; + return new Action[1] { () => Console.WriteLine(j) }; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] - public async Task DelegateEscape_02() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] + public async Task DelegateEscape_02() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + Action[] M(Action[] actions) { - Action[] M(Action[] actions) - { - var [|j|] = 0; - actions[0] = () => Console.WriteLine(j); - return actions; - } + var [|j|] = 0; + actions[0] = () => Console.WriteLine(j); + return actions; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] - public async Task DelegateEscape_03() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] + public async Task DelegateEscape_03() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C - { - Action[,] M(Action[,] actions) - { - var [|j|] = 0; - actions[0, 0] = () => Console.WriteLine(j); - return actions; - } + class C + { + Action[,] M(Action[,] actions) + { + var [|j|] = 0; + actions[0, 0] = () => Console.WriteLine(j); + return actions; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] - public async Task DelegateEscape_04() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] + public async Task DelegateEscape_04() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + List M() { - List M() - { - var [|j|] = 0; - return new List { () => Console.WriteLine(j) }; - } + var [|j|] = 0; + return new List { () => Console.WriteLine(j) }; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] - public async Task DelegateEscape_05() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32946")] + public async Task DelegateEscape_05() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + List M() { - List M() - { - var [|j|] = 0; - var list = new List(); - list.Add(() => Console.WriteLine(j)); - return list; - } + var [|j|] = 0; + var list = new List(); + list.Add(() => Console.WriteLine(j)); + return list; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32924")] - public async Task DelegateEscape_06() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32924")] + public async Task DelegateEscape_06() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - int [|j|] = 0; - Console.CancelKeyPress += (s, e) => e.Cancel = j != 0; - } + int [|j|] = 0; + Console.CancelKeyPress += (s, e) => e.Cancel = j != 0; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32924")] - public async Task DelegateEscape_07() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32924")] + public async Task DelegateEscape_07() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - int [|j|] = 0; - Console.CancelKeyPress += LocalFunctionHandler; - return; + int [|j|] = 0; + Console.CancelKeyPress += LocalFunctionHandler; + return; - void LocalFunctionHandler(object s, ConsoleCancelEventArgs e) => e.Cancel = j != 0; - } + void LocalFunctionHandler(object s, ConsoleCancelEventArgs e) => e.Cancel = j != 0; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32856")] - public async Task RedundantAssignment_IfStatementParent() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32856")] + public async Task RedundantAssignment_IfStatementParent() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(int j) { - void M(int j) - { - if (M2()) - [|j|] = 0; - } - - bool M2() => true; + if (M2()) + [|j|] = 0; } - """, - """ - class C - { - void M(int j) - { - if (M2()) - _ = 0; - } - bool M2() => true; + bool M2() => true; + } + """, + """ + class C + { + void M(int j) + { + if (M2()) + _ = 0; } - """, options: PreferDiscard); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32856")] - public async Task RedundantAssignment_LoopStatementParent() - { - await TestInRegularAndScriptAsync( - """ - class C + bool M2() => true; + } + """, options: PreferDiscard); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32856")] + public async Task RedundantAssignment_LoopStatementParent() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(int j, int[] array) { - void M(int j, int[] array) - { - for (int i = 0; i < array.Length; i++) - [|j|] = i; - } + for (int i = 0; i < array.Length; i++) + [|j|] = i; } - """, - """ - class C + } + """, + """ + class C + { + void M(int j, int[] array) { - void M(int j, int[] array) - { - for (int i = 0; i < array.Length; i++) - _ = i; - } + for (int i = 0; i < array.Length; i++) + _ = i; } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] - public async Task RedundantAssignment_ForStatementVariableDeclarationConstant() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] + public async Task RedundantAssignment_ForStatementVariableDeclarationConstant() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + for (int [|i|] = 0; ; ) { - for (int [|i|] = 0; ; ) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + for (; ; ) { - for (; ; ) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] - public async Task RedundantAssignment_ForStatementVariableDeclarationMethod() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int GetValue() => 0; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] + public async Task RedundantAssignment_ForStatementVariableDeclarationMethod() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int GetValue() => 0; - void M() + void M() + { + for (int [|i|] = GetValue(); ; ) { - for (int [|i|] = GetValue(); ; ) - { - } } } - """, - """ - class C - { - int GetValue() => 0; + } + """, + """ + class C + { + int GetValue() => 0; - void M() + void M() + { + for (int _ = GetValue(); ; ) { - for (int _ = GetValue(); ; ) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] - public async Task RedundantAssignment_ForStatementVariableDeclarationStaticMethod() - { - await TestInRegularAndScriptAsync( - """ - class C - { - static int GetValue() => 0; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] + public async Task RedundantAssignment_ForStatementVariableDeclarationStaticMethod() + { + await TestInRegularAndScriptAsync( + """ + class C + { + static int GetValue() => 0; - void M() + void M() + { + for (int [|i|] = GetValue(); ; ) { - for (int [|i|] = GetValue(); ; ) - { - } } } - """, - """ - class C - { - static int GetValue() => 0; + } + """, + """ + class C + { + static int GetValue() => 0; - void M() + void M() + { + for (int _ = GetValue(); ; ) { - for (int _ = GetValue(); ; ) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] - public async Task RedundantAssignment_ForStatementVariableDeclarationInsideUsedLambda() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] + public async Task RedundantAssignment_ForStatementVariableDeclarationInsideUsedLambda() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Action a = () => { - Action a = () => + for (int [|i|] = 0; ; ) { - for (int [|i|] = 0; ; ) - { - } - }; - a(); - } + } + }; + a(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + Action a = () => { - Action a = () => + for (; ; ) { - for (; ; ) - { - } - }; - a(); - } + } + }; + a(); } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] - public async Task RedundantAssignment_ForStatementVariableDeclarationInsideUnusedLambda() - { - //NOTE: Currently the diagnostic is only reported on the outer unused variable a. - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40336")] + public async Task RedundantAssignment_ForStatementVariableDeclarationInsideUnusedLambda() + { + //NOTE: Currently the diagnostic is only reported on the outer unused variable a. + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Action a = () => { - Action a = () => + for (int [|i|] = 0; ; ) { - for (int [|i|] = 0; ; ) - { - } - }; - } + } + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] - public async Task NullCoalesceAssignment_01() - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] + public async Task NullCoalesceAssignment_01() + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + """ + class C + { + public static void M(C x) { - public static void M(C x) - { - [|x|] = M2(); - x ??= new C(); - } - - private static C M2() => null; + [|x|] = M2(); + x ??= new C(); } - """, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] - public async Task NullCoalesceAssignment_02() - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - """ - class C - { - public static C M(C x) - { - [|x|] ??= new C(); - return x; - } - } - """, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + private static C M2() => null; + } + """, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] - public async Task NullCoalesceAssignment_03() - { - await TestInRegularAndScriptAsync( - """ - class C - { - public static void M(C x) - { - [|x|] ??= new C(); - } - } - """, - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] + public async Task NullCoalesceAssignment_02() + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + """ + class C + { + public static C M(C x) { - public static void M(C x) - { - _ = x ?? new C(); - } + [|x|] ??= new C(); + return x; } - """, optionName: nameof(PreferDiscard), parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] - public async Task NullCoalesceAssignment_04() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] + public async Task NullCoalesceAssignment_03() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public static void M(C x) { - public static C M(C x) - { - return [|x|] ??= new C(); - } + [|x|] ??= new C(); } - """, - """ - class C + } + """, + """ + class C + { + public static void M(C x) { - public static C M(C x) - { - return x ?? new C(); - } + _ = x ?? new C(); } - """, optionName: nameof(PreferDiscard), parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, optionName: nameof(PreferDiscard), parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] - public async Task NullCoalesceAssignment_05() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] + public async Task NullCoalesceAssignment_04() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public static C M(C x) { - public static C M(C x) - => [|x|] ??= new C(); + return [|x|] ??= new C(); } - """, - """ - class C + } + """, + """ + class C + { + public static C M(C x) { - public static C M(C x) - => x ?? new C(); + return x ?? new C(); } - """, optionName: nameof(PreferDiscard), parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, optionName: nameof(PreferDiscard), parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] - public async Task RedundantAssignment_WithLeadingAndTrailingComment() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33299")] + public async Task NullCoalesceAssignment_05() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public static C M(C x) + => [|x|] ??= new C(); + } + """, + """ + class C + { + public static C M(C x) + => x ?? new C(); + } + """, optionName: nameof(PreferDiscard), parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } + + [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] + public async Task RedundantAssignment_WithLeadingAndTrailingComment() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + // This is a comment before the variable assignment. + // It has two lines. + [|int foo = 0;|] // Trailing comment. + if (true) { - // This is a comment before the variable assignment. - // It has two lines. - [|int foo = 0;|] // Trailing comment. - if (true) - { - foo = 1; - } - System.Console.WriteLine(foo); + foo = 1; } + System.Console.WriteLine(foo); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // This is a comment before the variable assignment. + // It has two lines. + int foo; + if (true) { - // This is a comment before the variable assignment. - // It has two lines. - int foo; - if (true) - { - foo = 1; - } - System.Console.WriteLine(foo); + foo = 1; } + System.Console.WriteLine(foo); } - """, options: PreferUnusedLocal); - } + } + """, options: PreferUnusedLocal); + } - [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] - public async Task MultipleRedundantAssignment_WithLeadingAndTrailingComment() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] + public async Task MultipleRedundantAssignment_WithLeadingAndTrailingComment() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + // This is a comment before the variable assignment. + // It has two lines. + {|FixAllInDocument:int unused = 0, foo = 0, bar = 0;|} // Trailing comment. + if (true) { - // This is a comment before the variable assignment. - // It has two lines. - {|FixAllInDocument:int unused = 0, foo = 0, bar = 0;|} // Trailing comment. - if (true) - { - foo = 1; - bar = 1; - } - System.Console.WriteLine(foo); - System.Console.WriteLine(bar); + foo = 1; + bar = 1; } + System.Console.WriteLine(foo); + System.Console.WriteLine(bar); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // This is a comment before the variable assignment. + // It has two lines. + int foo; + int bar; + if (true) { - // This is a comment before the variable assignment. - // It has two lines. - int foo; - int bar; - if (true) - { - foo = 1; - bar = 1; - } - System.Console.WriteLine(foo); - System.Console.WriteLine(bar); + foo = 1; + bar = 1; } + System.Console.WriteLine(foo); + System.Console.WriteLine(bar); } - """, options: PreferUnusedLocal); - } + } + """, options: PreferUnusedLocal); + } - [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] - public async Task MultipleRedundantAssignment_WithInnerComment() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] + public async Task MultipleRedundantAssignment_WithInnerComment() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + {|FixAllInDocument:int unused = 0, /*Comment*/foo = 0, /*Another comment*/ bar = 0;|} + if (true) { - {|FixAllInDocument:int unused = 0, /*Comment*/foo = 0, /*Another comment*/ bar = 0;|} - if (true) - { - foo = 1; - } - System.Console.WriteLine(foo); + foo = 1; } + System.Console.WriteLine(foo); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int foo; + if (true) { - int foo; - if (true) - { - foo = 1; - } - System.Console.WriteLine(foo); + foo = 1; } + System.Console.WriteLine(foo); } - """, options: PreferUnusedLocal); - } + } + """, options: PreferUnusedLocal); + } - [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] - public async Task DeclarationPatternInSwitchCase_WithTrivia_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] + public async Task DeclarationPatternInSwitchCase_WithTrivia_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case /*Inline trivia*/ int [|x|]: - // Other trivia - x = 1; - break; - }; - } + case /*Inline trivia*/ int [|x|]: + // Other trivia + x = 1; + break; + }; } - """, - """ - class C + } + """, + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case /*Inline trivia*/ int _: - // Other trivia - int x = 1; - break; - }; - } + case /*Inline trivia*/ int _: + // Other trivia + int x = 1; + break; + }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Theory, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] - [CombinatorialData] - public async Task DeclarationPatternInSwitchCase_WithTrivia_PreferUnusedLocal( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] + [CombinatorialData] + public async Task DeclarationPatternInSwitchCase_WithTrivia_PreferUnusedLocal( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case /*Inline trivia*/ int [|x|]: - // Other trivia - x = 1; - break; - }; - } + case /*Inline trivia*/ int [|x|]: + // Other trivia + x = 1; + break; + }; } - """, PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion)); - } + } + """, PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion)); + } - [Theory, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] - [CombinatorialData] - public async Task DeclarationPatternInSwitchCase_WithTrivia_TypePattern( - [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) - { - var source = - """ - class C + [Theory, WorkItem(32856, "https://github.com/dotnet/roslyn/issues/33312")] + [CombinatorialData] + public async Task DeclarationPatternInSwitchCase_WithTrivia_TypePattern( + [CombinatorialValues(CodeFixTestBehaviors.None, CodeFixTestBehaviors.FixOne)] CodeFixTestBehaviors testBehaviors) + { + var source = + """ + class C + { + void M(object p) { - void M(object p) + switch (p) { - switch (p) - { - case /*Inline trivia*/ int {|IDE0059:x|}: - // Other trivia - {|IDE0059:x|} = 1; - break; - }; - } + case /*Inline trivia*/ int {|IDE0059:x|}: + // Other trivia + {|IDE0059:x|} = 1; + break; + }; } - """; - var (fixedSource, iterations) = testBehaviors switch - { - CodeFixTestBehaviors.None => + } + """; + var (fixedSource, iterations) = testBehaviors switch + { + CodeFixTestBehaviors.None => (""" class C { @@ -8546,7 +8533,7 @@ void M(object p) } } """, iterations: 2), - CodeFixTestBehaviors.FixOne => + CodeFixTestBehaviors.FixOne => (""" class C { @@ -8562,1528 +8549,1527 @@ void M(object p) } } """, iterations: 1), - _ => throw ExceptionUtilities.Unreachable(), - }; - - await new VerifyCS.Test - { - TestCode = source, - FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, - LanguageVersion = LanguageVersion.CSharp9, - CodeFixTestBehaviors = testBehaviors, - NumberOfIncrementalIterations = iterations, - NumberOfFixAllIterations = iterations, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } + _ => throw ExceptionUtilities.Unreachable(), + }; - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33949")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UsedInArgumentAfterAnArgumentWithControlFlow(string optionName) + await new VerifyCS.Test { - await TestMissingInRegularAndScriptAsync( - """ - class A - { - public static void M(int? x) - { - A [|a|] = new A(); - a = M2(x ?? 1, a); - } + TestCode = source, + FixedState = { Sources = { fixedSource }, MarkupHandling = MarkupMode.Allow }, + LanguageVersion = LanguageVersion.CSharp9, + CodeFixTestBehaviors = testBehaviors, + NumberOfIncrementalIterations = iterations, + NumberOfFixAllIterations = iterations, + Options = + { + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } - private static A M2(int? x, A a) - { - return a; - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33949")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UsedInArgumentAfterAnArgumentWithControlFlow(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class A + { + public static void M(int? x) + { + A [|a|] = new A(); + a = M2(x ?? 1, a); } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33949")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task CompoundAssignmentWithControlFlowInValue(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class A + private static A M2(int? x, A a) { - public static void M(int? x) - { - int [|a|] = 1; - a += M2(x ?? 1); - } + return a; + } + } + """, optionName); + } - private static int M2(int? x) => 0; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33949")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task CompoundAssignmentWithControlFlowInValue(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class A + { + public static void M(int? x) + { + int [|a|] = 1; + a += M2(x ?? 1); } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UsedValueWithUsingStatementAndLocalFunction(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + private static int M2(int? x) => 0; + } + """, optionName); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UsedValueWithUsingStatementAndLocalFunction(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + private class Disposable : IDisposable { public void Dispose() { } } + public int M() { - private class Disposable : IDisposable { public void Dispose() { } } - public int M() - { - var result = 0; - void append() => [|result|] += 1; // IDE0059 for 'result' - using (var a = new Disposable()) - append(); - return result; - } + var result = 0; + void append() => [|result|] += 1; // IDE0059 for 'result' + using (var a = new Disposable()) + append(); + return result; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UsedValueWithUsingStatementAndLambda(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UsedValueWithUsingStatementAndLambda(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + private class Disposable : IDisposable { public void Dispose() { } } + public int M() { - private class Disposable : IDisposable { public void Dispose() { } } - public int M() - { - var result = 0; - Action append = () => [|result|] += 1; // IDE0059 for 'result' - using (var a = new Disposable()) - append(); - return result; - } + var result = 0; + Action append = () => [|result|] += 1; // IDE0059 for 'result' + using (var a = new Disposable()) + append(); + return result; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UsedValueWithUsingStatementAndLambda_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UsedValueWithUsingStatementAndLambda_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + private class Disposable : IDisposable { public void Dispose() { } } + public int M() { - private class Disposable : IDisposable { public void Dispose() { } } - public int M() - { - var result = 0; - Action appendLambda = () => [|result|] += 1; - void appendLocalFunction() => appendLambda(); - Action appendDelegate = appendLocalFunction; - using (var a = new Disposable()) - appendDelegate(); - return result; - } + var result = 0; + Action appendLambda = () => [|result|] += 1; + void appendLocalFunction() => appendLambda(); + Action appendDelegate = appendLocalFunction; + using (var a = new Disposable()) + appendDelegate(); + return result; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UsedValueWithUsingStatementAndLambda_03(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33843")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UsedValueWithUsingStatementAndLambda_03(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + private class Disposable : IDisposable { public void Dispose() { } } + public int M() { - private class Disposable : IDisposable { public void Dispose() { } } - public int M() - { - var result = 0; - void appendLocalFunction() => [|result|] += 1; - Action appendLambda = () => appendLocalFunction(); - Action appendDelegate = appendLambda; - using (var a = new Disposable()) - appendDelegate(); - return result; - } + var result = 0; + void appendLocalFunction() => [|result|] += 1; + Action appendLambda = () => appendLocalFunction(); + Action appendDelegate = appendLambda; + using (var a = new Disposable()) + appendDelegate(); + return result; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33937")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInCatchUsedInFinally_ThrowInCatch(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33937")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInCatchUsedInFinally_ThrowInCatch(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - public static class Program + public static class Program + { + public static void Test() { - public static void Test() + var exceptionThrown = false; + try { - var exceptionThrown = false; - try - { - throw new Exception(); - } - catch - { - // The `exceptionThrown` token is incorrectly greyed out in the IDE - // IDE0059 Value assigned to 'exceptionThrown' is never used - [|exceptionThrown|] = true; - throw; - } - finally - { - // Breakpoint on this line is hit and 'true' is printed - Console.WriteLine(exceptionThrown); - } + throw new Exception(); + } + catch + { + // The `exceptionThrown` token is incorrectly greyed out in the IDE + // IDE0059 Value assigned to 'exceptionThrown' is never used + [|exceptionThrown|] = true; + throw; + } + finally + { + // Breakpoint on this line is hit and 'true' is printed + Console.WriteLine(exceptionThrown); } } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33937")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task AssignedInCatchUsedInFinally_NoThrowInCatch(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33937")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task AssignedInCatchUsedInFinally_NoThrowInCatch(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - public static class Program + public static class Program + { + public static void Test() { - public static void Test() + var exceptionThrown = false; + try { - var exceptionThrown = false; - try - { - throw new Exception(); - } - catch - { - [|exceptionThrown|] = true; - } - finally - { - Console.WriteLine(exceptionThrown); - } + throw new Exception(); + } + catch + { + [|exceptionThrown|] = true; + } + finally + { + Console.WriteLine(exceptionThrown); } } - """, optionName); - } + } + """, optionName); + } - [Fact] - public async Task DoesNotUseLocalFunctionName_PreferUnused() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task DoesNotUseLocalFunctionName_PreferUnused() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() - { - int [|x|] = M2(); - x = 2; - return x; - - void unused() { } - } + int [|x|] = M2(); + x = 2; + return x; - int M2() => 0; + void unused() { } } - """, - """ - class C - { - int M() - { - int unused1 = M2(); - int x = 2; - return x; - void unused() { } - } + int M2() => 0; + } + """, + """ + class C + { + int M() + { + int unused1 = M2(); + int x = 2; + return x; - int M2() => 0; + void unused() { } } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task CanUseLocalFunctionParameterName_PreferUnused() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M() - { - int [|x|] = M2(); - x = 2; - return x; + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - void MLocal(int unused) { } - } + [Fact] + public async Task CanUseLocalFunctionParameterName_PreferUnused() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() + { + int [|x|] = M2(); + x = 2; + return x; - int M2() => 0; + void MLocal(int unused) { } } - """, - """ - class C - { - int M() - { - int unused = M2(); - int x = 2; - return x; - void MLocal(int unused) { } - } + int M2() => 0; + } + """, + """ + class C + { + int M() + { + int unused = M2(); + int x = 2; + return x; - int M2() => 0; + void MLocal(int unused) { } } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task DoesNotUseLambdaFunctionParameterNameWithCSharpLessThan8_PreferUnused() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C - { - int M() - { - int [|x|] = M2(); - x = 2; - Action myLambda = unused => { }; + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - return x; - } + [Fact] + public async Task DoesNotUseLambdaFunctionParameterNameWithCSharpLessThan8_PreferUnused() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + int M() + { + int [|x|] = M2(); + x = 2; + Action myLambda = unused => { }; - int M2() => 0; + return x; } - """, - """ - using System; - class C - { - int M() - { - int unused1 = M2(); - int x = 2; - Action myLambda = unused => { }; - return x; - } + int M2() => 0; + } + """, + """ + using System; + class C + { + int M() + { + int unused1 = M2(); + int x = 2; + Action myLambda = unused => { }; - int M2() => 0; + return x; } - """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } - [Fact] - public async Task CanUseLambdaFunctionParameterNameWithCSharp8_PreferUnused() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C - { - int M() - { - int [|x|] = M2(); - x = 2; - Action myLambda = unused => { }; + int M2() => 0; + } + """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - return x; - } + [Fact] + public async Task CanUseLambdaFunctionParameterNameWithCSharp8_PreferUnused() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + int M() + { + int [|x|] = M2(); + x = 2; + Action myLambda = unused => { }; - int M2() => 0; + return x; } - """, - """ - using System; - class C - { - int M() - { - int unused = M2(); - int x = 2; - Action myLambda = unused => { }; - return x; - } + int M2() => 0; + } + """, + """ + using System; + class C + { + int M() + { + int unused = M2(); + int x = 2; + Action myLambda = unused => { }; - int M2() => 0; + return x; } - """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33464")] - public async Task UsingDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + int M2() => 0; + } + """, options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33464")] + public async Task UsingDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C : IDisposable + class C : IDisposable + { + public void Dispose() { - public void Dispose() - { - } + } - void M() - { - using var [|x|] = new C(); - } + void M() + { + using var [|x|] = new C(); } - """, options: PreferDiscard, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """, options: PreferDiscard, +parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33464")] - public async Task UsingDeclarationWithInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33464")] + public async Task UsingDeclarationWithInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C : IDisposable + class C : IDisposable + { + public int P { get; set; } + public void Dispose() { - public int P { get; set; } - public void Dispose() - { - } + } - void M() - { - using var [|x|] = new C() { P = 1 }; - } + void M() + { + using var [|x|] = new C() { P = 1 }; } - """, options: PreferDiscard, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """, options: PreferDiscard, +parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37709")] - public async Task RefParameter_WrittenBeforeThrow() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37709")] + public async Task RefParameter_WrittenBeforeThrow() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + public void DoSomething(ref bool p) { - public void DoSomething(ref bool p) + if (p) { - if (p) - { - [|p|] = false; - throw new ArgumentException(string.Empty); - } + [|p|] = false; + throw new ArgumentException(string.Empty); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37709")] - public async Task OutParameter_WrittenBeforeThrow() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37709")] + public async Task OutParameter_WrittenBeforeThrow() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + public void DoSomething(out bool p, bool x) { - public void DoSomething(out bool p, bool x) + if (x) { - if (x) - { - [|p|] = false; - throw new ArgumentException(string.Empty); - } - else - { - p = true; - } + [|p|] = false; + throw new ArgumentException(string.Empty); + } + else + { + p = true; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37871")] - public async Task RefParameter_RefAssignmentFollowedByAssignment() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37871")] + public async Task RefParameter_RefAssignmentFollowedByAssignment() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C - { - delegate ref int UnsafeAdd(ref int source, int elementOffset); - static UnsafeAdd MyUnsafeAdd; + class C + { + delegate ref int UnsafeAdd(ref int source, int elementOffset); + static UnsafeAdd MyUnsafeAdd; - static void T1(ref int param) - { - [|param|] = ref MyUnsafeAdd(ref param, 1); - param = default; - } + static void T1(ref int param) + { + [|param|] = ref MyUnsafeAdd(ref param, 1); + param = default; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37871")] - public async Task RefParameter_RefConditionalAssignment() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37871")] + public async Task RefParameter_RefConditionalAssignment() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C - { - delegate ref int UnsafeAdd(ref int source, int elementOffset); - static UnsafeAdd MyUnsafeAdd; + class C + { + delegate ref int UnsafeAdd(ref int source, int elementOffset); + static UnsafeAdd MyUnsafeAdd; - static void T1(ref int param, bool flag) - { - [|param|] = flag ? ref MyUnsafeAdd(ref param, 1) : ref MyUnsafeAdd(ref param, 2); - param = default; - } + static void T1(ref int param, bool flag) + { + [|param|] = flag ? ref MyUnsafeAdd(ref param, 1) : ref MyUnsafeAdd(ref param, 2); + param = default; } - """); - } + } + """); + } - [Fact] - public async Task LocalFunction_OutParameter_UsedInCaller() - { - await TestDiagnosticMissingAsync( - """ - public class C + [Fact] + public async Task LocalFunction_OutParameter_UsedInCaller() + { + await TestDiagnosticMissingAsync( + """ + public class C + { + public void M() { - public void M() + if (GetVal(out var [|value|])) { - if (GetVal(out var [|value|])) - { - var x = value; - } + var x = value; + } - bool GetVal(out string val) - { - val = string.Empty; - return true; - } + bool GetVal(out string val) + { + val = string.Empty; + return true; } } - """); - } + } + """); + } - [Fact] - public async Task TupleMember_UsedAfterContinueBranch() - { - await TestDiagnosticMissingAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task TupleMember_UsedAfterContinueBranch() + { + await TestDiagnosticMissingAsync( + """ + using System; + using System.Collections.Generic; - public class Test + public class Test + { + void M(List<(int, int)> list) { - void M(List<(int, int)> list) + foreach (var (x, [|y|]) in list) { - foreach (var (x, [|y|]) in list) + if (x != 0) { - if (x != 0) - { - continue; - } - - Console.Write(y); + continue; } + + Console.Write(y); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] - public async Task DeclarationPatternInSwitchExpressionArm_UsedLocal() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] + public async Task DeclarationPatternInSwitchExpressionArm_UsedLocal() + { + await TestDiagnosticMissingAsync( + """ + class C + { + string M(object obj) { - string M(object obj) + return obj switch { - return obj switch - { - int [|p2|] => p2.ToString(), - _ => "NoMatch" - }; - } + int [|p2|] => p2.ToString(), + _ => "NoMatch" + }; } - """, new TestParameters(options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8))); - } + } + """, new TestParameters(options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8))); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] - [CombinatorialData] - public async Task DeclarationPatternInSwitchExpressionArm_UnusedLocal_PreferUnusedLocal( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) - { - await TestDiagnosticMissingAsync( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] + [CombinatorialData] + public async Task DeclarationPatternInSwitchExpressionArm_UnusedLocal_PreferUnusedLocal( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestDiagnosticMissingAsync( + """ + class C + { + string M(object obj) { - string M(object obj) + return obj switch { - return obj switch - { - int [|p2|] => "Int", - _ => "NoMatch" - }; - } + int [|p2|] => "Int", + _ => "NoMatch" + }; } - """, new TestParameters(options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion))); - } + } + """, new TestParameters(options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] - public async Task LocalUsedWithPropertySubPattern() - { - await TestDiagnosticMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] + public async Task LocalUsedWithPropertySubPattern() + { + await TestDiagnosticMissingAsync( + """ + class C + { + public object P { get; } + void M() { - public object P { get; } - void M() - { - C [|c|] = new C(); - var x = c is { P : int i }; - } + C [|c|] = new C(); + var x = c is { P : int i }; } - """, new TestParameters(options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8))); - } + } + """, new TestParameters(options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] - public async Task UnusedLocalDefinedInPropertySubPattern_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] + public async Task UnusedLocalDefinedInPropertySubPattern_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public object P { get; } + void M(C c) { - public object P { get; } - void M(C c) - { - var x = c is { P : int [|i|] }; - } + var x = c is { P : int [|i|] }; } - """, - """ - class C + } + """, + """ + class C + { + public object P { get; } + void M(C c) { - public object P { get; } - void M(C c) - { - var x = c is { P : int _ }; - } + var x = c is { P : int _ }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] - public async Task UnusedLocalDefinedInPropertySubPattern_TypePattern() - { - var source = - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] + public async Task UnusedLocalDefinedInPropertySubPattern_TypePattern() + { + var source = + """ + class C + { + public object P { get; } + bool M(C c) { - public object P { get; } - bool M(C c) - { - var x = c is { P : int {|IDE0059:i|} }; - return x; - } + var x = c is { P : int {|IDE0059:i|} }; + return x; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + public object P { get; } + bool M(C c) { - public object P { get; } - bool M(C c) - { - var x = c is { P : int }; - return x; - } + var x = c is { P : int }; + return x; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp9, + Options = { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp9, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] - [CombinatorialData] - public async Task UnusedVarLocalDefinedInPropertySubPattern_PreferDiscard( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] + [CombinatorialData] + public async Task UnusedVarLocalDefinedInPropertySubPattern_PreferDiscard( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestInRegularAndScriptAsync( + """ + class C + { + public object P { get; } + void M(C c) { - public object P { get; } - void M(C c) - { - var x = c is { P : var [|i|] }; - } + var x = c is { P : var [|i|] }; } - """, - """ - class C + } + """, + """ + class C + { + public object P { get; } + void M(C c) { - public object P { get; } - void M(C c) - { - var x = c is { P : _ }; - } + var x = c is { P : _ }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(languageVersion)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(languageVersion)); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] - [CombinatorialData] - public async Task UnusedLocalDefinedInPropertySubPattern_PreferUnusedLocal( - [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) - { - await TestDiagnosticMissingAsync( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/40499")] + [CombinatorialData] + public async Task UnusedLocalDefinedInPropertySubPattern_PreferUnusedLocal( + [CombinatorialValues(LanguageVersion.CSharp8, LanguageVersion.CSharp9)] LanguageVersion languageVersion) + { + await TestDiagnosticMissingAsync( + """ + class C + { + public object P { get; } + void M(C c) { - public object P { get; } - void M(C c) - { - var x = c is { P : int [|i|] }; - } + var x = c is { P : int [|i|] }; } - """, new TestParameters(options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion))); - } + } + """, new TestParameters(options: PreferUnusedLocal, parseOptions: new CSharpParseOptions(languageVersion))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] - public async Task DeclarationPatternInSwitchExpressionArm_UnusedLocal_PreferDiscard() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] + public async Task DeclarationPatternInSwitchExpressionArm_UnusedLocal_PreferDiscard() + { + await TestInRegularAndScriptAsync( + """ + class C + { + string M(object obj) { - string M(object obj) + return obj switch { - return obj switch - { - int [|p2|] => "Int", - _ => "NoMatch" - }; - } + int [|p2|] => "Int", + _ => "NoMatch" + }; } - """, - """ - class C + } + """, + """ + class C + { + string M(object obj) { - string M(object obj) + return obj switch { - return obj switch - { - int _ => "Int", - _ => "NoMatch" - }; - } + int _ => "Int", + _ => "NoMatch" + }; } - """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, options: PreferDiscard, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] - public async Task DeclarationPatternInSwitchExpressionArm_UnusedLocal_TypePattern() - { - var source = - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38640")] + public async Task DeclarationPatternInSwitchExpressionArm_UnusedLocal_TypePattern() + { + var source = + """ + class C + { + string M(object obj) { - string M(object obj) + return obj switch { - return obj switch - { - int {|IDE0059:p2|} => "Int", - _ => "NoMatch" - }; - } + int {|IDE0059:p2|} => "Int", + _ => "NoMatch" + }; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + string M(object obj) { - string M(object obj) + return obj switch { - return obj switch - { - int => "Int", - _ => "NoMatch" - }; - } + int => "Int", + _ => "NoMatch" + }; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = LanguageVersion.CSharp9, + Options = { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = LanguageVersion.CSharp9, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39344")] - public async Task AssignmentInTry_UsedInFinally_NoDiagnostic() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39344")] + public async Task AssignmentInTry_UsedInFinally_NoDiagnostic() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M(int i) { - void M(int i) + bool b = false; + try { - bool b = false; - try + if (i == 0) { - if (i == 0) - { - [|b|] = true; - } + [|b|] = true; } - finally + } + finally + { + if (!b) { - if (!b) - { - Console.WriteLine(i); - } + Console.WriteLine(i); } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39755")] - public async Task AssignmentInTry_UsedInFinally_NoDiagnostic_02() - { - await TestDiagnosticMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39755")] + public async Task AssignmentInTry_UsedInFinally_NoDiagnostic_02() + { + await TestDiagnosticMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + IntPtr a = (IntPtr)1; + try { - IntPtr a = (IntPtr)1; - try - { - var b = a; + var b = a; - if (Some(a)) - [|a|] = IntPtr.Zero; - } - finally + if (Some(a)) + [|a|] = IntPtr.Zero; + } + finally + { + if (a != IntPtr.Zero) { - if (a != IntPtr.Zero) - { - } } } - - bool Some(IntPtr a) => true; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39755")] - public async Task AssignmentInTry_NotUsedInFinally_Diagnostic() - { - await TestInRegularAndScriptAsync( - """ - using System; + bool Some(IntPtr a) => true; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39755")] + public async Task AssignmentInTry_NotUsedInFinally_Diagnostic() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int i) { - void M(int i) - { - bool b = false; - try - { - if (i == 0) - { - [|b|] = true; - } - } - finally + bool b = false; + try + { + if (i == 0) { + [|b|] = true; } } - } - """, - """ - using System; - - class C - { - void M(int i) + finally { - bool b = false; - try - { - if (i == 0) - { - } - } - finally - { - } } } - """, options: PreferDiscard); - } + } + """, + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38507")] - public async Task TestCodeFixTitleForBlockBodyRedundantCompoundAssignmentReturn() - { - var source = """ - class C + class C + { + void M(int i) { - C M(C x) + bool b = false; + try + { + if (i == 0) + { + } + } + finally { - return [|x ??= M2()|]; } + } + } + """, options: PreferDiscard); + } - C M2() => new C(); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38507")] + public async Task TestCodeFixTitleForBlockBodyRedundantCompoundAssignmentReturn() + { + var source = """ + class C + { + C M(C x) + { + return [|x ??= M2()|]; } - """; - await TestExactActionSetOfferedAsync(source, [CodeFixesResources.Remove_redundant_assignment]); - } + C M2() => new C(); + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38507")] - public async Task TestCodeFixTitleForExpressionBodyRedundantCompoundAssignmentReturn() - { - var source = """ - class C - { - C M(C x) => [|x ??= M2()|]; + await TestExactActionSetOfferedAsync(source, [CodeFixesResources.Remove_redundant_assignment]); + } - C M2() => new C(); - } - """; - await TestExactActionSetOfferedAsync(source, [CodeFixesResources.Remove_redundant_assignment]); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38507")] + public async Task TestCodeFixTitleForExpressionBodyRedundantCompoundAssignmentReturn() + { + var source = """ + class C + { + C M(C x) => [|x ??= M2()|]; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38507")] - public async Task TestCodeFixTitleForPatternMatching() - { - var source = """ - class C + C M2() => new C(); + } + """; + await TestExactActionSetOfferedAsync(source, [CodeFixesResources.Remove_redundant_assignment]); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38507")] + public async Task TestCodeFixTitleForPatternMatching() + { + var source = """ + class C + { + void M() { - void M() + var c = M2(); + if [|(c is object obj)|] { - var c = M2(); - if [|(c is object obj)|] - { - } } - - C M2() => new C(); } - """; - await TestExactActionSetOfferedAsync(source, [CodeFixesResources.Remove_redundant_assignment]); - } + C M2() => new C(); + } + """; - [Fact, WorkItem(38507, "https://github.com/dotnet/roslyn/issues/46251")] - public async Task TestCodeFixForAllInDocumentForNestedDiagnostic() - { - var source = """ - using System; - namespace ConsoleApp + await TestExactActionSetOfferedAsync(source, [CodeFixesResources.Remove_redundant_assignment]); + } + + [Fact, WorkItem(38507, "https://github.com/dotnet/roslyn/issues/46251")] + public async Task TestCodeFixForAllInDocumentForNestedDiagnostic() + { + var source = """ + using System; + namespace ConsoleApp + { + public static class ConsoleApp { - public static class ConsoleApp + public static void Main(string[] args) { - public static void Main(string[] args) - { - {|FixAllInDocument:Foo(() => { Bar(); return true; })|}; - } + {|FixAllInDocument:Foo(() => { Bar(); return true; })|}; + } - public static bool Foo(Func func) - { - return func. Invoke(); - } + public static bool Foo(Func func) + { + return func. Invoke(); + } - public static bool Bar() - { - return true; - } - } - } - """; - var expected = """ - using System; - namespace ConsoleApp + public static bool Bar() + { + return true; + } + } + } + """; + var expected = """ + using System; + namespace ConsoleApp + { + public static class ConsoleApp { - public static class ConsoleApp + public static void Main(string[] args) { - public static void Main(string[] args) - { - _ = Foo(() => { _ = Bar(); return true; }); - } + _ = Foo(() => { _ = Bar(); return true; }); + } - public static bool Foo(Func func) - { - return func. Invoke(); - } + public static bool Foo(Func func) + { + return func. Invoke(); + } - public static bool Bar() - { - return true; - } - } - } - """; - await TestInRegularAndScriptAsync(source, expected, options: PreferDiscard).ConfigureAwait(false); - } + public static bool Bar() + { + return true; + } + } + } + """; + await TestInRegularAndScriptAsync(source, expected, options: PreferDiscard).ConfigureAwait(false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45768")] - public async Task UnusedVarPattern_PartOfCase() - { - await TestInRegularAndScriptAsync( - """ - static class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45768")] + public async Task UnusedVarPattern_PartOfCase() + { + await TestInRegularAndScriptAsync( + """ + static class Program + { + public static void Main() { - public static void Main() + switch (string.Empty.Length) { - switch (string.Empty.Length) + case var [|i|] when string.Empty.Length switch { var y => y > 0 }: { - case var [|i|] when string.Empty.Length switch { var y => y > 0 }: - { - break; - } + break; } } } - """, - """ - static class Program + } + """, + """ + static class Program + { + public static void Main() { - public static void Main() + switch (string.Empty.Length) { - switch (string.Empty.Length) + case var _ when string.Empty.Length switch { var y => y > 0 }: { - case var _ when string.Empty.Length switch { var y => y > 0 }: - { - break; - } + break; } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45768")] - public async Task UnusedVarPattern_PartOfIs() - { - await TestInRegularAndScriptAsync( - """ - static class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45768")] + public async Task UnusedVarPattern_PartOfIs() + { + await TestInRegularAndScriptAsync( + """ + static class Program + { + public static void Main() { - public static void Main() + if (string.Empty.Length is var [|x|]) { - if (string.Empty.Length is var [|x|]) - { - } } } - """, - """ - static class Program + } + """, + """ + static class Program + { + public static void Main() { - public static void Main() + if (string.Empty.Length is var _) { - if (string.Empty.Length is var _) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45768")] - public async Task UnusedVarPattern_TestTrivia() - { - await TestInRegularAndScriptAsync( - """ - static class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45768")] + public async Task UnusedVarPattern_TestTrivia() + { + await TestInRegularAndScriptAsync( + """ + static class Program + { + public static void Main() { - public static void Main() + if (string.Empty.Length is var [|/*1*/x/*2*/|]) { - if (string.Empty.Length is var [|/*1*/x/*2*/|]) - { - } } } - """, - """ - static class Program + } + """, + """ + static class Program + { + public static void Main() { - public static void Main() + if (string.Empty.Length is var /*1*/_/*2*/) { - if (string.Empty.Length is var /*1*/_/*2*/) - { - } } } - """, options: PreferDiscard); - } + } + """, options: PreferDiscard); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/57650")] - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task UseInLambda_WithInvocationOutsideLocalScope(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [WorkItem("https://github.com/dotnet/roslyn/issues/57650")] + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task UseInLambda_WithInvocationOutsideLocalScope(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Action act = null; { - Action act = null; - { - var[| capture |] = new object(); - act = () => capture.ToString(); - } - act(); + var[| capture |] = new object(); + act = () => capture.ToString(); } + act(); } - """, optionName); - } + } + """, optionName); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64291")] - public async Task TestImplicitObjectCreationInInitialization() - { - var source = - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64291")] + public async Task TestImplicitObjectCreationInInitialization() + { + var source = + """ + class C + { + void M() { - void M() - { - C {|IDE0059:c|} = new(); - } + C {|IDE0059:c|} = new(); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void M() { - void M() - { - _ = new C(); - } + _ = new C(); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64291")] - public async Task TestImplicitObjectCreationInAssignment() - { - var source = - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/64291")] + public async Task TestImplicitObjectCreationInAssignment() + { + var source = + """ + class C + { + void M(C c) { - void M(C c) - { - System.Console.WriteLine(c); - {|IDE0059:c|} = new(); - } + System.Console.WriteLine(c); + {|IDE0059:c|} = new(); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void M(C c) { - void M(C c) - { - System.Console.WriteLine(c); - _ = new C(); - } + System.Console.WriteLine(c); + _ = new C(); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestPropertyPatternAssignment1() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestPropertyPatternAssignment1() + { + var source = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { } {|IDE0059:str|}) { - if (obj is string { } {|IDE0059:str|}) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { }) { - if (obj is string { }) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestPropertyPatternAssignment2() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestPropertyPatternAssignment2() + { + var source = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { Length: > 0 } {|IDE0059:str|}) { - if (obj is string { Length: > 0 } {|IDE0059:str|}) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { Length: > 0 }) { - if (obj is string { Length: > 0 }) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestPropertyPatternAssignment3() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestPropertyPatternAssignment3() + { + var source = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { Length: { } {|IDE0059:length|} }) { - if (obj is string { Length: { } {|IDE0059:length|} }) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { Length: { } }) { - if (obj is string { Length: { } }) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestPropertyPatternAssignment4() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestPropertyPatternAssignment4() + { + var source = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { Length: { } {|IDE0059:length|} } {|IDE0059:str|}) { - if (obj is string { Length: { } {|IDE0059:length|} } {|IDE0059:str|}) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(object obj) { - void M(object obj) + if (obj is string { Length: { } }) { - if (obj is string { Length: { } }) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestListPatternAssignment1() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestListPatternAssignment1() + { + var source = """ + class C + { + void M(string s) { - void M(string s) + if (s is [] {|IDE0059:str|}) { - if (s is [] {|IDE0059:str|}) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(string s) { - void M(string s) + if (s is []) { - if (s is []) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestListPatternAssignment2() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestListPatternAssignment2() + { + var source = """ + class C + { + void M(string[] ss) { - void M(string[] ss) + if (ss is [[] {|IDE0059:str|}]) { - if (ss is [[] {|IDE0059:str|}]) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(string[] ss) { - void M(string[] ss) + if (ss is [[]]) { - if (ss is [[]]) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] - public async Task TestListPatternAssignment3() - { - var source = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66573")] + public async Task TestListPatternAssignment3() + { + var source = """ + class C + { + void M(string[] ss) { - void M(string[] ss) + if (ss is [[] {|IDE0059:str|}] {|IDE0059:strings|}) { - if (ss is [[] {|IDE0059:str|}] {|IDE0059:strings|}) - { - } } } - """; + } + """; - var fixedSource = """ - class C + var fixedSource = """ + class C + { + void M(string[] ss) { - void M(string[] ss) + if (ss is [[]]) { - if (ss is [[]]) - { - } } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = fixedSource, + Options = { - TestCode = source, - FixedCode = fixedSource, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp11, - ReferenceAssemblies = ReferenceAssemblies.Net.Net70, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp11, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69643")] - public async Task TestPrimaryConstructorParameterAssignment() - { - var source = """ - class C(string str) { - public void Reset() { - str = string.Empty; - } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69643")] + public async Task TestPrimaryConstructorParameterAssignment() + { + var source = """ + class C(string str) { + public void Reset() { + str = string.Empty; + } + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + Options = { - TestCode = source, - FixedCode = source, - Options = - { - { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, - }, - LanguageVersion = LanguageVersion.CSharp12, - ReferenceAssemblies = ReferenceAssemblies.Net.Net80, - }.RunAsync(); - } + { CSharpCodeStyleOptions.UnusedValueAssignment, UnusedValuePreference.DiscardVariable }, + }, + LanguageVersion = LanguageVersion.CSharp12, + ReferenceAssemblies = ReferenceAssemblies.Net.Net80, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueExpressionStatementTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueExpressionStatementTests.cs index 21900f86a38b5..1eab2bb220d85 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueExpressionStatementTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValueExpressionStatementTests.cs @@ -14,711 +14,710 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues; + +[Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] +public partial class RemoveUnusedValueExpressionStatementTests : RemoveUnusedValuesTestsBase { - [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedValues)] - public partial class RemoveUnusedValueExpressionStatementTests : RemoveUnusedValuesTestsBase + public RemoveUnusedValueExpressionStatementTests(ITestOutputHelper logger) + : base(logger) { - public RemoveUnusedValueExpressionStatementTests(ITestOutputHelper logger) - : base(logger) - { - } - - private protected override OptionsCollection PreferNone - => Option(CSharpCodeStyleOptions.UnusedValueExpressionStatement, - new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.None)); - - private protected override OptionsCollection PreferDiscard - => Option(CSharpCodeStyleOptions.UnusedValueExpressionStatement, - new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.Silent)); - - private protected override OptionsCollection PreferUnusedLocal - => Option(CSharpCodeStyleOptions.UnusedValueExpressionStatement, - new CodeStyleOption2(UnusedValuePreference.UnusedLocalVariable, NotificationOption2.Silent)); - - [Fact] - public async Task ExpressionStatement_Suppressed() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void M() - { - [|M2()|]; - } + } - int M2() => 0; - } - """, options: PreferNone); - } + private protected override OptionsCollection PreferNone + => Option(CSharpCodeStyleOptions.UnusedValueExpressionStatement, + new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.None)); - [Fact] - public async Task ExpressionStatement_PreferDiscard_CSharp6() - { - // Discard not supported in C# 6.0, so we fallback to unused local variable. - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - { - [|M2()|]; - } + private protected override OptionsCollection PreferDiscard + => Option(CSharpCodeStyleOptions.UnusedValueExpressionStatement, + new CodeStyleOption2(UnusedValuePreference.DiscardVariable, NotificationOption2.Silent)); - int M2() => 0; - } - """, - """ - class C - { - void M() - { - var unused = M2(); - } + private protected override OptionsCollection PreferUnusedLocal + => Option(CSharpCodeStyleOptions.UnusedValueExpressionStatement, + new CodeStyleOption2(UnusedValuePreference.UnusedLocalVariable, NotificationOption2.Silent)); - int M2() => 0; + [Fact] + public async Task ExpressionStatement_Suppressed() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + [|M2()|]; } - """, options: PreferDiscard, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6)); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_VariableInitialization(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void M() - { - int x = [|M2()|]; - } + int M2() => 0; + } + """, options: PreferNone); + } - int M2() => 0; + [Fact] + public async Task ExpressionStatement_PreferDiscard_CSharp6() + { + // Discard not supported in C# 6.0, so we fallback to unused local variable. + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + [|M2()|]; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused")] - public async Task ExpressionStatement_NonConstantPrimitiveTypeValue(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + void M() { - void M() - { - [|M2()|]; - } - - int M2() => 0; + var unused = M2(); } - """, - $$""" - class C - { - void M() - { - {{fix}} = M2(); - } - int M2() => 0; - } - """, optionName); - } + int M2() => 0; + } + """, options: PreferDiscard, +parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6)); + } - [Theory] - [InlineData(nameof(PreferDiscard), "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused")] - public async Task ExpressionStatement_UserDefinedType(string optionName, string fix) - { - await TestInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_VariableInitialization(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - [|M2()|]; - } - - C M2() => new C(); + int x = [|M2()|]; } - """, - $$""" - class C - { - void M() - { - {{fix}} = M2(); - } - C M2() => new C(); - } - """, optionName); - } + int M2() => 0; + } + """, optionName); + } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_ConstantValue(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused")] + public async Task ExpressionStatement_NonConstantPrimitiveTypeValue(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - [|1|]; - } + [|M2()|]; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_SyntaxError(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + $$""" + class C + { + void M() { - void M() - { - [|M2(,)|]; - } - - int M2() => 0; + {{fix}} = M2(); } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_SemanticError(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard), "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused")] + public async Task ExpressionStatement_UserDefinedType(string optionName, string fix) + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - [|M2()|]; - } + [|M2()|]; } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33073")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_SemanticError_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + C M2() => new C(); + } + """, + $$""" + class C + { + void M() { - void M() - { - [|M2()|]; - } - - UndefinedType M2() => null; + {{fix}} = M2(); } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33073")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_SemanticError_03(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Threading.Tasks; + C M2() => new C(); + } + """, optionName); + } - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_ConstantValue(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - private async Task M() - { - // error CS0103: The name 'CancellationToken' does not exist in the current context - [|await Task.Delay(0, CancellationToken.None).ConfigureAwait(false)|]; - } + [|1|]; } - """, optionName); - } + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33073")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_SemanticError_04(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_SyntaxError(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - private async Task M() - { - // error CS0103: The name 'Task' does not exist in the current context - // error CS0103: The name 'CancellationToken' does not exist in the current context - // error CS1983: The return type of an async method must be void, Task or Task - [|await Task.Delay(0, CancellationToken.None).ConfigureAwait(false)|]; - } + [|M2(,)|]; } - """, optionName); - } - [Theory] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_VoidReturningMethodCall(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void M() - { - [|M2()|]; - } + int M2() => 0; + } + """, optionName); + } - void M2() { } + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_SemanticError(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + [|M2()|]; } - """, optionName); - } + } + """, optionName); + } - [Theory] - [InlineData("=")] - [InlineData("+=")] - public async Task ExpressionStatement_AssignmentExpression(string op) - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33073")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_SemanticError_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M(int x) - { - x {{op}} [|M2()|]; - } + [|M2()|]; + } - int M2() => 0; + UndefinedType M2() => null; + } + """, optionName); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33073")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_SemanticError_03(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Threading.Tasks; + + class C + { + private async Task M() + { + // error CS0103: The name 'CancellationToken' does not exist in the current context + [|await Task.Delay(0, CancellationToken.None).ConfigureAwait(false)|]; } - """); - } + } + """, optionName); + } - [Theory] - [InlineData("x++")] - [InlineData("x--")] - [InlineData("++x")] - [InlineData("--x")] - public async Task ExpressionStatement_IncrementOrDecrement(string incrementOrDecrement) - { - await TestMissingInRegularAndScriptWithAllOptionsAsync( - $$""" - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33073")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_SemanticError_04(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + private async Task M() + { + // error CS0103: The name 'Task' does not exist in the current context + // error CS0103: The name 'CancellationToken' does not exist in the current context + // error CS1983: The return type of an async method must be void, Task or Task + [|await Task.Delay(0, CancellationToken.None).ConfigureAwait(false)|]; + } + } + """, optionName); + } + + [Theory] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_VoidReturningMethodCall(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - int M(int x) - { - [|{{incrementOrDecrement}}|]; - return x; - } + [|M2()|]; } - """); - } - [Fact] - public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed() - { - await TestInRegularAndScriptAsync( - """ - class C + void M2() { } + } + """, optionName); + } + + [Theory] + [InlineData("=")] + [InlineData("+=")] + public async Task ExpressionStatement_AssignmentExpression(string op) + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + void M(int x) { - void M() - { - var unused = M2(); - [|M2()|]; - } + x {{op}} [|M2()|]; + } - int M2() => 0; + int M2() => 0; + } + """); + } + + [Theory] + [InlineData("x++")] + [InlineData("x--")] + [InlineData("++x")] + [InlineData("--x")] + public async Task ExpressionStatement_IncrementOrDecrement(string incrementOrDecrement) + { + await TestMissingInRegularAndScriptWithAllOptionsAsync( + $$""" + class C + { + int M(int x) + { + [|{{incrementOrDecrement}}|]; + return x; } - """, - """ - class C + } + """); + } + + [Fact] + public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - var unused = M2(); - var unused1 = M2(); - } + var unused = M2(); + [|M2()|]; + } - int M2() => 0; + int M2() => 0; + } + """, + """ + class C + { + void M() + { + var unused = M2(); + var unused1 = M2(); } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed_02() - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed_02() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - [|M2()|]; - var unused = M2(); - } + [|M2()|]; + var unused = M2(); + } - int M2() => 0; + int M2() => 0; + } + """, + """ + class C + { + void M() + { + var unused1 = M2(); + var unused = M2(); } - """, - """ - class C + + int M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Fact] + public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed_03() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(int p) { - void M() + [|M2()|]; + if (p > 0) { - var unused1 = M2(); var unused = M2(); } - - int M2() => 0; } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed_03() - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + void M(int p) { - void M(int p) + var unused1 = M2(); + if (p > 0) { - [|M2()|]; - if (p > 0) - { - var unused = M2(); - } + var unused = M2(); } - - int M2() => 0; } - """, - """ - class C - { - void M(int p) - { - var unused1 = M2(); - if (p > 0) - { - var unused = M2(); - } - } - int M2() => 0; - } - """, options: PreferUnusedLocal); - } + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - [Fact] - public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed_04() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ExpressionStatement_UnusedLocal_NameAlreadyUsed_04() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(int p) { - void M(int p) + if (p > 0) { - if (p > 0) - { - [|M2()|]; - } - else - { - var unused = M2(); - } + [|M2()|]; } - - int M2() => 0; - } - """, - """ - class C - { - void M(int p) + else { - if (p > 0) - { - var unused1 = M2(); - } - else - { - var unused = M2(); - } + var unused = M2(); } - - int M2() => 0; } - """, options: PreferUnusedLocal); - } - [Theory] - [InlineData(nameof(PreferDiscard), "_", "_", "_")] - [InlineData(nameof(PreferUnusedLocal), "var unused", "var unused", "var unused3")] - public async Task ExpressionStatement_FixAll(string optionName, string fix1, string fix2, string fix3) - { - await TestInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + void M(int p) { - public C() + if (p > 0) { - M2(); // Separate code block + var unused1 = M2(); } - - void M(int unused1, int unused2) + else { - {|FixAllInDocument:M2()|}; - M2(); // Another instance in same code block - _ = M2(); // Already fixed - var x = M2(); // Different unused value diagnostic + var unused = M2(); } - - int M2() => 0; } - """, - $$""" - class C - { - public C() - { - {{fix1}} = M2(); // Separate code block - } - void M(int unused1, int unused2) - { - {{fix3}} = M2(); - {{fix2}} = M2(); // Another instance in same code block - _ = M2(); // Already fixed - var x = M2(); // Different unused value diagnostic - } + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - int M2() => 0; + [Theory] + [InlineData(nameof(PreferDiscard), "_", "_", "_")] + [InlineData(nameof(PreferUnusedLocal), "var unused", "var unused", "var unused3")] + public async Task ExpressionStatement_FixAll(string optionName, string fix1, string fix2, string fix3) + { + await TestInRegularAndScriptAsync( + """ + class C + { + public C() + { + M2(); // Separate code block } - """, optionName); - } - [Fact] - public async Task ExpressionStatement_Trivia_PreferDiscard_01() - { - await TestInRegularAndScriptAsync( - """ - class C + void M(int unused1, int unused2) { - void M() - { - // C1 - [|M2()|]; // C2 - // C3 - } - - int M2() => 0; + {|FixAllInDocument:M2()|}; + M2(); // Another instance in same code block + _ = M2(); // Already fixed + var x = M2(); // Different unused value diagnostic } - """, - """ - class C - { - void M() - { - // C1 - _ = M2(); // C2 - // C3 - } - int M2() => 0; + int M2() => 0; + } + """, + $$""" + class C + { + public C() + { + {{fix1}} = M2(); // Separate code block } - """, options: PreferDiscard); - } - [Fact] - public async Task ExpressionStatement_Trivia_PreferDiscard_02() - { - await TestInRegularAndScriptAsync( - """ - class C + void M(int unused1, int unused2) { - void M() - {/*C0*/ - /*C1*/[|M2()|]/*C2*/;/*C3*/ - /*C4*/ - } - - int M2() => 0; + {{fix3}} = M2(); + {{fix2}} = M2(); // Another instance in same code block + _ = M2(); // Already fixed + var x = M2(); // Different unused value diagnostic } - """, - """ - class C - { - void M() - {/*C0*/ - /*C1*/ - _ = M2()/*C2*/;/*C3*/ - /*C4*/ - } - int M2() => 0; - } - """, options: PreferDiscard); - } + int M2() => 0; + } + """, optionName); + } - [Fact] - public async Task ExpressionStatement_Trivia_PreferUnusedLocal_01() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ExpressionStatement_Trivia_PreferDiscard_01() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - // C1 - [|M2()|]; // C2 - // C3 - } - - int M2() => 0; + // C1 + [|M2()|]; // C2 + // C3 } - """, - """ - class C - { - void M() - { - // C1 - var unused = M2(); // C2 - // C3 - } - int M2() => 0; + int M2() => 0; + } + """, + """ + class C + { + void M() + { + // C1 + _ = M2(); // C2 + // C3 } - """, options: PreferUnusedLocal); - } - [Fact] - public async Task ExpressionStatement_Trivia_PreferUnusedLocal_02() - { - await TestInRegularAndScriptAsync( - """ - class C - { - void M() - {/*C0*/ - /*C1*/[|M2()|]/*C2*/;/*C3*/ - /*C4*/ - } + int M2() => 0; + } + """, options: PreferDiscard); + } - int M2() => 0; - } - """, - """ - class C - { - void M() - {/*C0*/ - /*C1*/ - var unused = M2()/*C2*/;/*C3*/ - /*C4*/ - } + [Fact] + public async Task ExpressionStatement_Trivia_PreferDiscard_02() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + {/*C0*/ + /*C1*/[|M2()|]/*C2*/;/*C3*/ + /*C4*/ + } + + int M2() => 0; + } + """, + """ + class C + { + void M() + {/*C0*/ + /*C1*/ + _ = M2()/*C2*/;/*C3*/ + /*C4*/ + } + + int M2() => 0; + } + """, options: PreferDiscard); + } - int M2() => 0; + [Fact] + public async Task ExpressionStatement_Trivia_PreferUnusedLocal_01() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + { + // C1 + [|M2()|]; // C2 + // C3 } - """, options: PreferUnusedLocal); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32942")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionBodiedMember_01(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + int M2() => 0; + } + """, + """ + class C + { + void M() { - void M() => [|M2()|]; - int M2() => 0; + // C1 + var unused = M2(); // C2 + // C3 } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32942")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionBodiedMember_02(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void M() - { - System.Action a = () => [|M2()|]; - } + int M2() => 0; + } + """, options: PreferUnusedLocal); + } - int M2() => 0; - } - """, optionName); - } + [Fact] + public async Task ExpressionStatement_Trivia_PreferUnusedLocal_02() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() + {/*C0*/ + /*C1*/[|M2()|]/*C2*/;/*C3*/ + /*C4*/ + } + + int M2() => 0; + } + """, + """ + class C + { + void M() + {/*C0*/ + /*C1*/ + var unused = M2()/*C2*/;/*C3*/ + /*C4*/ + } + + int M2() => 0; + } + """, options: PreferUnusedLocal); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32942")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionBodiedMember_01(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() => [|M2()|]; + int M2() => 0; + } + """, optionName); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32942")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionBodiedMember_03(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32942")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionBodiedMember_02(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - LocalFunction(); - return; + System.Action a = () => [|M2()|]; + } - void LocalFunction() => [|M2()|]; - } + int M2() => 0; + } + """, optionName); + } - int M2() => 0; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/32942")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionBodiedMember_03(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() + { + LocalFunction(); + return; + + void LocalFunction() => [|M2()|]; } - """, optionName); - } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43648")] - [InlineData(nameof(PreferDiscard))] - [InlineData(nameof(PreferUnusedLocal))] - public async Task ExpressionStatement_Dynamic(string optionName) - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Collections.Generic; + int M2() => 0; + } + """, optionName); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43648")] + [InlineData(nameof(PreferDiscard))] + [InlineData(nameof(PreferUnusedLocal))] + public async Task ExpressionStatement_Dynamic(string optionName) + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Collections.Generic; - class C + class C + { + void M() { - void M() - { - List returnValue = new List(); + List returnValue = new List(); - dynamic dynamicValue = new object(); + dynamic dynamicValue = new object(); - [|returnValue.Add(dynamicValue)|]; - } + [|returnValue.Add(dynamicValue)|]; } - """, optionName); - } + } + """, optionName); } } diff --git a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValuesTestsBase.cs b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValuesTestsBase.cs index 2d10f3593c9ab..9748413c87d57 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValuesTestsBase.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnusedParametersAndValues/RemoveUnusedValuesTestsBase.cs @@ -12,59 +12,58 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnusedParametersAndValues; + +public abstract class RemoveUnusedValuesTestsBase : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - public abstract class RemoveUnusedValuesTestsBase : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + protected RemoveUnusedValuesTestsBase(ITestOutputHelper logger) + : base(logger) { - protected RemoveUnusedValuesTestsBase(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpRemoveUnusedParametersAndValuesDiagnosticAnalyzer(), new CSharpRemoveUnusedValuesCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpRemoveUnusedParametersAndValuesDiagnosticAnalyzer(), new CSharpRemoveUnusedValuesCodeFixProvider()); - private protected abstract OptionsCollection PreferNone { get; } - private protected abstract OptionsCollection PreferDiscard { get; } - private protected abstract OptionsCollection PreferUnusedLocal { get; } + private protected abstract OptionsCollection PreferNone { get; } + private protected abstract OptionsCollection PreferDiscard { get; } + private protected abstract OptionsCollection PreferUnusedLocal { get; } - private protected OptionsCollection GetOptions(string optionName) + private protected OptionsCollection GetOptions(string optionName) + { + switch (optionName) { - switch (optionName) - { - case nameof(PreferDiscard): - return PreferDiscard; + case nameof(PreferDiscard): + return PreferDiscard; - case nameof(PreferUnusedLocal): - return PreferUnusedLocal; + case nameof(PreferUnusedLocal): + return PreferUnusedLocal; - default: - return PreferNone; - } + default: + return PreferNone; } + } - private protected Task TestMissingInRegularAndScriptAsync(string initialMarkup, OptionsCollection options, ParseOptions parseOptions = null) - => TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options, parseOptions: parseOptions)); - private protected Task TestMissingInRegularAndScriptAsync(string initialMarkup, string optionName, ParseOptions parseOptions = null) - => TestMissingInRegularAndScriptAsync(initialMarkup, GetOptions(optionName), parseOptions); - protected Task TestInRegularAndScriptAsync(string initialMarkup, string expectedMarkup, string optionName, ParseOptions parseOptions = null) - => TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: GetOptions(optionName), parseOptions: parseOptions); + private protected Task TestMissingInRegularAndScriptAsync(string initialMarkup, OptionsCollection options, ParseOptions parseOptions = null) + => TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options, parseOptions: parseOptions)); + private protected Task TestMissingInRegularAndScriptAsync(string initialMarkup, string optionName, ParseOptions parseOptions = null) + => TestMissingInRegularAndScriptAsync(initialMarkup, GetOptions(optionName), parseOptions); + protected Task TestInRegularAndScriptAsync(string initialMarkup, string expectedMarkup, string optionName, ParseOptions parseOptions = null) + => TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: GetOptions(optionName), parseOptions: parseOptions); - // Helpers to test all options - only used by tests which already have InlineData for custom input test code snippets. - protected async Task TestInRegularAndScriptWithAllOptionsAsync(string initialMarkup, string expectedMarkup, ParseOptions parseOptions = null) + // Helpers to test all options - only used by tests which already have InlineData for custom input test code snippets. + protected async Task TestInRegularAndScriptWithAllOptionsAsync(string initialMarkup, string expectedMarkup, ParseOptions parseOptions = null) + { + foreach (var options in new[] { PreferDiscard, PreferUnusedLocal }) { - foreach (var options in new[] { PreferDiscard, PreferUnusedLocal }) - { - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: options, parseOptions: parseOptions); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: options, parseOptions: parseOptions); } + } - protected async Task TestMissingInRegularAndScriptWithAllOptionsAsync(string initialMarkup, ParseOptions parseOptions = null) + protected async Task TestMissingInRegularAndScriptWithAllOptionsAsync(string initialMarkup, ParseOptions parseOptions = null) + { + foreach (var options in new[] { PreferDiscard, PreferUnusedLocal }) { - foreach (var options in new[] { PreferDiscard, PreferUnusedLocal }) - { - await TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options, parseOptions: parseOptions)); - } + await TestMissingInRegularAndScriptAsync(initialMarkup, new TestParameters(options: options, parseOptions: parseOptions)); } } } diff --git a/src/Analyzers/CSharp/Tests/ReplaceDefaultLiteral/ReplaceDefaultLiteralTests.cs b/src/Analyzers/CSharp/Tests/ReplaceDefaultLiteral/ReplaceDefaultLiteralTests.cs index 383e1670779f6..22c0a667c9837 100644 --- a/src/Analyzers/CSharp/Tests/ReplaceDefaultLiteral/ReplaceDefaultLiteralTests.cs +++ b/src/Analyzers/CSharp/Tests/ReplaceDefaultLiteral/ReplaceDefaultLiteralTests.cs @@ -13,1023 +13,1022 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ReplaceDefaultLiteral +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ReplaceDefaultLiteral; + +[Trait(Traits.Feature, Traits.Features.CodeActionsReplaceDefaultLiteral)] +public sealed class ReplaceDefaultLiteralTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsReplaceDefaultLiteral)] - public sealed class ReplaceDefaultLiteralTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public ReplaceDefaultLiteralTests(ITestOutputHelper logger) + : base(logger) { - public ReplaceDefaultLiteralTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpReplaceDefaultLiteralCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpReplaceDefaultLiteralCodeFixProvider()); - private static readonly ImmutableArray s_csharp7_1above = - ImmutableArray.Create( - LanguageVersion.CSharp7_1, - LanguageVersion.Latest); + private static readonly ImmutableArray s_csharp7_1above = + ImmutableArray.Create( + LanguageVersion.CSharp7_1, + LanguageVersion.Latest); - private static readonly ImmutableArray s_csharp7below = - ImmutableArray.Create( - LanguageVersion.CSharp7, - LanguageVersion.CSharp6, - LanguageVersion.CSharp5, - LanguageVersion.CSharp4, - LanguageVersion.CSharp3, - LanguageVersion.CSharp2, - LanguageVersion.CSharp1); + private static readonly ImmutableArray s_csharp7below = + ImmutableArray.Create( + LanguageVersion.CSharp7, + LanguageVersion.CSharp6, + LanguageVersion.CSharp5, + LanguageVersion.CSharp4, + LanguageVersion.CSharp3, + LanguageVersion.CSharp2, + LanguageVersion.CSharp1); - private async Task TestWithLanguageVersionsAsync(string initialMarkup, string expectedMarkup, ImmutableArray versions) + private async Task TestWithLanguageVersionsAsync(string initialMarkup, string expectedMarkup, ImmutableArray versions) + { + foreach (var version in versions) { - foreach (var version in versions) - { - await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(version)); - } + await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, + parseOptions: CSharpParseOptions.Default.WithLanguageVersion(version)); } + } - private async Task TestMissingWithLanguageVersionsAsync(string initialMarkup, ImmutableArray versions) + private async Task TestMissingWithLanguageVersionsAsync(string initialMarkup, ImmutableArray versions) + { + foreach (var version in versions) { - foreach (var version in versions) - { - await TestMissingInRegularAndScriptAsync(initialMarkup, - new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(version))); - } + await TestMissingInRegularAndScriptAsync(initialMarkup, + new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(version))); } + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_Int() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_Int() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case [||]default: } - } - } - """, - """ - class C + switch (1) { case [||]default: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch (1) { case 0: } - } + switch (1) { case 0: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_Int_InParentheses() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_Int_InParentheses() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case ([||]default): } - } - } - """, - """ - class C + switch (1) { case ([||]default): } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch (1) { case (0): } - } + switch (1) { case (0): } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_Int_NotInsideCast() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_Int_NotInsideCast() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case (int)[||]default: } - } + switch (1) { case (int)[||]default: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_Int_NotOnDefaultExpression() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_Int_NotOnDefaultExpression() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case [||]default(int): } - } + switch (1) { case [||]default(int): } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_Int_NotOnNumericLiteral() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_Int_NotOnNumericLiteral() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case [||]0: } - } + switch (1) { case [||]0: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_DateTime() - { - // Note that the default value of a struct type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_DateTime() + { + // Note that the default value of a struct type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (System.DateTime.Now) { case [||]default: } - } - } - """, - """ - class C + switch (System.DateTime.Now) { case [||]default: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch (System.DateTime.Now) { case default(System.DateTime): } - } + switch (System.DateTime.Now) { case default(System.DateTime): } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCaseSwitchLabel_TupleType() - { - // Note that the default value of a tuple type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCaseSwitchLabel_TupleType() + { + // Note that the default value of a tuple type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch ((0, true)) { case [||]default: } - } - } - """, - """ - class C + switch ((0, true)) { case [||]default: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch ((0, true)) { case default((int, bool)): } - } + switch ((0, true)) { case default((int, bool)): } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("value")] - [InlineData("null")] - [InlineData("default")] - [InlineData("() => { }")] - [InlineData("")] - public async Task TestCSharp7_1_InCaseSwitchLabel_NotForInvalidType(string expression) - { - await TestMissingWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("value")] + [InlineData("null")] + [InlineData("default")] + [InlineData("() => { }")] + [InlineData("")] + public async Task TestCSharp7_1_InCaseSwitchLabel_NotForInvalidType(string expression) + { + await TestMissingWithLanguageVersionsAsync( + $$""" + class C + { + void M() { - void M() - { - switch ({{expression}}) { case [||]default: } - } + switch ({{expression}}) { case [||]default: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case [||]default when true: } - } - } - """, - """ - class C + switch (1) { case [||]default when true: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch (1) { case 0 when true: } - } + switch (1) { case 0 when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_InParentheses() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_InParentheses() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case ([||]default) when true: } - } - } - """, - """ - class C + switch (1) { case ([||]default) when true: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch (1) { case (0) when true: } - } + switch (1) { case (0) when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_NotInsideCast() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_NotInsideCast() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case (int)[||]default when true: } - } + switch (1) { case (int)[||]default when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_NotOnDefaultExpression() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_NotOnDefaultExpression() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case [||]default(int) when true: } - } + switch (1) { case [||]default(int) when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_NotOnNumericLiteral() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_Int_NotOnNumericLiteral() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (1) { case [||]0 when true: } - } + switch (1) { case [||]0 when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_DateTime() - { - // Note that the default value of a struct type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_DateTime() + { + // Note that the default value of a struct type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch (System.DateTime.Now) { case [||]default when true: } - } - } - """, - """ - class C + switch (System.DateTime.Now) { case [||]default when true: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch (System.DateTime.Now) { case default(System.DateTime) when true: } - } + switch (System.DateTime.Now) { case default(System.DateTime) when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_TupleType() - { - // Note that the default value of a tuple type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_TupleType() + { + // Note that the default value of a tuple type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - switch ((0, true)) { case [||]default when true: } - } - } - """, - """ - class C + switch ((0, true)) { case [||]default when true: } + } + } + """, + """ + class C + { + void M() { - void M() - { - switch ((0, true)) { case default((int, bool)) when true: } - } + switch ((0, true)) { case default((int, bool)) when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("value")] - [InlineData("null")] - [InlineData("default")] - [InlineData("() => { }")] - [InlineData("")] - public async Task TestCSharp7_1_InCasePatternSwitchLabel_NotForInvalidType(string expression) - { - await TestMissingWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("value")] + [InlineData("null")] + [InlineData("default")] + [InlineData("() => { }")] + [InlineData("")] + public async Task TestCSharp7_1_InCasePatternSwitchLabel_NotForInvalidType(string expression) + { + await TestMissingWithLanguageVersionsAsync( + $$""" + class C + { + void M() { - void M() - { - switch ({{expression}}) { case [||]default when true: } - } + switch ({{expression}}) { case [||]default when true: } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Bool() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_Bool() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (true is [||]default) { } - } - } - """, - """ - class C + if (true is [||]default) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if (true is false) { } - } + if (true is false) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Bool_InParentheses() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_Bool_InParentheses() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (true is ([||]default)) { } - } - } - """, - """ - class C + if (true is ([||]default)) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if (true is (false)) { } - } + if (true is (false)) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Bool_NotInsideCast() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_Bool_NotInsideCast() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (true is (bool)[||]default) { } - } + if (true is (bool)[||]default) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Bool_NotOnDefaultExpression() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_Bool_NotOnDefaultExpression() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (true is [||]default(bool)) { } - } + if (true is [||]default(bool)) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Bool_NotOnFalseLiteral() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_Bool_NotOnFalseLiteral() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (true is [||]false) { } - } + if (true is [||]false) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("int", "0")] - [InlineData("uint", "0U")] - [InlineData("byte", "0")] - [InlineData("sbyte", "0")] - [InlineData("short", "0")] - [InlineData("ushort", "0")] - [InlineData("long", "0L")] - [InlineData("ulong", "0UL")] - [InlineData("float", "0F")] - [InlineData("double", "0D")] - [InlineData("decimal", "0M")] - [InlineData("char", "'\\0'")] - [InlineData("string", "null")] - [InlineData("object", "null")] - public async Task TestCSharp7_1_InIsPattern_BuiltInType(string type, string expectedLiteral) - { - await TestWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("int", "0")] + [InlineData("uint", "0U")] + [InlineData("byte", "0")] + [InlineData("sbyte", "0")] + [InlineData("short", "0")] + [InlineData("ushort", "0")] + [InlineData("long", "0L")] + [InlineData("ulong", "0UL")] + [InlineData("float", "0F")] + [InlineData("double", "0D")] + [InlineData("decimal", "0M")] + [InlineData("char", "'\\0'")] + [InlineData("string", "null")] + [InlineData("object", "null")] + public async Task TestCSharp7_1_InIsPattern_BuiltInType(string type, string expectedLiteral) + { + await TestWithLanguageVersionsAsync( + $$""" + class C + { + void M({{type}} value) { - void M({{type}} value) - { - if (value is [||]default) { } - } - } - """, - $$""" - class C + if (value is [||]default) { } + } + } + """, + $$""" + class C + { + void M({{type}} value) { - void M({{type}} value) - { - if (value is {{expectedLiteral}}) { } - } + if (value is {{expectedLiteral}}) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_DateTime() - { - // Note that the default value of a struct type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_DateTime() + { + // Note that the default value of a struct type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (System.DateTime.Now is [||]default) { } - } - } - """, - """ - class C + if (System.DateTime.Now is [||]default) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if (System.DateTime.Now is default(System.DateTime)) { } - } + if (System.DateTime.Now is default(System.DateTime)) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_TupleType() - { - // Note that the default value of a tuple type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_TupleType() + { + // Note that the default value of a tuple type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if ((0, true) is [||]default) { } - } - } - """, - """ - class C + if ((0, true) is [||]default) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if ((0, true) is default((int, bool))) { } - } + if ((0, true) is default((int, bool))) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("class Type { }")] - [InlineData("interface Type { }")] - [InlineData("delegate void Type();")] - public async Task TestCSharp7_1_InIsPattern_CustomReferenceType(string typeDeclaration) - { - await TestWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("class Type { }")] + [InlineData("interface Type { }")] + [InlineData("delegate void Type();")] + public async Task TestCSharp7_1_InIsPattern_CustomReferenceType(string typeDeclaration) + { + await TestWithLanguageVersionsAsync( + $$""" + class C + { + {{typeDeclaration}} + void M() { - {{typeDeclaration}} - void M() - { - if (new Type() is [||]default) { } - } - } - """, - $$""" - class C + if (new Type() is [||]default) { } + } + } + """, + $$""" + class C + { + {{typeDeclaration}} + void M() { - {{typeDeclaration}} - void M() - { - if (new Type() is null) { } - } + if (new Type() is null) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("enum Enum { }")] - [InlineData("enum Enum { None = 0 }")] - [InlineData("[Flags] enum Enum { None = 0 }")] - [InlineData("[System.Flags] enum Enum { None = 1 }")] - [InlineData("[System.Flags] enum Enum { None = 1, None = 0 }")] - [InlineData("[System.Flags] enum Enum { Some = 0 }")] - public async Task TestCSharp7_1_InIsPattern_CustomEnum_WithoutSpecialMember(string enumDeclaration) - { - await TestWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("enum Enum { }")] + [InlineData("enum Enum { None = 0 }")] + [InlineData("[Flags] enum Enum { None = 0 }")] + [InlineData("[System.Flags] enum Enum { None = 1 }")] + [InlineData("[System.Flags] enum Enum { None = 1, None = 0 }")] + [InlineData("[System.Flags] enum Enum { Some = 0 }")] + public async Task TestCSharp7_1_InIsPattern_CustomEnum_WithoutSpecialMember(string enumDeclaration) + { + await TestWithLanguageVersionsAsync( + $$""" + class C + { + {{enumDeclaration}} + void M() { - {{enumDeclaration}} - void M() - { - if (new Enum() is [||]default) { } - } - } - """, - $$""" - class C + if (new Enum() is [||]default) { } + } + } + """, + $$""" + class C + { + {{enumDeclaration}} + void M() { - {{enumDeclaration}} - void M() - { - if (new Enum() is 0) { } - } + if (new Enum() is 0) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("[System.Flags] enum Enum : int { None = 0 }")] - [InlineData("[System.Flags] enum Enum : uint { None = 0 }")] - [InlineData("[System.Flags] enum Enum : byte { None = 0 }")] - [InlineData("[System.Flags] enum Enum : sbyte { None = 0 }")] - [InlineData("[System.Flags] enum Enum : short { None = 0 }")] - [InlineData("[System.Flags] enum Enum : ushort { None = 0 }")] - [InlineData("[System.Flags] enum Enum : long { None = 0 }")] - [InlineData("[System.Flags] enum Enum : ulong { None = 0 }")] - [InlineData("[System.Flags] enum Enum { None = default }")] - [InlineData("[System.Flags] enum Enum { Some = 1, None = 0 }")] - [InlineData("[System.FlagsAttribute] enum Enum { None = 0, Some = 1 }")] - public async Task TestCSharp7_1_InIsPattern_CustomEnum_WithSpecialMember(string enumDeclaration) - { - await TestWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("[System.Flags] enum Enum : int { None = 0 }")] + [InlineData("[System.Flags] enum Enum : uint { None = 0 }")] + [InlineData("[System.Flags] enum Enum : byte { None = 0 }")] + [InlineData("[System.Flags] enum Enum : sbyte { None = 0 }")] + [InlineData("[System.Flags] enum Enum : short { None = 0 }")] + [InlineData("[System.Flags] enum Enum : ushort { None = 0 }")] + [InlineData("[System.Flags] enum Enum : long { None = 0 }")] + [InlineData("[System.Flags] enum Enum : ulong { None = 0 }")] + [InlineData("[System.Flags] enum Enum { None = default }")] + [InlineData("[System.Flags] enum Enum { Some = 1, None = 0 }")] + [InlineData("[System.FlagsAttribute] enum Enum { None = 0, Some = 1 }")] + public async Task TestCSharp7_1_InIsPattern_CustomEnum_WithSpecialMember(string enumDeclaration) + { + await TestWithLanguageVersionsAsync( + $$""" + class C + { + {{enumDeclaration}} + void M() { - {{enumDeclaration}} - void M() - { - if (new Enum() is [||]default) { } - } - } - """, - $$""" - class C + if (new Enum() is [||]default) { } + } + } + """, + $$""" + class C + { + {{enumDeclaration}} + void M() { - {{enumDeclaration}} - void M() - { - if (new Enum() is Enum.None) { } - } + if (new Enum() is Enum.None) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_CustomStruct() - { - // Note that the default value of a struct type is not a constant, so this code is incorrect. - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_CustomStruct() + { + // Note that the default value of a struct type is not a constant, so this code is incorrect. + await TestWithLanguageVersionsAsync( + """ + class C + { + struct Struct { } + void M() { - struct Struct { } - void M() - { - if (new Struct() is [||]default) { } - } - } - """, - """ - class C + if (new Struct() is [||]default) { } + } + } + """, + """ + class C + { + struct Struct { } + void M() { - struct Struct { } - void M() - { - if (new Struct() is default(Struct)) { } - } + if (new Struct() is default(Struct)) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_AnonymousType() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_AnonymousType() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (new { a = 0 } is [||]default) { } - } - } - """, - """ - class C + if (new { a = 0 } is [||]default) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if (new { a = 0 } is null) { } - } + if (new { a = 0 } is null) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("class Container { }")] - [InlineData("interface Container { }")] - [InlineData("delegate void Container();")] - public async Task TestCSharp7_1_InIsPattern_CustomReferenceTypeOfAnonymousType(string typeDeclaration) - { - await TestWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("class Container { }")] + [InlineData("interface Container { }")] + [InlineData("delegate void Container();")] + public async Task TestCSharp7_1_InIsPattern_CustomReferenceTypeOfAnonymousType(string typeDeclaration) + { + await TestWithLanguageVersionsAsync( + $$""" + class C + { + {{typeDeclaration}} + Container ToContainer(T value) => new Container(); + void M() { - {{typeDeclaration}} - Container ToContainer(T value) => new Container(); - void M() - { - if (ToContainer(new { x = 0 }) is [||]default) { } - } - } - """, - $$""" - class C + if (ToContainer(new { x = 0 }) is [||]default) { } + } + } + """, + $$""" + class C + { + {{typeDeclaration}} + Container ToContainer(T value) => new Container(); + void M() { - {{typeDeclaration}} - Container ToContainer(T value) => new Container(); - void M() - { - if (ToContainer(new { x = 0 }) is null) { } - } - } - """, s_csharp7_1above); - } + if (ToContainer(new { x = 0 }) is null) { } + } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_NotForCustomStructOfAnonymousType() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_NotForCustomStructOfAnonymousType() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + struct Container { } + Container ToContainer(T value) => new Container(); + void M() { - struct Container { } - Container ToContainer(T value) => new Container(); - void M() - { - if (ToContainer(new { x = 0 }) is [||]default) { } - } - } - """, s_csharp7_1above); - } + if (ToContainer(new { x = 0 }) is [||]default) { } + } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("System.Threading", "CancellationToken", "None")] - [InlineData("System", "IntPtr", "Zero")] - [InlineData("System", "UIntPtr", "Zero")] - public async Task TestCSharp7_1_InIsPattern_SpecialTypeQualified(string @namespace, string type, string member) - { - await TestWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("System.Threading", "CancellationToken", "None")] + [InlineData("System", "IntPtr", "Zero")] + [InlineData("System", "UIntPtr", "Zero")] + public async Task TestCSharp7_1_InIsPattern_SpecialTypeQualified(string @namespace, string type, string member) + { + await TestWithLanguageVersionsAsync( + $$""" + class C + { + void M() { - void M() - { - if (default({{@namespace}}.{{type}}) is [||]default) { } - } - } - """, - $$""" - class C + if (default({{@namespace}}.{{type}}) is [||]default) { } + } + } + """, + $$""" + class C + { + void M() { - void M() - { - if (default({{@namespace}}.{{type}}) is {{@namespace}}.{{type}}.{{member}}) { } - } + if (default({{@namespace}}.{{type}}) is {{@namespace}}.{{type}}.{{member}}) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("System.Threading", "CancellationToken", "None")] - [InlineData("System", "IntPtr", "Zero")] - [InlineData("System", "UIntPtr", "Zero")] - public async Task TestCSharp7_1_InIsPattern_SpecialTypeUnqualifiedWithUsing(string @namespace, string type, string member) - { - await TestWithLanguageVersionsAsync( - $$""" - using {{@namespace}}; - class C + [Theory] + [InlineData("System.Threading", "CancellationToken", "None")] + [InlineData("System", "IntPtr", "Zero")] + [InlineData("System", "UIntPtr", "Zero")] + public async Task TestCSharp7_1_InIsPattern_SpecialTypeUnqualifiedWithUsing(string @namespace, string type, string member) + { + await TestWithLanguageVersionsAsync( + $$""" + using {{@namespace}}; + class C + { + void M() { - void M() - { - if (default({{type}}) is [||]default) { } - } - } - """, - $$""" - using {{@namespace}}; - class C + if (default({{type}}) is [||]default) { } + } + } + """, + $$""" + using {{@namespace}}; + class C + { + void M() { - void M() - { - if (default({{type}}) is {{type}}.{{member}}) { } - } + if (default({{type}}) is {{type}}.{{member}}) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("CancellationToken")] - [InlineData("IntPtr")] - [InlineData("UIntPtr")] - public async Task TestCSharp7_1_InIsPattern_NotForSpecialTypeUnqualifiedWithoutUsing(string type) - { - await TestMissingWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("CancellationToken")] + [InlineData("IntPtr")] + [InlineData("UIntPtr")] + public async Task TestCSharp7_1_InIsPattern_NotForSpecialTypeUnqualifiedWithoutUsing(string type) + { + await TestMissingWithLanguageVersionsAsync( + $$""" + class C + { + void M() { - void M() - { - if (default({{type}}) is [||]default) { } - } + if (default({{type}}) is [||]default) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_NotForInvalidType1() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C - { - void M() - { - var value; - if (value is [||]default) { } - } + [Fact] + public async Task TestCSharp7_1_InIsPattern_NotForInvalidType1() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() + { + var value; + if (value is [||]default) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("value")] - [InlineData("null")] - [InlineData("default")] - [InlineData("")] - public async Task TestCSharp7_1_InIsPattern_NotForInvalidType2(string expression) - { - await TestMissingWithLanguageVersionsAsync( - $$""" - class C - { - void M() - { - var value = {{expression}}; - if (value is [||]default) { } - } + [Theory] + [InlineData("value")] + [InlineData("null")] + [InlineData("default")] + [InlineData("")] + public async Task TestCSharp7_1_InIsPattern_NotForInvalidType2(string expression) + { + await TestMissingWithLanguageVersionsAsync( + $$""" + class C + { + void M() + { + var value = {{expression}}; + if (value is [||]default) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Theory] - [InlineData("value")] - [InlineData("null")] - [InlineData("default")] - [InlineData("() => { }")] - [InlineData("")] - public async Task TestCSharp7_1_InIsPattern_NotForInvalidType3(string expression) - { - await TestMissingWithLanguageVersionsAsync( - $$""" - class C + [Theory] + [InlineData("value")] + [InlineData("null")] + [InlineData("default")] + [InlineData("() => { }")] + [InlineData("")] + public async Task TestCSharp7_1_InIsPattern_NotForInvalidType3(string expression) + { + await TestMissingWithLanguageVersionsAsync( + $$""" + class C + { + void M() { - void M() - { - if ({{expression}} is [||]default) { } - } + if ({{expression}} is [||]default) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Lambda() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C - { - void M() - { - var value = () => { }; - if (value is [||]default) { } - } + [Fact] + public async Task TestCSharp7_1_InIsPattern_Lambda() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() + { + var value = () => { }; + if (value is [||]default) { } } - """, ImmutableArray.Create(LanguageVersion.CSharp7_1)); - } + } + """, ImmutableArray.Create(LanguageVersion.CSharp7_1)); + } - [Fact] - public async Task TestCSharpLatest_InIsPattern_Lambda() - { - await TestWithLanguageVersionsAsync( - """ - class C - { - void M() - { - var value = () => { }; - if (value is [||]default) { } - } - } - """, - """ - class C - { - void M() - { - var value = () => { }; - if (value is null) { } - } + [Fact] + public async Task TestCSharpLatest_InIsPattern_Lambda() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() + { + var value = () => { }; + if (value is [||]default) { } } - """, ImmutableArray.Create(LanguageVersion.Latest)); - } + } + """, + """ + class C + { + void M() + { + var value = () => { }; + if (value is null) { } + } + } + """, ImmutableArray.Create(LanguageVersion.Latest)); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_Bool_Trivia() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_Bool_Trivia() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (true is - /*a*/ [||]default /*b*/) { } - } - } - """, - """ - class C + if (true is + /*a*/ [||]default /*b*/) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if (true is - /*a*/ false /*b*/) { } - } + if (true is + /*a*/ false /*b*/) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_InIsPattern_DateTime_Trivia() - { - await TestWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_InIsPattern_DateTime_Trivia() + { + await TestWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - if (System.DateTime.Now is - /*a*/ [||]default /*b*/) { } - } - } - """, - """ - class C + if (System.DateTime.Now is + /*a*/ [||]default /*b*/) { } + } + } + """, + """ + class C + { + void M() { - void M() - { - if (System.DateTime.Now is - /*a*/ default(System.DateTime) /*b*/) { } - } + if (System.DateTime.Now is + /*a*/ default(System.DateTime) /*b*/) { } } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_NotInsideExpression() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_NotInsideExpression() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - int i = [||]default; - } + int i = [||]default; } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7_1_NotInsideExpression_InvalidType() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7_1_NotInsideExpression_InvalidType() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - var v = [||]default; - } + var v = [||]default; } - """, s_csharp7_1above); - } + } + """, s_csharp7_1above); + } - [Fact] - public async Task TestCSharp7Lower_NotInsideExpression() - { - await TestMissingWithLanguageVersionsAsync( - """ - class C + [Fact] + public async Task TestCSharp7Lower_NotInsideExpression() + { + await TestMissingWithLanguageVersionsAsync( + """ + class C + { + void M() { - void M() - { - int i = [||]default; - } + int i = [||]default; } - """, s_csharp7below); - } + } + """, s_csharp7below); } } diff --git a/src/Analyzers/CSharp/Tests/SimplifyBooleanExpression/SimplifyConditionalTests.cs b/src/Analyzers/CSharp/Tests/SimplifyBooleanExpression/SimplifyConditionalTests.cs index 7a0024dd1afce..b1ee339594795 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyBooleanExpression/SimplifyConditionalTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyBooleanExpression/SimplifyConditionalTests.cs @@ -13,357 +13,356 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SimplifyBooleanExpression +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SimplifyBooleanExpression; + +[Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyConditional)] +public partial class SimplifyConditionalTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyConditional)] - public partial class SimplifyConditionalTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public SimplifyConditionalTests(ITestOutputHelper logger) + : base(logger) { - public SimplifyConditionalTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpSimplifyConditionalDiagnosticAnalyzer(), new SimplifyConditionalCodeFixProvider()); - - [Fact] - public async Task TestSimpleCase() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C - { - bool M() - { - return [|X() && Y() ? true : false|]; - } + } - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); - } - """, - """ - using System; + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpSimplifyConditionalDiagnosticAnalyzer(), new SimplifyConditionalCodeFixProvider()); - class C - { - bool M() - { - return X() && Y(); - } + [Fact] + public async Task TestSimpleCase() + { + await TestInRegularAndScript1Async( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + bool M() + { + return [|X() && Y() ? true : false|]; } - """); - } - [Fact] - public async Task TestSimpleNegatedCase() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + bool M() { - bool M() - { - return [|X() && Y() ? false : true|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return X() && Y(); } - """, - """ - using System; - class C - { - bool M() - { - return !X() || !Y(); - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } + + [Fact] + public async Task TestSimpleNegatedCase() + { + await TestInRegularAndScript1Async( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + bool M() + { + return [|X() && Y() ? false : true|]; } - """); - } - [Fact] - public async Task TestMustBeBool1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + bool M() { - string M() - { - return [|X() && Y() ? "" : null|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return !X() || !Y(); } - """); - } - [Fact] - public async Task TestMustBeBool2() - { - await TestMissingAsync( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } - class C - { - string M() - { - return [|X() && Y() ? null : ""|]; - } + [Fact] + public async Task TestMustBeBool1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + string M() + { + return [|X() && Y() ? "" : null|]; } - """); - } - [Fact] - public async Task TestWithTrueTrue() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } - class C - { - bool M() - { - return [|X() && Y() ? true : true|]; - } + [Fact] + public async Task TestMustBeBool2() + { + await TestMissingAsync( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + string M() + { + return [|X() && Y() ? null : ""|]; } - """, - """ - using System; - class C - { - bool M() - { - return X() && Y() || true; - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + [Fact] + public async Task TestWithTrueTrue() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + bool M() + { + return [|X() && Y() ? true : true|]; } - """); - } - [Fact] - public async Task TestWithFalseFalse() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + bool M() { - bool M() - { - return [|X() && Y() ? false : false|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return X() && Y() || true; } - """, - """ - using System; - class C - { - bool M() - { - return X() && Y() && false; - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } + + [Fact] + public async Task TestWithFalseFalse() + { + await TestInRegularAndScript1Async( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + bool M() + { + return [|X() && Y() ? false : false|]; } - """); - } - [Fact] - public async Task TestWhenTrueIsTrueAndWhenFalseIsUnknown() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + bool M() { - string M() - { - return [|X() ? true : Y()|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return X() && Y() && false; } - """, - """ - using System; - class C - { - string M() - { - return X() || Y(); - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + [Fact] + public async Task TestWhenTrueIsTrueAndWhenFalseIsUnknown() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + string M() + { + return [|X() ? true : Y()|]; } - """); - } - [Fact] - public async Task TestWhenTrueIsFalseAndWhenFalseIsUnknown() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + string M() { - string M() - { - return [|X() ? false : Y()|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return X() || Y(); } - """, - """ - using System; - class C - { - string M() - { - return !X() && Y(); - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } + + [Fact] + public async Task TestWhenTrueIsFalseAndWhenFalseIsUnknown() + { + await TestInRegularAndScript1Async( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + string M() + { + return [|X() ? false : Y()|]; } - """); - } - [Fact] - public async Task TestWhenTrueIsUnknownAndWhenFalseIsTrue() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + string M() { - string M() - { - return [|X() ? Y() : true|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return !X() && Y(); } - """, - """ - using System; - class C - { - string M() - { - return !X() || Y(); - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + [Fact] + public async Task TestWhenTrueIsUnknownAndWhenFalseIsTrue() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + string M() + { + return [|X() ? Y() : true|]; } - """); - } - [Fact] - public async Task TestWhenTrueIsUnknownAndWhenFalseIsFalse() - { - await TestInRegularAndScript1Async( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + string M() { - string M() - { - return [|X() ? Y() : false|]; - } - - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + return !X() || Y(); } - """, - """ - using System; - class C - { - string M() - { - return X() && Y(); - } + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } + + [Fact] + public async Task TestWhenTrueIsUnknownAndWhenFalseIsFalse() + { + await TestInRegularAndScript1Async( + """ + using System; - private bool X() => throw new NotImplementedException(); - private bool Y() => throw new NotImplementedException(); + class C + { + string M() + { + return [|X() ? Y() : false|]; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62827")] - public async Task TestFixAll() - { - await TestInRegularAndScriptAsync( - """ - using System; + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """, + """ + using System; - class C + class C + { + string M() { - public bool M(object x, object y, Func isEqual) - { - return {|FixAllInDocument:x == null ? false : y == null ? false : isEqual == null ? x.Equals(y) : isEqual(x, y)|}; - } + return X() && Y(); } - """, - """ - using System; - class C + private bool X() => throw new NotImplementedException(); + private bool Y() => throw new NotImplementedException(); + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62827")] + public async Task TestFixAll() + { + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + public bool M(object x, object y, Func isEqual) + { + return {|FixAllInDocument:x == null ? false : y == null ? false : isEqual == null ? x.Equals(y) : isEqual(x, y)|}; + } + } + """, + """ + using System; + + class C + { + public bool M(object x, object y, Func isEqual) { - public bool M(object x, object y, Func isEqual) - { - return x != null && y != null && (isEqual == null ? x.Equals(y) : isEqual(x, y)); - } + return x != null && y != null && (isEqual == null ? x.Equals(y) : isEqual(x, y)); } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/SimplifyInterpolation/SimplifyInterpolationTests.cs b/src/Analyzers/CSharp/Tests/SimplifyInterpolation/SimplifyInterpolationTests.cs index e43ed8ebfa8cc..5c30b9c4c1e95 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyInterpolation/SimplifyInterpolationTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyInterpolation/SimplifyInterpolationTests.cs @@ -13,1351 +13,1350 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SimplifyInterpolation +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SimplifyInterpolation; + +[Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyInterpolation)] +public partial class SimplifyInterpolationTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyInterpolation)] - public partial class SimplifyInterpolationTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public SimplifyInterpolationTests(ITestOutputHelper logger) + : base(logger) { - public SimplifyInterpolationTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpSimplifyInterpolationDiagnosticAnalyzer(), new CSharpSimplifyInterpolationCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpSimplifyInterpolationDiagnosticAnalyzer(), new CSharpSimplifyInterpolationCodeFixProvider()); - [Fact] - public async Task SubsequentUnnecessarySpansDoNotRepeatTheSmartTag() - { - var parameters = new TestParameters(retainNonFixableDiagnostics: true, includeDiagnosticsOutsideSelection: true); + [Fact] + public async Task SubsequentUnnecessarySpansDoNotRepeatTheSmartTag() + { + var parameters = new TestParameters(retainNonFixableDiagnostics: true, includeDiagnosticsOutsideSelection: true); - using var workspace = CreateWorkspaceFromOptions(""" - class C + using var workspace = CreateWorkspaceFromOptions(""" + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}{|Unnecessary:.PadLeft(|}3{|Unnecessary:)|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}{|Unnecessary:.PadLeft(|}3{|Unnecessary:)|}} suffix"; } - """, parameters); + } + """, parameters); - var diagnostics = await GetDiagnosticsWorkerAsync(workspace, parameters); + var diagnostics = await GetDiagnosticsWorkerAsync(workspace, parameters); - Assert.Equal( - new[] { - ("IDE0071", DiagnosticSeverity.Info), - }, - diagnostics.Select(d => (d.Descriptor.Id, d.Severity))); - } + Assert.Equal( + new[] { + ("IDE0071", DiagnosticSeverity.Info), + }, + diagnostics.Select(d => (d.Descriptor.Id, d.Severity))); + } - [Fact] - public async Task ToStringWithNoParameter() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithNoParameter() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue} suffix"; - } + _ = $"prefix {someValue} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithParameter() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithParameter() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int someValue) { - void M(int someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString("|}g{|Unnecessary:")|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString("|}g{|Unnecessary:")|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(int someValue) { - void M(int someValue) - { - _ = $"prefix {someValue:g} suffix"; - } + _ = $"prefix {someValue:g} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithEscapeSequences() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithEscapeSequences() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString("|}\\d \"d\"{|Unnecessary:")|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString("|}\\d \"d\"{|Unnecessary:")|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue:\\d \"d\"} suffix"; - } + _ = $"prefix {someValue:\\d \"d\"} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithVerbatimEscapeSequencesInsideVerbatimInterpolatedString() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithVerbatimEscapeSequencesInsideVerbatimInterpolatedString() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $@"prefix {someValue{|Unnecessary:[||].ToString(@"|}\d ""d""{|Unnecessary:")|}} suffix"; - } + _ = $@"prefix {someValue{|Unnecessary:[||].ToString(@"|}\d ""d""{|Unnecessary:")|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $@"prefix {someValue:\d ""d""} suffix"; - } + _ = $@"prefix {someValue:\d ""d""} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithVerbatimEscapeSequencesInsideNonVerbatimInterpolatedString() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithVerbatimEscapeSequencesInsideNonVerbatimInterpolatedString() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString(@"|}\d ""d""{|Unnecessary:")|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString(@"|}\d ""d""{|Unnecessary:")|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue:\\d \"d\"} suffix"; - } + _ = $"prefix {someValue:\\d \"d\"} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithNonVerbatimEscapeSequencesInsideVerbatimInterpolatedString() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithNonVerbatimEscapeSequencesInsideVerbatimInterpolatedString() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $@"prefix {someValue{|Unnecessary:[||].ToString("|}\\d \"d\"{|Unnecessary:")|}} suffix"; - } + _ = $@"prefix {someValue{|Unnecessary:[||].ToString("|}\\d \"d\"{|Unnecessary:")|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $@"prefix {someValue:\d ""d""} suffix"; - } + _ = $@"prefix {someValue:\d ""d""} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithStringConstantParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithStringConstantParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - const string someConst = "some format code"; - _ = $"prefix {someValue[||].ToString(someConst)} suffix"; - } + const string someConst = "some format code"; + _ = $"prefix {someValue[||].ToString(someConst)} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithCharacterLiteralParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithCharacterLiteralParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(C someValue) { - void M(C someValue) - { - _ = $"prefix {someValue[||].ToString('f')} suffix"; - } - - public string ToString(object obj) => null; + _ = $"prefix {someValue[||].ToString('f')} suffix"; } - """); - } - [Fact] - public async Task ToStringWithFormatProvider() - { - // (If someone is explicitly specifying culture, an implicit form should not be encouraged.) + public string ToString(object obj) => null; + } + """); + } + + [Fact] + public async Task ToStringWithFormatProvider() + { + // (If someone is explicitly specifying culture, an implicit form should not be encouraged.) - await TestMissingInRegularAndScriptAsync( - """ - class C + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue[||].ToString("some format code", System.Globalization.CultureInfo.CurrentCulture)} suffix"; - } + _ = $"prefix {someValue[||].ToString("some format code", System.Globalization.CultureInfo.CurrentCulture)} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithInvariantCultureInsideFormattableStringInvariant() - { - // Invariance remains explicit, so this is okay. + [Fact] + public async Task ToStringWithInvariantCultureInsideFormattableStringInvariant() + { + // Invariance remains explicit, so this is okay. - await TestInRegularAndScript1Async( - """ - class C + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString(System.Globalization.CultureInfo.InvariantCulture)|}} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString(System.Globalization.CultureInfo.InvariantCulture)|}} suffix"); } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue} suffix"); } - """); - } + } + """); + } - [Fact] - public async Task DateTimeFormatInfoInvariantInfoIsRecognized() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task DateTimeFormatInfoInvariantInfoIsRecognized() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo)|}} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo)|}} suffix"); } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue} suffix"); } - """); - } + } + """); + } - [Fact] - public async Task NumberFormatInfoInvariantInfoIsRecognized() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task NumberFormatInfoInvariantInfoIsRecognized() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int someValue) { - void M(int someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)|}} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)|}} suffix"); } - """, - """ - class C + } + """, + """ + class C + { + void M(int someValue) { - void M(int someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue} suffix"); } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithInvariantCultureOutsideFormattableStringInvariant() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithInvariantCultureOutsideFormattableStringInvariant() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue[||].ToString(System.Globalization.CultureInfo.InvariantCulture)} suffix"; - } + _ = $"prefix {someValue[||].ToString(System.Globalization.CultureInfo.InvariantCulture)} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithFormatAndInvariantCultureInsideFormattableStringInvariant() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithFormatAndInvariantCultureInsideFormattableStringInvariant() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString("|}some format code{|Unnecessary:", System.Globalization.CultureInfo.InvariantCulture)|}} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue[||]{|Unnecessary:.ToString("|}some format code{|Unnecessary:", System.Globalization.CultureInfo.InvariantCulture)|}} suffix"); } - """, - """ - class C + } + """, + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = System.FormattableString.Invariant($"prefix {someValue:some format code} suffix"); - } + _ = System.FormattableString.Invariant($"prefix {someValue:some format code} suffix"); } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithFormatAndInvariantCultureOutsideFormattableStringInvariant() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithFormatAndInvariantCultureOutsideFormattableStringInvariant() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(System.DateTime someValue) { - void M(System.DateTime someValue) - { - _ = $"prefix {someValue[||].ToString("some format code", System.Globalization.CultureInfo.InvariantCulture)} suffix"; - } + _ = $"prefix {someValue[||].ToString("some format code", System.Globalization.CultureInfo.InvariantCulture)} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftWithIntegerLiteral() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadLeftWithIntegerLiteral() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].PadLeft(|}3{|Unnecessary:)|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].PadLeft(|}3{|Unnecessary:)|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,3} suffix"; - } + _ = $"prefix {someValue,3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWithIntegerLiteral() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadRightWithIntegerLiteral() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].PadRight(|}3{|Unnecessary:)|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].PadRight(|}3{|Unnecessary:)|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,-3} suffix"; - } + _ = $"prefix {someValue,-3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftWithComplexConstantExpression() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(string someValue) - { - const int someConstant = 1; - _ = $"prefix {someValue{|Unnecessary:[||].PadLeft(|}(byte)3.3 + someConstant{|Unnecessary:)|}} suffix"; - } - } - """, - """ - class C - { - void M(string someValue) - { - const int someConstant = 1; - _ = $"prefix {someValue,(byte)3.3 + someConstant} suffix"; - } - } - """); - } + [Fact] + public async Task PadLeftWithComplexConstantExpression() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) + { + const int someConstant = 1; + _ = $"prefix {someValue{|Unnecessary:[||].PadLeft(|}(byte)3.3 + someConstant{|Unnecessary:)|}} suffix"; + } + } + """, + """ + class C + { + void M(string someValue) + { + const int someConstant = 1; + _ = $"prefix {someValue,(byte)3.3 + someConstant} suffix"; + } + } + """); + } - [Fact] - public async Task PadLeftWithSpaceChar() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadLeftWithSpaceChar() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].PadLeft(|}3{|Unnecessary:, ' ')|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].PadLeft(|}3{|Unnecessary:, ' ')|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,3} suffix"; - } + _ = $"prefix {someValue,3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWithSpaceChar() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadRightWithSpaceChar() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].PadRight(|}3{|Unnecessary:, ' ')|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].PadRight(|}3{|Unnecessary:, ' ')|}} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,-3} suffix"; - } + _ = $"prefix {someValue,-3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftWithNonSpaceChar() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task PadLeftWithNonSpaceChar() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadLeft(3, '\t')} suffix"; - } + _ = $"prefix {someValue[||].PadLeft(3, '\t')} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWithNonSpaceChar() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task PadRightWithNonSpaceChar() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadRight(3, '\t')} suffix"; - } + _ = $"prefix {someValue[||].PadRight(3, '\t')} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWithComplexConstantExpressionRequiringParentheses() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(string someValue) - { - const int someConstant = 1; - _ = $"prefix {someValue{|Unnecessary:[||].PadRight(|}(byte)3.3 + someConstant{|Unnecessary:)|}} suffix"; - } - } - """, - """ - class C - { - void M(string someValue) - { - const int someConstant = 1; - _ = $"prefix {someValue,-((byte)3.3 + someConstant)} suffix"; - } - } - """); - } + [Fact] + public async Task PadRightWithComplexConstantExpressionRequiringParentheses() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) + { + const int someConstant = 1; + _ = $"prefix {someValue{|Unnecessary:[||].PadRight(|}(byte)3.3 + someConstant{|Unnecessary:)|}} suffix"; + } + } + """, + """ + class C + { + void M(string someValue) + { + const int someConstant = 1; + _ = $"prefix {someValue,-((byte)3.3 + someConstant)} suffix"; + } + } + """); + } - [Fact] - public async Task ToStringWithNoParameterWhenFormattingComponentIsSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithNoParameterWhenFormattingComponentIsSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].ToString():goo} suffix"; - } + _ = $"prefix {someValue[||].ToString():goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithStringLiteralParameterWhenFormattingComponentIsSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithStringLiteralParameterWhenFormattingComponentIsSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].ToString("bar"):goo} suffix"; - } + _ = $"prefix {someValue[||].ToString("bar"):goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithNoParameterWhenAlignmentComponentIsSpecified() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithNoParameterWhenAlignmentComponentIsSpecified() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString()|},3} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString()|},3} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,3} suffix"; - } + _ = $"prefix {someValue,3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithNoParameterWhenBothComponentsAreSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithNoParameterWhenBothComponentsAreSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].ToString(),3:goo} suffix"; - } + _ = $"prefix {someValue[||].ToString(),3:goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithStringLiteralParameterWhenBothComponentsAreSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task ToStringWithStringLiteralParameterWhenBothComponentsAreSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].ToString("some format code"),3:goo} suffix"; - } + _ = $"prefix {someValue[||].ToString("some format code"),3:goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftWhenFormattingComponentIsSpecified() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadLeftWhenFormattingComponentIsSpecified() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadLeft(3):goo} suffix"; - } + _ = $"prefix {someValue[||].PadLeft(3):goo} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,3:goo} suffix"; - } + _ = $"prefix {someValue,3:goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWhenFormattingComponentIsSpecified() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadRightWhenFormattingComponentIsSpecified() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadRight(3):goo} suffix"; - } + _ = $"prefix {someValue[||].PadRight(3):goo} suffix"; } - """, - """ - class C + } + """, + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,-3:goo} suffix"; - } + _ = $"prefix {someValue,-3:goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftWhenAlignmentComponentIsSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task PadLeftWhenAlignmentComponentIsSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadLeft(3),3} suffix"; - } + _ = $"prefix {someValue[||].PadLeft(3),3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWhenAlignmentComponentIsSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task PadRightWhenAlignmentComponentIsSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadRight(3),3} suffix"; - } + _ = $"prefix {someValue[||].PadRight(3),3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftWhenBothComponentsAreSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task PadLeftWhenBothComponentsAreSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadLeft(3),3:goo} suffix"; - } + _ = $"prefix {someValue[||].PadLeft(3),3:goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadRightWhenBothComponentsAreSpecified() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task PadRightWhenBothComponentsAreSpecified() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue[||].PadRight(3),3:goo} suffix"; - } + _ = $"prefix {someValue[||].PadRight(3),3:goo} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task ToStringWithoutFormatThenPadLeft() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task ToStringWithoutFormatThenPadLeft() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}{|Unnecessary:.PadLeft(|}3{|Unnecessary:)|}} suffix"; - } + _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}{|Unnecessary:.PadLeft(|}3{|Unnecessary:)|}} suffix"; } - """, """ - class C + } + """, """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue,3} suffix"; - } + _ = $"prefix {someValue,3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftThenToStringWithoutFormat() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadLeftThenToStringWithoutFormat() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3){|Unnecessary:[||].ToString()|}} suffix"; - } + _ = $"prefix {someValue.PadLeft(3){|Unnecessary:[||].ToString()|}} suffix"; } - """, """ - class C + } + """, """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3)} suffix"; - } + _ = $"prefix {someValue.PadLeft(3)} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftThenToStringWithoutFormatWhenAlignmentComponentIsSpecified() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadLeftThenToStringWithoutFormatWhenAlignmentComponentIsSpecified() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3){|Unnecessary:[||].ToString()|},3} suffix"; - } + _ = $"prefix {someValue.PadLeft(3){|Unnecessary:[||].ToString()|},3} suffix"; } - """, """ - class C + } + """, """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3),3} suffix"; - } + _ = $"prefix {someValue.PadLeft(3),3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftThenPadRight_WithoutAlignment() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task PadLeftThenPadRight_WithoutAlignment() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3){|Unnecessary:[||].PadRight(|}3{|Unnecessary:)|}} suffix"; - } + _ = $"prefix {someValue.PadLeft(3){|Unnecessary:[||].PadRight(|}3{|Unnecessary:)|}} suffix"; } - """, """ - class C + } + """, """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3),-3} suffix"; - } + _ = $"prefix {someValue.PadLeft(3),-3} suffix"; } - """); - } + } + """); + } - [Fact] - public async Task PadLeftThenPadRight_WithAlignment() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task PadLeftThenPadRight_WithAlignment() + { + await TestMissingAsync( + """ + class C + { + void M(string someValue) { - void M(string someValue) - { - _ = $"prefix {someValue.PadLeft(3)[||].PadRight(3),3} suffix"; - } + _ = $"prefix {someValue.PadLeft(3)[||].PadRight(3),3} suffix"; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] - public async Task MissingOnImplicitToStringReceiver() - { - await TestMissingAsync( - """ - class C - { - override string ToString() => "Goobar"; + } + """); + } - string GetViaInterpolation() => $"Hello {ToString[||]()}"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] + public async Task MissingOnImplicitToStringReceiver() + { + await TestMissingAsync( + """ + class C + { + override string ToString() => "Goobar"; + + string GetViaInterpolation() => $"Hello {ToString[||]()}"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] - public async Task MissingOnImplicitToStringReceiverWithArg() - { - await TestMissingAsync( - """ - class C - { - string ToString(string arg) => "Goobar"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] + public async Task MissingOnImplicitToStringReceiverWithArg() + { + await TestMissingAsync( + """ + class C + { + string ToString(string arg) => "Goobar"; + + string GetViaInterpolation() => $"Hello {ToString[||]("g")}"; + } + """); + } - string GetViaInterpolation() => $"Hello {ToString[||]("g")}"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] + public async Task MissingOnStaticToStringReceiver() + { + await TestMissingAsync( + """ + class C + { + public static string ToString() => "Goobar"; + + string GetViaInterpolation() => $"Hello {ToString[||]()}"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] - public async Task MissingOnStaticToStringReceiver() - { - await TestMissingAsync( - """ - class C - { - public static string ToString() => "Goobar"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] + public async Task MissingOnStaticToStringReceiverWithArg() + { + await TestMissingAsync( + """ + class C + { + public static string ToString(string arg) => "Goobar"; + + string GetViaInterpolation() => $"Hello {ToString[||]("g")}"; + } + """); + } - string GetViaInterpolation() => $"Hello {ToString[||]()}"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] + public async Task MissingOnImplicitPadLeft() + { + await TestMissingAsync( + """ + class C + { + public string PadLeft(int val) => ""; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] - public async Task MissingOnStaticToStringReceiverWithArg() - { - await TestMissingAsync( - """ - class C + void M(string someValue) { - public static string ToString(string arg) => "Goobar"; - - string GetViaInterpolation() => $"Hello {ToString[||]("g")}"; + _ = $"prefix {[||]PadLeft(3)} suffix"; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] - public async Task MissingOnImplicitPadLeft() - { - await TestMissingAsync( - """ - class C - { - public string PadLeft(int val) => ""; + } + """); + } - void M(string someValue) - { - _ = $"prefix {[||]PadLeft(3)} suffix"; - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] + public async Task MissingOnStaticPadLeft() + { + await TestMissingAsync( + """ + class C + { + public static string PadLeft(int val) => ""; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41381")] - public async Task MissingOnStaticPadLeft() - { - await TestMissingAsync( - """ - class C + void M(string someValue) { - public static string PadLeft(int val) => ""; - - void M(string someValue) - { - _ = $"prefix {[||]PadLeft(3)} suffix"; - } + _ = $"prefix {[||]PadLeft(3)} suffix"; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42247")] - public async Task OnConstantAlignment1() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Linq; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42247")] + public async Task OnConstantAlignment1() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Linq; - public static class Sample + public static class Sample + { + public static void PrintRightAligned ( String[] strings ) { - public static void PrintRightAligned ( String[] strings ) - { - const int maxLength = 1; - - for ( var i = 0; i < strings.Length; i++ ) - { - var str = strings[i]; - Console.WriteLine ($"{i}.{str[||].PadRight(maxLength, ' ')}"); - } - } - } - """, + const int maxLength = 1; - """ - using System; - using System.Linq; - - public static class Sample - { - public static void PrintRightAligned ( String[] strings ) + for ( var i = 0; i < strings.Length; i++ ) { - const int maxLength = 1; - - for ( var i = 0; i < strings.Length; i++ ) - { - var str = strings[i]; - Console.WriteLine ($"{i}.{str,-maxLength}"); - } + var str = strings[i]; + Console.WriteLine ($"{i}.{str[||].PadRight(maxLength, ' ')}"); } } - """); - } + } + """, - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42247")] - public async Task MissingOnNonConstantAlignment() - { - await TestMissingAsync( - """ - using System; - using System.Linq; + """ + using System; + using System.Linq; - public static class Sample + public static class Sample + { + public static void PrintRightAligned ( String[] strings ) { - public static void PrintRightAligned ( String[] strings ) - { - var maxLength = strings.Max(str => str.Length); + const int maxLength = 1; - for ( var i = 0; i < strings.Length; i++ ) - { - var str = strings[i]; - Console.WriteLine ($"{i}.{str[||].PadRight(maxLength, ' ')}"); - } + for ( var i = 0; i < strings.Length; i++ ) + { + var str = strings[i]; + Console.WriteLine ($"{i}.{str,-maxLength}"); } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] - public async Task MissingOnBaseToString() - { - await TestMissingAsync( - """ - class C - { - public override string ToString() => $"Test: {base[||].ToString()}"; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] - public async Task MissingOnBaseToStringEvenWhenNotOverridden() - { - await TestMissingAsync( - """ - class C - { - string M() => $"Test: {base[||].ToString()}"; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] - public async Task MissingOnBaseToStringWithArgument() - { - await TestMissingAsync( - """ - class Base - { - public string ToString(string format) => format; - } - - class Derived : Base - { - public override string ToString() => $"Test: {base[||].ToString("a")}"; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] - public async Task PadLeftSimplificationIsStillOfferedOnBaseToString() - { - await TestInRegularAndScript1Async( - """ - class C - { - public override string ToString() => $"Test: {base.ToString()[||].PadLeft(10)}"; - } - """, - """ - class C - { - public override string ToString() => $"Test: {base.ToString(),10}"; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] - public async Task FormatComponentSimplificationIsNotOfferedOnNonIFormattableType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - string M(TypeNotImplementingIFormattable value) => $"Test: {value[||].ToString("a")}"; - } - - struct TypeNotImplementingIFormattable - { - public string ToString(string format) => "A"; - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] - public async Task FormatComponentSimplificationIsOfferedOnIFormattableType() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C - { - string M(TypeImplementingIFormattable value) => $"Test: {value[||].ToString("a")}"; - } - - struct TypeImplementingIFormattable : IFormattable - { - public string ToString(string format) => "A"; - - string IFormattable.ToString(string format, IFormatProvider formatProvider) => "B"; - } - """, - """ - using System; + } + """); + } - class C - { - string M(TypeImplementingIFormattable value) => $"Test: {value:a}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42247")] + public async Task MissingOnNonConstantAlignment() + { + await TestMissingAsync( + """ + using System; + using System.Linq; - struct TypeImplementingIFormattable : IFormattable + public static class Sample + { + public static void PrintRightAligned ( String[] strings ) { - public string ToString(string format) => "A"; + var maxLength = strings.Max(str => str.Length); - string IFormattable.ToString(string format, IFormatProvider formatProvider) => "B"; + for ( var i = 0; i < strings.Length; i++ ) + { + var str = strings[i]; + Console.WriteLine ($"{i}.{str[||].PadRight(maxLength, ' ')}"); + } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] - public async Task ParameterlessToStringSimplificationIsStillOfferedOnNonIFormattableType() - { - await TestInRegularAndScript1Async( - """ - class C - { - string M(TypeNotImplementingIFormattable value) => $"Test: {value[||].ToString()}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] + public async Task MissingOnBaseToString() + { + await TestMissingAsync( + """ + class C + { + public override string ToString() => $"Test: {base[||].ToString()}"; + } + """); + } - struct TypeNotImplementingIFormattable - { - public string ToString(string format) => "A"; - } - """, - """ - class C - { - string M(TypeNotImplementingIFormattable value) => $"Test: {value}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] + public async Task MissingOnBaseToStringEvenWhenNotOverridden() + { + await TestMissingAsync( + """ + class C + { + string M() => $"Test: {base[||].ToString()}"; + } + """); + } - struct TypeNotImplementingIFormattable - { - public string ToString(string format) => "A"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] + public async Task MissingOnBaseToStringWithArgument() + { + await TestMissingAsync( + """ + class Base + { + public string ToString(string format) => format; + } + + class Derived : Base + { + public override string ToString() => $"Test: {base[||].ToString("a")}"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] - public async Task PadLeftSimplificationIsStillOfferedOnNonIFormattableType() - { - await TestInRegularAndScript1Async( - """ - class C - { - string M(TypeNotImplementingIFormattable value) => $"Test: {value.ToString("a")[||].PadLeft(10)}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42669")] + public async Task PadLeftSimplificationIsStillOfferedOnBaseToString() + { + await TestInRegularAndScript1Async( + """ + class C + { + public override string ToString() => $"Test: {base.ToString()[||].PadLeft(10)}"; + } + """, + """ + class C + { + public override string ToString() => $"Test: {base.ToString(),10}"; + } + """); + } - struct TypeNotImplementingIFormattable - { - public string ToString(string format) => "A"; - } - """, - """ - class C - { - string M(TypeNotImplementingIFormattable value) => $"Test: {value.ToString("a"),10}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] + public async Task FormatComponentSimplificationIsNotOfferedOnNonIFormattableType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + string M(TypeNotImplementingIFormattable value) => $"Test: {value[||].ToString("a")}"; + } + + struct TypeNotImplementingIFormattable + { + public string ToString(string format) => "A"; + } + """); + } - struct TypeNotImplementingIFormattable - { - public string ToString(string format) => "A"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] + public async Task FormatComponentSimplificationIsOfferedOnIFormattableType() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + string M(TypeImplementingIFormattable value) => $"Test: {value[||].ToString("a")}"; + } + + struct TypeImplementingIFormattable : IFormattable + { + public string ToString(string format) => "A"; + + string IFormattable.ToString(string format, IFormatProvider formatProvider) => "B"; + } + """, + """ + using System; + + class C + { + string M(TypeImplementingIFormattable value) => $"Test: {value:a}"; + } + + struct TypeImplementingIFormattable : IFormattable + { + public string ToString(string format) => "A"; + + string IFormattable.ToString(string format, IFormatProvider formatProvider) => "B"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42936")] - public async Task ToStringSimplificationIsNotOfferedOnRefStruct() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - string M(RefStruct someValue) => $"Test: {someValue[||].ToString()}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] + public async Task ParameterlessToStringSimplificationIsStillOfferedOnNonIFormattableType() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M(TypeNotImplementingIFormattable value) => $"Test: {value[||].ToString()}"; + } + + struct TypeNotImplementingIFormattable + { + public string ToString(string format) => "A"; + } + """, + """ + class C + { + string M(TypeNotImplementingIFormattable value) => $"Test: {value}"; + } + + struct TypeNotImplementingIFormattable + { + public string ToString(string format) => "A"; + } + """); + } - ref struct RefStruct - { - public override string ToString() => "A"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42887")] + public async Task PadLeftSimplificationIsStillOfferedOnNonIFormattableType() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M(TypeNotImplementingIFormattable value) => $"Test: {value.ToString("a")[||].PadLeft(10)}"; + } + + struct TypeNotImplementingIFormattable + { + public string ToString(string format) => "A"; + } + """, + """ + class C + { + string M(TypeNotImplementingIFormattable value) => $"Test: {value.ToString("a"),10}"; + } + + struct TypeNotImplementingIFormattable + { + public string ToString(string format) => "A"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42936")] - public async Task PadLeftSimplificationIsStillOfferedOnRefStruct() - { - await TestInRegularAndScript1Async( - """ - class C - { - string M(RefStruct someValue) => $"Test: {someValue.ToString()[||].PadLeft(10)}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42936")] + public async Task ToStringSimplificationIsNotOfferedOnRefStruct() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + string M(RefStruct someValue) => $"Test: {someValue[||].ToString()}"; + } + + ref struct RefStruct + { + public override string ToString() => "A"; + } + """); + } - ref struct RefStruct - { - public override string ToString() => "A"; - } - """, - """ - class C - { - string M(RefStruct someValue) => $"Test: {someValue.ToString(),10}"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42936")] + public async Task PadLeftSimplificationIsStillOfferedOnRefStruct() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M(RefStruct someValue) => $"Test: {someValue.ToString()[||].PadLeft(10)}"; + } + + ref struct RefStruct + { + public override string ToString() => "A"; + } + """, + """ + class C + { + string M(RefStruct someValue) => $"Test: {someValue.ToString(),10}"; + } + + ref struct RefStruct + { + public override string ToString() => "A"; + } + """); + } - ref struct RefStruct - { - public override string ToString() => "A"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46011")] + public async Task ShadowedToString() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public new string ToString() => "Shadow"; + static string M(C c) => $"{c[||].ToString()}"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46011")] - public async Task ShadowedToString() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - public new string ToString() => "Shadow"; - static string M(C c) => $"{c[||].ToString()}"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46011")] + public async Task OverridenShadowedToString() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public new string ToString() => "Shadow"; + } + + class B : C + { + public override string ToString() => "OverrideShadow"; + static string M(C c) => $"{c[||].ToString()}"; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46011")] - public async Task OverridenShadowedToString() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - public new string ToString() => "Shadow"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46011")] + public async Task DoubleOverridenToString() + { + await TestInRegularAndScript1Async( + """ + class C + { + public override string ToString() => "Override"; + } - class B : C - { - public override string ToString() => "OverrideShadow"; - static string M(C c) => $"{c[||].ToString()}"; - } - """); - } + class B : C + { + public override string ToString() => "OverrideOverride"; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46011")] - public async Task DoubleOverridenToString() - { - await TestInRegularAndScript1Async( - """ - class C + void M(B someValue) { - public override string ToString() => "Override"; + _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}} suffix"; } + } + """, + """ + class C + { + public override string ToString() => "Override"; + } - class B : C - { - public override string ToString() => "OverrideOverride"; + class B : C + { + public override string ToString() => "OverrideOverride"; - void M(B someValue) - { - _ = $"prefix {someValue{|Unnecessary:[||].ToString()|}} suffix"; - } - } - """, - """ - class C + void M(B someValue) { - public override string ToString() => "Override"; + _ = $"prefix {someValue} suffix"; } + } + """); + } - class B : C - { - public override string ToString() => "OverrideOverride"; - - void M(B someValue) - { - _ = $"prefix {someValue} suffix"; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49647")] - public async Task ConditionalExpressionMustRemainParenthesizedWhenUsingParameterlessToString() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49647")] + public async Task ConditionalExpressionMustRemainParenthesizedWhenUsingParameterlessToString() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool cond) { - void M(bool cond) - { - _ = $"{(cond ? 1 : 2){|Unnecessary:[||].ToString()|}}"; - } + _ = $"{(cond ? 1 : 2){|Unnecessary:[||].ToString()|}}"; } - """, - """ - class C + } + """, + """ + class C + { + void M(bool cond) { - void M(bool cond) - { - _ = $"{(cond ? 1 : 2)}"; - } + _ = $"{(cond ? 1 : 2)}"; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49647")] - public async Task ConditionalExpressionMustRemainParenthesizedWhenUsingParameterizedToString() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49647")] + public async Task ConditionalExpressionMustRemainParenthesizedWhenUsingParameterizedToString() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool cond) { - void M(bool cond) - { - _ = $"{(cond ? 1 : 2){|Unnecessary:[||].ToString("|}g{|Unnecessary:")|}}"; - } + _ = $"{(cond ? 1 : 2){|Unnecessary:[||].ToString("|}g{|Unnecessary:")|}}"; } - """, - """ - class C + } + """, + """ + class C + { + void M(bool cond) { - void M(bool cond) - { - _ = $"{(cond ? 1 : 2):g}"; - } + _ = $"{(cond ? 1 : 2):g}"; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49647")] - public async Task ConditionalExpressionMustRemainParenthesizedWhenUsingPadLeft() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49647")] + public async Task ConditionalExpressionMustRemainParenthesizedWhenUsingPadLeft() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool cond) { - void M(bool cond) - { - _ = $"{(cond ? "1" : "2"){|Unnecessary:[||].PadLeft(|}3{|Unnecessary:)|}}"; - } + _ = $"{(cond ? "1" : "2"){|Unnecessary:[||].PadLeft(|}3{|Unnecessary:)|}}"; } - """, - """ - class C + } + """, + """ + class C + { + void M(bool cond) { - void M(bool cond) - { - _ = $"{(cond ? "1" : "2"),3}"; - } + _ = $"{(cond ? "1" : "2"),3}"; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs index efc2741cb4040..774562e8c2c98 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionFixAllTests.cs @@ -8,147 +8,146 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpSimplifyLinqExpressionDiagnosticAnalyzer, - CSharpSimplifyLinqExpressionCodeFixProvider>; +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpression; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpSimplifyLinqExpressionDiagnosticAnalyzer, + CSharpSimplifyLinqExpressionCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] - public partial class CSharpSimplifyLinqExpressionTests +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineDeclaration)] +public partial class CSharpSimplifyLinqExpressionTests +{ + [Fact] + public async Task FixAllInDocument() { - [Fact] - public async Task FixAllInDocument() + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - using System.Linq; - using System.Collections.Generic; + TestCode = """ + using System; + using System.Linq; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - IEnumerable test = new List { "hello", "world", "!" }; - var test1 = [|test.Where(x => x.Equals('!')).Any()|]; - var test2 = [|test.Where(x => x.Equals('!')).SingleOrDefault()|]; - var test3 = [|test.Where(x => x.Equals('!')).Last()|]; - var test4 = [|test.Where(x => x.Equals('!')).Count()|]; - var test5 = [|test.Where(x => x.Equals('!')).FirstOrDefault()|]; - } + IEnumerable test = new List { "hello", "world", "!" }; + var test1 = [|test.Where(x => x.Equals('!')).Any()|]; + var test2 = [|test.Where(x => x.Equals('!')).SingleOrDefault()|]; + var test3 = [|test.Where(x => x.Equals('!')).Last()|]; + var test4 = [|test.Where(x => x.Equals('!')).Count()|]; + var test5 = [|test.Where(x => x.Equals('!')).FirstOrDefault()|]; } - """, - FixedCode = """ - using System; - using System.Linq; - using System.Collections.Generic; + } + """, + FixedCode = """ + using System; + using System.Linq; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - IEnumerable test = new List { "hello", "world", "!" }; - var test1 = test.Any(x => x.Equals('!')); - var test2 = test.SingleOrDefault(x => x.Equals('!')); - var test3 = test.Last(x => x.Equals('!')); - var test4 = test.Count(x => x.Equals('!')); - var test5 = test.FirstOrDefault(x => x.Equals('!')); - } + IEnumerable test = new List { "hello", "world", "!" }; + var test1 = test.Any(x => x.Equals('!')); + var test2 = test.SingleOrDefault(x => x.Equals('!')); + var test3 = test.Last(x => x.Equals('!')); + var test4 = test.Count(x => x.Equals('!')); + var test5 = test.FirstOrDefault(x => x.Equals('!')); } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact] - public async Task FixAllInDocumentExplicitCall() - { + [Fact] + public async Task FixAllInDocumentExplicitCall() + { - var testCode = """ - using System; - using System.Linq; - using System.Collections.Generic; + var testCode = """ + using System; + using System.Linq; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - IEnumerable test = new List { "hello", "world", "!" }; - var test1 = [|Enumerable.Where(test, x => x.Equals("!")).Any()|]; - var test2 = [|Enumerable.Where(test, x => x.Equals("!")).SingleOrDefault()|]; - var test3 = [|Enumerable.Where(test, x => x.Equals("!")).Last()|]; - var test4 = [|Enumerable.Where(test, x => x.Equals("!")).Count()|]; - var test5 = [|Enumerable.Where(test, x => x.Equals("!")).FirstOrDefault()|]; - } + IEnumerable test = new List { "hello", "world", "!" }; + var test1 = [|Enumerable.Where(test, x => x.Equals("!")).Any()|]; + var test2 = [|Enumerable.Where(test, x => x.Equals("!")).SingleOrDefault()|]; + var test3 = [|Enumerable.Where(test, x => x.Equals("!")).Last()|]; + var test4 = [|Enumerable.Where(test, x => x.Equals("!")).Count()|]; + var test5 = [|Enumerable.Where(test, x => x.Equals("!")).FirstOrDefault()|]; } - """; - var fixedCode = """ - using System; - using System.Linq; - using System.Collections.Generic; + } + """; + var fixedCode = """ + using System; + using System.Linq; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - IEnumerable test = new List { "hello", "world", "!" }; - var test1 = Enumerable.Any(test, x => x.Equals("!")); - var test2 = Enumerable.SingleOrDefault(test, x => x.Equals("!")); - var test3 = Enumerable.Last(test, x => x.Equals("!")); - var test4 = Enumerable.Count(test, x => x.Equals("!")); - var test5 = Enumerable.FirstOrDefault(test, x => x.Equals("!")); - } + IEnumerable test = new List { "hello", "world", "!" }; + var test1 = Enumerable.Any(test, x => x.Equals("!")); + var test2 = Enumerable.SingleOrDefault(test, x => x.Equals("!")); + var test3 = Enumerable.Last(test, x => x.Equals("!")); + var test4 = Enumerable.Count(test, x => x.Equals("!")); + var test5 = Enumerable.FirstOrDefault(test, x => x.Equals("!")); } - """; - await VerifyCS.VerifyCodeFixAsync(testCode, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(testCode, fixedCode); + } - [Fact] - public async Task NestedInDocument() + [Fact] + public async Task NestedInDocument() + { + + await new VerifyCS.Test { + TestCode = """ + using System; + using System.Linq; + using System.Collections.Generic; - await new VerifyCS.Test + class C { - TestCode = """ - using System; - using System.Linq; - using System.Collections.Generic; - - class C + static void M() { - static void M() - { - var test = new List { "hello", "world", "!" }; - var test1 = [|test.Where(x => x.Equals('!')).Any()|]; - var test2 = [|test.Where(x => x.Equals('!')).SingleOrDefault()|]; - var test3 = [|test.Where(x => x.Equals('!')).Last()|]; - var test4 = test.Where(x => x.Equals('!')).Count(); - var test5 = from x in test where x.Equals('!') select x; - var test6 = [|test.Where(a => [|a.Where(s => s.Equals("hello")).FirstOrDefault()|].Equals("hello")).FirstOrDefault()|]; - } + var test = new List { "hello", "world", "!" }; + var test1 = [|test.Where(x => x.Equals('!')).Any()|]; + var test2 = [|test.Where(x => x.Equals('!')).SingleOrDefault()|]; + var test3 = [|test.Where(x => x.Equals('!')).Last()|]; + var test4 = test.Where(x => x.Equals('!')).Count(); + var test5 = from x in test where x.Equals('!') select x; + var test6 = [|test.Where(a => [|a.Where(s => s.Equals("hello")).FirstOrDefault()|].Equals("hello")).FirstOrDefault()|]; } - """, - FixedCode = """ - using System; - using System.Linq; - using System.Collections.Generic; + } + """, + FixedCode = """ + using System; + using System.Linq; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - var test = new List { "hello", "world", "!" }; - var test1 = test.Any(x => x.Equals('!')); - var test2 = test.SingleOrDefault(x => x.Equals('!')); - var test3 = test.Last(x => x.Equals('!')); - var test4 = test.Where(x => x.Equals('!')).Count(); - var test5 = from x in test where x.Equals('!') select x; - var test6 = test.FirstOrDefault(a => a.FirstOrDefault(s => s.Equals("hello")).Equals("hello")); - } + var test = new List { "hello", "world", "!" }; + var test1 = test.Any(x => x.Equals('!')); + var test2 = test.SingleOrDefault(x => x.Equals('!')); + var test3 = test.Last(x => x.Equals('!')); + var test4 = test.Where(x => x.Equals('!')).Count(); + var test5 = from x in test where x.Equals('!') select x; + var test6 = test.FirstOrDefault(a => a.FirstOrDefault(s => s.Equals("hello")).Equals("hello")); } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs index c23af353e0b94..6e5d611754ff4 100644 --- a/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/SimplifyLinqExpression/CSharpSimplifyLinqExpressionTests.cs @@ -8,522 +8,521 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpSimplifyLinqExpressionDiagnosticAnalyzer, - CSharpSimplifyLinqExpressionCodeFixProvider>; +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.SimplifyLinqExpression; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpSimplifyLinqExpressionDiagnosticAnalyzer, + CSharpSimplifyLinqExpressionCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyLinqExpression)] - public partial class CSharpSimplifyLinqExpressionTests +[Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyLinqExpression)] +public partial class CSharpSimplifyLinqExpressionTests +{ + [Theory, CombinatorialData] + public static async Task TestAllowedMethodTypes( + [CombinatorialValues( + "x => x==1", + "(x) => x==1", + "x => { return x==1; }", + "(x) => { return x==1; }")] + string lambda, + [CombinatorialValues( + "First", + "Last", + "Single", + "Any", + "Count", + "SingleOrDefault", + "FirstOrDefault", + "LastOrDefault")] + string methodName) { - [Theory, CombinatorialData] - public static async Task TestAllowedMethodTypes( - [CombinatorialValues( - "x => x==1", - "(x) => x==1", - "x => { return x==1; }", - "(x) => { return x==1; }")] - string lambda, - [CombinatorialValues( - "First", - "Last", - "Single", - "Any", - "Count", - "SingleOrDefault", - "FirstOrDefault", - "LastOrDefault")] - string methodName) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + TestCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; - class Test + class Test + { + static void Main() { - static void Main() + static IEnumerable Data() { - static IEnumerable Data() - { - yield return 1; - yield return 2; - } - - var test = [|Data().Where({{lambda}}).{{methodName}}()|]; + yield return 1; + yield return 2; } - } - """, - FixedCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; - class Test + var test = [|Data().Where({{lambda}}).{{methodName}}()|]; + } + } + """, + FixedCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + static void Main() { - static void Main() + static IEnumerable Data() { - static IEnumerable Data() - { - yield return 1; - yield return 2; - } - - var test = Data().{{methodName}}({{lambda}}); + yield return 1; + yield return 2; } + + var test = Data().{{methodName}}({{lambda}}); } - """ - }.RunAsync(); - } - - [Theory, CombinatorialData] - public static async Task TestWhereWithIndexMethodTypes( - [CombinatorialValues( - "(x, index) => x==index", - "(x, index) => { return x==index; }")] - string lambda, - [CombinatorialValues( - "First", - "Last", - "Single", - "Any", - "Count", - "SingleOrDefault", - "FirstOrDefault", - "LastOrDefault")] - string methodName) - { - var testCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + } + """ + }.RunAsync(); + } - class Test - { - static void Main() - { - static IEnumerable Data() - { - yield return 1; - yield return 2; - } + [Theory, CombinatorialData] + public static async Task TestWhereWithIndexMethodTypes( + [CombinatorialValues( + "(x, index) => x==index", + "(x, index) => { return x==index; }")] + string lambda, + [CombinatorialValues( + "First", + "Last", + "Single", + "Any", + "Count", + "SingleOrDefault", + "FirstOrDefault", + "LastOrDefault")] + string methodName) + { + var testCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; - var test = Data().Where({{lambda}}).{{methodName}}(); - } - } - """; - await VerifyCS.VerifyAnalyzerAsync(testCode); - } - - [Theory, CombinatorialData] - public async Task TestQueryComprehensionSyntax( - [CombinatorialValues( - "x => x==1", - "x => { return x==1; }")] - string lambda, - [CombinatorialValues( - "First", - "Last", - "Single", - "Any", - "Count", - "SingleOrDefault", - "FirstOrDefault", - "LastOrDefault")] - string methodName) - { - await new VerifyCS.Test + class Test { - TestCode = $$""" - using System.Linq; - - class Test + static void Main() { - static void M() + static IEnumerable Data() { - var test1 = [|(from value in Enumerable.Range(0, 10) select value).Where({{lambda}}).{{methodName}}()|]; + yield return 1; + yield return 2; } - } - """, - FixedCode = $$""" - using System.Linq; - class Test - { - static void M() - { - var test1 = (from value in Enumerable.Range(0, 10) select value).{{methodName}}({{lambda}}); - } + var test = Data().Where({{lambda}}).{{methodName}}(); } - """ - }.RunAsync(); - } - - [Theory] - [InlineData("First")] - [InlineData("Last")] - [InlineData("Single")] - [InlineData("Any")] - [InlineData("Count")] - [InlineData("SingleOrDefault")] - [InlineData("FirstOrDefault")] - [InlineData("LastOrDefault")] - public async Task TestMultiLineLambda(string methodName) + } + """; + await VerifyCS.VerifyAnalyzerAsync(testCode); + } + + [Theory, CombinatorialData] + public async Task TestQueryComprehensionSyntax( + [CombinatorialValues( + "x => x==1", + "x => { return x==1; }")] + string lambda, + [CombinatorialValues( + "First", + "Last", + "Single", + "Any", + "Count", + "SingleOrDefault", + "FirstOrDefault", + "LastOrDefault")] + string methodName) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + TestCode = $$""" + using System.Linq; - class Test + class Test + { + static void M() { - static void Main() - { - static IEnumerable Data() - { - yield return 1; - yield return 2; - } - - var test = [|Data().Where(x => - { - Console.Write(x); - return x == 1; - }).{{methodName}}()|]; - } + var test1 = [|(from value in Enumerable.Range(0, 10) select value).Where({{lambda}}).{{methodName}}()|]; } - """, - FixedCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + } + """, + FixedCode = $$""" + using System.Linq; - class Test + class Test + { + static void M() { - static void Main() - { - static IEnumerable Data() - { - yield return 1; - yield return 2; - } - - var test = Data().{{methodName}}(x => - { - Console.Write(x); - return x == 1; - }); - } + var test1 = (from value in Enumerable.Range(0, 10) select value).{{methodName}}({{lambda}}); } - """ - }.RunAsync(); - } - - [Theory] - [InlineData("First", "string")] - [InlineData("Last", "string")] - [InlineData("Single", "string")] - [InlineData("Any", "bool")] - [InlineData("Count", "int")] - [InlineData("SingleOrDefault", "string")] - [InlineData("FirstOrDefault", "string")] - [InlineData("LastOrDefault", "string")] - public async Task TestOutsideFunctionCallLambda(string methodName, string returnType) + } + """ + }.RunAsync(); + } + + [Theory] + [InlineData("First")] + [InlineData("Last")] + [InlineData("Single")] + [InlineData("Any")] + [InlineData("Count")] + [InlineData("SingleOrDefault")] + [InlineData("FirstOrDefault")] + [InlineData("LastOrDefault")] + public async Task TestMultiLineLambda(string methodName) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + TestCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; - class Test + class Test + { + static void Main() { - public static bool FooTest(string input) + static IEnumerable Data() { - return true; + yield return 1; + yield return 2; } - static IEnumerable test = new List { "hello", "world", "!" }; - {{returnType}} result = [|test.Where(x => FooTest(x)).{{methodName}}()|]; + var test = [|Data().Where(x => + { + Console.Write(x); + return x == 1; + }).{{methodName}}()|]; } - """, - FixedCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; - - class Test + } + """, + FixedCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + static void Main() { - public static bool FooTest(string input) + static IEnumerable Data() { - return true; + yield return 1; + yield return 2; } - static IEnumerable test = new List { "hello", "world", "!" }; - {{returnType}} result = test.{{methodName}}(x => FooTest(x)); + var test = Data().{{methodName}}(x => + { + Console.Write(x); + return x == 1; + }); } - """ - }.RunAsync(); - } - - [Theory] - [InlineData("First")] - [InlineData("Last")] - [InlineData("Single")] - [InlineData("Any")] - [InlineData("Count")] - [InlineData("SingleOrDefault")] - [InlineData("FirstOrDefault")] - [InlineData("LastOrDefault")] - public async Task TestQueryableIsNotConsidered(string methodName) + } + """ + }.RunAsync(); + } + + [Theory] + [InlineData("First", "string")] + [InlineData("Last", "string")] + [InlineData("Single", "string")] + [InlineData("Any", "bool")] + [InlineData("Count", "int")] + [InlineData("SingleOrDefault", "string")] + [InlineData("FirstOrDefault", "string")] + [InlineData("LastOrDefault", "string")] + public async Task TestOutsideFunctionCallLambda(string methodName, string returnType) + { + await new VerifyCS.Test { - var source = $$""" - using System; - using System.Linq; - using System.Collections.Generic; - namespace demo + TestCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + public static bool FooTest(string input) { - class Test - { - void M() - { - List testvar1 = new List { 1, 2, 3, 4, 5, 6, 7, 8 }; - IQueryable testvar2 = testvar1.AsQueryable().Where(x => x % 2 == 0); - var output = testvar2.Where(x => x == 4).{{methodName}}(); - } - } + return true; } - """; - await VerifyCS.VerifyAnalyzerAsync(source); - } - - [Theory, CombinatorialData] - public async Task TestNestedLambda( - [CombinatorialValues( - "First", - "Last", - "Single", - "Any", - "Count", - "SingleOrDefault", - "FirstOrDefault", - "LastOrDefault")] - string firstMethod, - [CombinatorialValues( - "First", - "Last", - "Single", - "Any", - "Count", - "SingleOrDefault", - "FirstOrDefault", - "LastOrDefault")] - string secondMethod) - { - var testCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; - class Test + static IEnumerable test = new List { "hello", "world", "!" }; + {{returnType}} result = [|test.Where(x => FooTest(x)).{{methodName}}()|]; + } + """, + FixedCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + public static bool FooTest(string input) { - void M() - { - IEnumerable test = new List { "hello", "world", "!" }; - var test5 = [|test.Where(a => [|a.Where(s => s.Equals("hello")).{{secondMethod}}()|].Equals("hello")).{{firstMethod}}()|]; - } + return true; } - """; - var fixedCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + static IEnumerable test = new List { "hello", "world", "!" }; + {{returnType}} result = test.{{methodName}}(x => FooTest(x)); + } + """ + }.RunAsync(); + } + + [Theory] + [InlineData("First")] + [InlineData("Last")] + [InlineData("Single")] + [InlineData("Any")] + [InlineData("Count")] + [InlineData("SingleOrDefault")] + [InlineData("FirstOrDefault")] + [InlineData("LastOrDefault")] + public async Task TestQueryableIsNotConsidered(string methodName) + { + var source = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + namespace demo + { class Test { void M() { - IEnumerable test = new List { "hello", "world", "!" }; - var test5 = test.{{firstMethod}}(a => a.{{secondMethod}}(s => s.Equals("hello")).Equals("hello")); + List testvar1 = new List { 1, 2, 3, 4, 5, 6, 7, 8 }; + IQueryable testvar2 = testvar1.AsQueryable().Where(x => x % 2 == 0); + var output = testvar2.Where(x => x == 4).{{methodName}}(); } } - """; - await VerifyCS.VerifyCodeFixAsync( - testCode, - fixedCode); - } - - [Theory] - [InlineData("First")] - [InlineData("Last")] - [InlineData("Single")] - [InlineData("Any")] - [InlineData("Count")] - [InlineData("SingleOrDefault")] - [InlineData("FirstOrDefault")] - [InlineData("LastOrDefault")] - public async Task TestExplicitEnumerableCall(string methodName) - { - await new VerifyCS.Test - { - TestCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; - using System.Linq.Expressions; + } + """; + await VerifyCS.VerifyAnalyzerAsync(source); + } - class Test + [Theory, CombinatorialData] + public async Task TestNestedLambda( + [CombinatorialValues( + "First", + "Last", + "Single", + "Any", + "Count", + "SingleOrDefault", + "FirstOrDefault", + "LastOrDefault")] + string firstMethod, + [CombinatorialValues( + "First", + "Last", + "Single", + "Any", + "Count", + "SingleOrDefault", + "FirstOrDefault", + "LastOrDefault")] + string secondMethod) + { + var testCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + void M() { - static void Main() - { - IEnumerable test = new List { 1, 2, 3, 4, 5}; - [|Enumerable.Where(test, (x => x == 1)).{{methodName}}()|]; - } + IEnumerable test = new List { "hello", "world", "!" }; + var test5 = [|test.Where(a => [|a.Where(s => s.Equals("hello")).{{secondMethod}}()|].Equals("hello")).{{firstMethod}}()|]; } - """, - FixedCode = $$""" - using System; - using System.Linq; - using System.Collections.Generic; - using System.Linq.Expressions; - - class Test + } + """; + var fixedCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + void M() { - static void Main() - { - IEnumerable test = new List { 1, 2, 3, 4, 5}; - Enumerable.{{methodName}}(test, (x => x == 1)); - } + IEnumerable test = new List { "hello", "world", "!" }; + var test5 = test.{{firstMethod}}(a => a.{{secondMethod}}(s => s.Equals("hello")).Equals("hello")); } - """ - }.RunAsync(); - } + } + """; + await VerifyCS.VerifyCodeFixAsync( + testCode, + fixedCode); + } - [Fact] - public async Task TestUserDefinedWhere() + [Theory] + [InlineData("First")] + [InlineData("Last")] + [InlineData("Single")] + [InlineData("Any")] + [InlineData("Count")] + [InlineData("SingleOrDefault")] + [InlineData("FirstOrDefault")] + [InlineData("LastOrDefault")] + public async Task TestExplicitEnumerableCall(string methodName) + { + await new VerifyCS.Test { - var source = """ - using System; - using System.Linq; - using System.Collections.Generic; - namespace demo + TestCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + using System.Linq.Expressions; + + class Test + { + static void Main() + { + IEnumerable test = new List { 1, 2, 3, 4, 5}; + [|Enumerable.Where(test, (x => x == 1)).{{methodName}}()|]; + } + } + """, + FixedCode = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + using System.Linq.Expressions; + + class Test + { + static void Main() + { + IEnumerable test = new List { 1, 2, 3, 4, 5}; + Enumerable.{{methodName}}(test, (x => x == 1)); + } + } + """ + }.RunAsync(); + } + + [Fact] + public async Task TestUserDefinedWhere() + { + var source = """ + using System; + using System.Linq; + using System.Collections.Generic; + namespace demo + { + class Test { - class Test + public class TestClass4 { - public class TestClass4 + private string test; + public TestClass4() => test = "hello"; + + public TestClass4 Where(Func input) { - private string test; - public TestClass4() => test = "hello"; - - public TestClass4 Where(Func input) - { - return this; - } - - public string Single() - { - return test; - } + return this; } - static void Main() + + public string Single() { - TestClass4 Test1 = new TestClass4(); - TestClass4 test = Test1.Where(y => true); + return test; } } + static void Main() + { + TestClass4 Test1 = new TestClass4(); + TestClass4 test = Test1.Where(y => true); + } } - """; - await VerifyCS.VerifyAnalyzerAsync(source); - } - - [Theory] - [InlineData("First")] - [InlineData("Last")] - [InlineData("Single")] - [InlineData("Any")] - [InlineData("Count")] - [InlineData("SingleOrDefault")] - [InlineData("FirstOrDefault")] - [InlineData("LastOrDefault")] - public async Task TestArgumentsInSecondCall(string methodName) - { - var source = $$""" - using System; - using System.Linq; - using System.Collections.Generic; + } + """; + await VerifyCS.VerifyAnalyzerAsync(source); + } - class Test + [Theory] + [InlineData("First")] + [InlineData("Last")] + [InlineData("Single")] + [InlineData("Any")] + [InlineData("Count")] + [InlineData("SingleOrDefault")] + [InlineData("FirstOrDefault")] + [InlineData("LastOrDefault")] + public async Task TestArgumentsInSecondCall(string methodName) + { + var source = $$""" + using System; + using System.Linq; + using System.Collections.Generic; + + class Test + { + static void M() { - static void M() - { - IEnumerable test1 = new List{ "hello", "world", "!" }; - var test2 = test1.Where(x => x == "!").{{methodName}}(x => x.Length == 1); - } + IEnumerable test1 = new List{ "hello", "world", "!" }; + var test2 = test1.Where(x => x == "!").{{methodName}}(x => x.Length == 1); } - """; - await VerifyCS.VerifyAnalyzerAsync(source); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(source); + } - [Fact] - public async Task TestUnsupportedFunction() - { - var source = """ - using System; - using System.Linq; - using System.Collections.Generic; - namespace demo + [Fact] + public async Task TestUnsupportedFunction() + { + var source = """ + using System; + using System.Linq; + using System.Collections.Generic; + namespace demo + { + class Test { - class Test - { - static List test1 = new List { 3, 12, 4, 6, 20 }; - int test2 = test1.Where(x => x > 0).Count(); - } + static List test1 = new List { 3, 12, 4, 6, 20 }; + int test2 = test1.Where(x => x > 0).Count(); } - """; - await VerifyCS.VerifyAnalyzerAsync(source); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(source); + } - [Fact] - public async Task TestExpressionTreeInput() - { - var source = """ - using System; - using System.Linq; - using System.Collections.Generic; - using System.Linq.Expressions; + [Fact] + public async Task TestExpressionTreeInput() + { + var source = """ + using System; + using System.Linq; + using System.Collections.Generic; + using System.Linq.Expressions; - class Test + class Test + { + void Main() { - void Main() - { - string[] places = { "Beach", "Pool", "Store", "House", - "Car", "Salon", "Mall", "Mountain"}; + string[] places = { "Beach", "Pool", "Store", "House", + "Car", "Salon", "Mall", "Mountain"}; - IQueryable queryableData = places.AsQueryable(); - ParameterExpression pe = Expression.Parameter(typeof(string), "place"); + IQueryable queryableData = places.AsQueryable(); + ParameterExpression pe = Expression.Parameter(typeof(string), "place"); - Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes)); - Expression right = Expression.Constant("coho winery"); - Expression e1 = Expression.Equal(left, right); + Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes)); + Expression right = Expression.Constant("coho winery"); + Expression e1 = Expression.Equal(left, right); - left = Expression.Property(pe, typeof(string).GetProperty("Length")); - right = Expression.Constant(16, typeof(int)); - Expression e2 = Expression.GreaterThan(left, right); + left = Expression.Property(pe, typeof(string).GetProperty("Length")); + right = Expression.Constant(16, typeof(int)); + Expression e2 = Expression.GreaterThan(left, right); - Expression predicateBody = Expression.OrElse(e1, e2); - Expression> lambda1 = num => num < 5; + Expression predicateBody = Expression.OrElse(e1, e2); + Expression> lambda1 = num => num < 5; - string result = queryableData.Where(Expression.Lambda>(predicateBody, new ParameterExpression[] { pe })).First(); - } + string result = queryableData.Where(Expression.Lambda>(predicateBody, new ParameterExpression[] { pe })).First(); } - """; - await VerifyCS.VerifyAnalyzerAsync(source); - } + } + """; + await VerifyCS.VerifyAnalyzerAsync(source); } } diff --git a/src/Analyzers/CSharp/Tests/TransposeRecordKeyword/TransposeRecordKeywordTests.cs b/src/Analyzers/CSharp/Tests/TransposeRecordKeyword/TransposeRecordKeywordTests.cs index cb4deca3322da..cf367cd0398b0 100644 --- a/src/Analyzers/CSharp/Tests/TransposeRecordKeyword/TransposeRecordKeywordTests.cs +++ b/src/Analyzers/CSharp/Tests/TransposeRecordKeyword/TransposeRecordKeywordTests.cs @@ -9,178 +9,177 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.TransposeRecordKeyword -{ - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpTransposeRecordKeywordCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.TransposeRecordKeyword; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpTransposeRecordKeywordCodeFixProvider>; - public class TransposeRecordKeywordTests +public class TransposeRecordKeywordTests +{ + [Fact] + public async Task TestStructRecord() { - [Fact] - public async Task TestStructRecord() + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = @"struct {|CS9012:record|} C { }", - FixedCode = @"record struct C { }", - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = @"struct {|CS9012:record|} C { }", + FixedCode = @"record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestClassRecord() + [Fact] + public async Task TestClassRecord() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = @"class {|CS9012:record|} C { }", - FixedCode = @"record class C { }", - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = @"class {|CS9012:record|} C { }", + FixedCode = @"record class C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestWithModifiers() + [Fact] + public async Task TestWithModifiers() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = @"public struct {|CS9012:record|} C { }", - FixedCode = @"public record struct C { }", - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = @"public struct {|CS9012:record|} C { }", + FixedCode = @"public record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestWithComment() + [Fact] + public async Task TestWithComment() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - // my struct - public struct {|CS9012:record|} C { } - """, - FixedCode = """ - // my struct - public record struct C { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = """ + // my struct + public struct {|CS9012:record|} C { } + """, + FixedCode = """ + // my struct + public record struct C { } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestWithDocComment() + [Fact] + public async Task TestWithDocComment() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - /// - public struct {|CS9012:record|} C { } - """, - FixedCode = """ - /// - public record struct C { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = """ + /// + public struct {|CS9012:record|} C { } + """, + FixedCode = """ + /// + public record struct C { } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestWithAttributes1() + [Fact] + public async Task TestWithAttributes1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [System.CLSCompliant(false)] - struct {|CS9012:record|} C { } - """, - FixedCode = """ - [System.CLSCompliant(false)] - record struct C { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = """ + [System.CLSCompliant(false)] + struct {|CS9012:record|} C { } + """, + FixedCode = """ + [System.CLSCompliant(false)] + record struct C { } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestWithAttributes2() + [Fact] + public async Task TestWithAttributes2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - [System.CLSCompliant(false)] struct {|CS9012:record|} C { } - """, - FixedCode = """ - [System.CLSCompliant(false)] record struct C { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = """ + [System.CLSCompliant(false)] struct {|CS9012:record|} C { } + """, + FixedCode = """ + [System.CLSCompliant(false)] record struct C { } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestNestedRecord() + [Fact] + public async Task TestNestedRecord() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class {|CS9012:record|} C + { + struct {|CS9012:record|} D { } + } + """, + FixedCode = """ + record class C { - TestCode = """ - class {|CS9012:record|} C - { - struct {|CS9012:record|} D { } - } - """, - FixedCode = """ - record class C - { - record struct D { } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + record struct D { } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestNestedRecordWithComments() + [Fact] + public async Task TestNestedRecordWithComments() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + // my class + class {|CS9012:record|} C + { + // my struct + struct {|CS9012:record|} D { } + } + """, + FixedCode = """ + // my class + record class C { - TestCode = """ - // my class - class {|CS9012:record|} C - { - // my struct - struct {|CS9012:record|} D { } - } - """, - FixedCode = """ - // my class - record class C - { - // my struct - record struct D { } - } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + // my struct + record struct D { } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestTriviaBeforeAfter() + [Fact] + public async Task TestTriviaBeforeAfter() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - /*1*/ - class /**/ - /*3*/ - {|CS9012:record|} /*4*/ C { } - """, - FixedCode = """ - /*1*/ - record /**/ - /*3*/ - class /*4*/ C { } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + TestCode = """ + /*1*/ + class /**/ + /*3*/ + {|CS9012:record|} /*4*/ C { } + """, + FixedCode = """ + /*1*/ + record /**/ + /*3*/ + class /*4*/ C { } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UnsealClass/UnsealClassTests.cs b/src/Analyzers/CSharp/Tests/UnsealClass/UnsealClassTests.cs index b839de9a31967..dd46340be7b03 100644 --- a/src/Analyzers/CSharp/Tests/UnsealClass/UnsealClassTests.cs +++ b/src/Analyzers/CSharp/Tests/UnsealClass/UnsealClassTests.cs @@ -9,294 +9,293 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UnsealClass +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UnsealClass; + +using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpUnsealClassCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUnsealClass)] +public sealed class UnsealClassTests { - using VerifyCS = CSharpCodeFixVerifier< - EmptyDiagnosticAnalyzer, - CSharpUnsealClassCodeFixProvider>; + [Fact] + public async Task RemovedFromSealedClass() + { + await VerifyCS.VerifyCodeFixAsync(""" + sealed class C + { + } + class D : {|CS0509:C|} + { + } + """, """ + class C + { + } + class D : C + { + } + """); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsUnsealClass)] - public sealed class UnsealClassTests + [Fact] + public async Task RemovedFromSealedClassWithOtherModifiersPreserved() { - [Fact] - public async Task RemovedFromSealedClass() - { - await VerifyCS.VerifyCodeFixAsync(""" - sealed class C - { - } - class D : {|CS0509:C|} - { - } - """, """ - class C - { - } - class D : C - { - } - """); - } + await VerifyCS.VerifyCodeFixAsync(""" + public sealed unsafe class C + { + } + class D : {|CS0509:C|} + { + } + """, """ + public unsafe class C + { + } + class D : C + { + } + """); + } - [Fact] - public async Task RemovedFromSealedClassWithOtherModifiersPreserved() - { - await VerifyCS.VerifyCodeFixAsync(""" - public sealed unsafe class C - { - } - class D : {|CS0509:C|} - { - } - """, """ - public unsafe class C - { - } - class D : C - { - } - """); - } + [Fact] + public async Task RemovedFromSealedClassWithConstructedGeneric() + { + await VerifyCS.VerifyCodeFixAsync(""" + sealed class C + { + } + class D : {|CS0509:C|} + { + } + """, """ + class C + { + } + class D : C + { + } + """); + } - [Fact] - public async Task RemovedFromSealedClassWithConstructedGeneric() - { - await VerifyCS.VerifyCodeFixAsync(""" - sealed class C - { - } - class D : {|CS0509:C|} - { - } - """, """ - class C - { - } - class D : C - { - } - """); - } + [Fact] + public async Task NotOfferedForNonSealedClass() + { + var code = """ + class C + { + } + class D : C + { + } + """; - [Fact] - public async Task NotOfferedForNonSealedClass() - { - var code = """ - class C - { - } - class D : C - { - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task NotOfferedForStaticClass() + { + var code = """ + static class C + { + } + class {|CS0709:D|} : C + { + } + """; - [Fact] - public async Task NotOfferedForStaticClass() - { - var code = """ - static class C - { - } - class {|CS0709:D|} : C - { - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task NotOfferedForStruct() + { + var code = """ + struct S + { + } + class D : {|CS0509:S|} + { + } + """; - [Fact] - public async Task NotOfferedForStruct() - { - var code = """ - struct S - { - } - class D : {|CS0509:S|} - { - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task NotOfferedForDelegate() + { + var code = """ + delegate void F(); - [Fact] - public async Task NotOfferedForDelegate() - { - var code = """ - delegate void F(); + class D : {|CS0509:F|} + { + } + """; - class D : {|CS0509:F|} - { - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task NotOfferedForSealedClassFromMetadata1() + { + var code = """ + class D : {|CS0509:string|} + { + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task NotOfferedForSealedClassFromMetadata1() - { - var code = """ - class D : {|CS0509:string|} - { - } - """; + [Fact] + public async Task NotOfferedForSealedClassFromMetadata2() + { + var code = """ + class D : {|CS0509:System.ApplicationId|} + { + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task NotOfferedForSealedClassFromMetadata2() - { - var code = """ - class D : {|CS0509:System.ApplicationId|} - { - } - """; + [Fact] + public async Task RemovedFromAllPartialClassDeclarationsInSameFile() + { + await VerifyCS.VerifyCodeFixAsync(""" + public sealed partial class C + { + } + partial class C + { + } + sealed partial class C + { + } + class D : {|CS0509:C|} + { + } + """, """ + public partial class C + { + } + partial class C + { + } + partial class C + { + } + class D : C + { + } + """); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task RemovedFromAllPartialClassDeclarationsAcrossFiles() + { + var document1 = """ + public sealed partial class C + { + } + """; + var document2 = """ + partial class C + { + } + sealed partial class C + { + } + """; + var document3 = """ + class D : {|CS0509:C|} + { + } + """; - [Fact] - public async Task RemovedFromAllPartialClassDeclarationsInSameFile() - { - await VerifyCS.VerifyCodeFixAsync(""" - public sealed partial class C - { - } - partial class C - { - } - sealed partial class C - { - } - class D : {|CS0509:C|} - { - } - """, """ - public partial class C - { - } - partial class C - { - } - partial class C - { - } - class D : C - { - } - """); - } + var fixedDocument1 = """ + public partial class C + { + } + """; + var fixedDocument2 = """ + partial class C + { + } + partial class C + { + } + """; + var fixedDocument3 = """ + class D : C + { + } + """; - [Fact] - public async Task RemovedFromAllPartialClassDeclarationsAcrossFiles() + await new VerifyCS.Test { - var document1 = """ - public sealed partial class C - { - } - """; - var document2 = """ - partial class C - { - } - sealed partial class C - { - } - """; - var document3 = """ - class D : {|CS0509:C|} - { - } - """; + TestState = + { + Sources = { document1, document2, document3 } + }, + FixedState = + { + Sources = { fixedDocument1, fixedDocument2, fixedDocument3 } + } + }.RunAsync(); + } - var fixedDocument1 = """ - public partial class C - { - } - """; - var fixedDocument2 = """ - partial class C - { - } - partial class C - { - } - """; - var fixedDocument3 = """ - class D : C - { - } - """; + [Fact] + public async Task RemovedFromClassInVisualBasicProject() + { + var csharpDocument = """ + class D : {|CS0509:C|} + { + } + """; + var vbDocument = """ + public notinheritable class C + end class + """; - await new VerifyCS.Test + var fixedCSharpDocument = """ + class D : C { - TestState = - { - Sources = { document1, document2, document3 } - }, - FixedState = - { - Sources = { fixedDocument1, fixedDocument2, fixedDocument3 } - } - }.RunAsync(); - } + } + """; + var fixedVBDocument = """ + public class C + end class + """; - [Fact] - public async Task RemovedFromClassInVisualBasicProject() + await new VerifyCS.Test { - var csharpDocument = """ - class D : {|CS0509:C|} - { - } - """; - var vbDocument = """ - public notinheritable class C - end class - """; - - var fixedCSharpDocument = """ - class D : C - { - } - """; - var fixedVBDocument = """ - public class C - end class - """; - - await new VerifyCS.Test + TestState = { - TestState = + Sources = { csharpDocument }, + AdditionalProjectReferences = { "Project2" }, + AdditionalProjects = { - Sources = { csharpDocument }, - AdditionalProjectReferences = { "Project2" }, - AdditionalProjects = + ["Project2", LanguageNames.VisualBasic] = { - ["Project2", LanguageNames.VisualBasic] = - { - Sources = { vbDocument } - } + Sources = { vbDocument } } - }, - FixedState = + } + }, + FixedState = + { + Sources = { fixedCSharpDocument }, + AdditionalProjectReferences = { "Project2" }, + AdditionalProjects = { - Sources = { fixedCSharpDocument }, - AdditionalProjectReferences = { "Project2" }, - AdditionalProjects = + ["Project2", LanguageNames.VisualBasic] = { - ["Project2", LanguageNames.VisualBasic] = - { - Sources = { fixedVBDocument } - } + Sources = { fixedVBDocument } } } - }.RunAsync(); - } + } + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs b/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs index de5b58c0986ab..6e41212880099 100644 --- a/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs +++ b/src/Analyzers/CSharp/Tests/UpdateLegacySuppressions/UpdateLegacySuppressionsTests.cs @@ -12,77 +12,76 @@ Microsoft.CodeAnalysis.CSharp.RemoveUnnecessarySuppressions.CSharpRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer, Microsoft.CodeAnalysis.UpdateLegacySuppressions.UpdateLegacySuppressionsCodeFixProvider>; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpdateLegacySuppressions +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpdateLegacySuppressions; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUpdateLegacySuppressions)] +[WorkItem("https://github.com/dotnet/roslyn/issues/44362")] +public class UpdateLegacySuppressionsTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsUpdateLegacySuppressions)] - [WorkItem("https://github.com/dotnet/roslyn/issues/44362")] - public class UpdateLegacySuppressionsTests - { - [Theory, CombinatorialData] - public void TestStandardProperty(AnalyzerProperty property) - => VerifyCS.VerifyStandardProperty(property); + [Theory, CombinatorialData] + public void TestStandardProperty(AnalyzerProperty property) + => VerifyCS.VerifyStandardProperty(property); - // Namespace - [InlineData("namespace", "N", "~N:N")] - // Type - [InlineData("type", "N.C+D", "~T:N.C.D")] - // Field - [InlineData("member", "N.C.#F", "~F:N.C.F")] - // Property - [InlineData("member", "N.C.#P", "~P:N.C.P")] - // Method - [InlineData("member", "N.C.#M", "~M:N.C.M")] - // Generic method with parameters - [InlineData("member", "N.C.#M2(!!0)", "~M:N.C.M2``1(``0)~System.Int32")] - // Event - [InlineData("member", "e:N.C.#E", "~E:N.C.E")] - [Theory] - public async Task LegacySuppressions(string scope, string target, string fixedTarget) - { - var input = $$""" - [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "{{scope}}", Target = {|#0:"{{target}}"|})] + // Namespace + [InlineData("namespace", "N", "~N:N")] + // Type + [InlineData("type", "N.C+D", "~T:N.C.D")] + // Field + [InlineData("member", "N.C.#F", "~F:N.C.F")] + // Property + [InlineData("member", "N.C.#P", "~P:N.C.P")] + // Method + [InlineData("member", "N.C.#M", "~M:N.C.M")] + // Generic method with parameters + [InlineData("member", "N.C.#M2(!!0)", "~M:N.C.M2``1(``0)~System.Int32")] + // Event + [InlineData("member", "e:N.C.#E", "~E:N.C.E")] + [Theory] + public async Task LegacySuppressions(string scope, string target, string fixedTarget) + { + var input = $$""" + [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "{{scope}}", Target = {|#0:"{{target}}"|})] - namespace N + namespace N + { + class C { - class C - { - private int F; - public int P { get; set; } - public void M() { } - public int M2(T t) => 0; - public event System.EventHandler E; + private int F; + public int P { get; set; } + public void M() { } + public int M2(T t) => 0; + public event System.EventHandler E; - class D - { - } + class D + { } } - """; + } + """; - var expectedDiagnostic = VerifyCS.Diagnostic(AbstractRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer.LegacyFormatTargetDescriptor) - .WithLocation(0) - .WithArguments(target); + var expectedDiagnostic = VerifyCS.Diagnostic(AbstractRemoveUnnecessaryAttributeSuppressionsDiagnosticAnalyzer.LegacyFormatTargetDescriptor) + .WithLocation(0) + .WithArguments(target); - var fixedCode = $$""" - [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "{{scope}}", Target = "{{fixedTarget}}")] + var fixedCode = $$""" + [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Category", "Id: Title", Scope = "{{scope}}", Target = "{{fixedTarget}}")] - namespace N + namespace N + { + class C { - class C - { - private int F; - public int P { get; set; } - public void M() { } - public int M2(T t) => 0; - public event System.EventHandler E; + private int F; + public int P { get; set; } + public void M() { } + public int M2(T t) => 0; + public event System.EventHandler E; - class D - { - } + class D + { } } - """; - await VerifyCS.VerifyCodeFixAsync(input, expectedDiagnostic, fixedCode); - } + } + """; + await VerifyCS.VerifyCodeFixAsync(input, expectedDiagnostic, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/UpdateProjectToAllowUnsafe/UpdateProjectToAllowUnsafeTests.cs b/src/Analyzers/CSharp/Tests/UpdateProjectToAllowUnsafe/UpdateProjectToAllowUnsafeTests.cs index f833af5bc6a33..465374925290d 100644 --- a/src/Analyzers/CSharp/Tests/UpdateProjectToAllowUnsafe/UpdateProjectToAllowUnsafeTests.cs +++ b/src/Analyzers/CSharp/Tests/UpdateProjectToAllowUnsafe/UpdateProjectToAllowUnsafeTests.cs @@ -14,111 +14,110 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpdateProjectToAllowUnsafe +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpdateProjectToAllowUnsafe; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUpdateProjectToAllowUnsafe)] +public class UpdateProjectToAllowUnsafeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUpdateProjectToAllowUnsafe)] - public class UpdateProjectToAllowUnsafeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UpdateProjectToAllowUnsafeTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpUpdateProjectToAllowUnsafeCodeFixProvider()); + + private async Task TestAllowUnsafeEnabledIfDisabledAsync(string initialMarkup) { - public UpdateProjectToAllowUnsafeTests(ITestOutputHelper logger) - : base(logger) + var parameters = new TestParameters(); + using (var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters)) { + var (_, action) = await GetCodeActionsAsync(workspace, parameters); + var operations = await VerifyActionAndGetOperationsAsync(workspace, action); + + var (oldSolution, newSolution) = await ApplyOperationsAndGetSolutionAsync(workspace, operations); + Assert.True(((CSharpCompilationOptions)newSolution.Projects.Single().CompilationOptions!).AllowUnsafe); } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpUpdateProjectToAllowUnsafeCodeFixProvider()); + // no action offered if unsafe was already enabled + await TestMissingAsync(initialMarkup, new TestParameters(compilationOptions: + new CSharpCompilationOptions(outputKind: default, allowUnsafe: true))); + } - private async Task TestAllowUnsafeEnabledIfDisabledAsync(string initialMarkup) - { - var parameters = new TestParameters(); - using (var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters)) + [Fact] + public async Task OnUnsafeClass() + { + await TestAllowUnsafeEnabledIfDisabledAsync( + """ + unsafe class [|C|] // The compiler reports this on the name, not the 'unsafe' keyword. { - var (_, action) = await GetCodeActionsAsync(workspace, parameters); - var operations = await VerifyActionAndGetOperationsAsync(workspace, action); - - var (oldSolution, newSolution) = await ApplyOperationsAndGetSolutionAsync(workspace, operations); - Assert.True(((CSharpCompilationOptions)newSolution.Projects.Single().CompilationOptions!).AllowUnsafe); } + """); + } - // no action offered if unsafe was already enabled - await TestMissingAsync(initialMarkup, new TestParameters(compilationOptions: - new CSharpCompilationOptions(outputKind: default, allowUnsafe: true))); - } - - [Fact] - public async Task OnUnsafeClass() - { - await TestAllowUnsafeEnabledIfDisabledAsync( - """ - unsafe class [|C|] // The compiler reports this on the name, not the 'unsafe' keyword. + [Fact] + public async Task OnUnsafeMethod() + { + await TestAllowUnsafeEnabledIfDisabledAsync( + """ + class C + { + unsafe void [|M|]() { } - """); - } - - [Fact] - public async Task OnUnsafeMethod() - { - await TestAllowUnsafeEnabledIfDisabledAsync( - """ - class C - { - unsafe void [|M|]() - { - } - } - """); - } + } + """); + } - [Fact] - public async Task OnUnsafeLocalFunction() - { - await TestAllowUnsafeEnabledIfDisabledAsync( - """ - class C + [Fact] + public async Task OnUnsafeLocalFunction() + { + await TestAllowUnsafeEnabledIfDisabledAsync( + """ + class C + { + void M() { - void M() + unsafe void [|F|]() { - unsafe void [|F|]() - { - } } } - """); - } + } + """); + } - [Fact] - public async Task OnUnsafeBlock() - { - await TestAllowUnsafeEnabledIfDisabledAsync( - """ - class C + [Fact] + public async Task OnUnsafeBlock() + { + await TestAllowUnsafeEnabledIfDisabledAsync( + """ + class C + { + void M() { - void M() + [|unsafe|] { - [|unsafe|] - { - } } } - """); - } + } + """); + } - [Fact] - public async Task NotInsideUnsafeBlock() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task NotInsideUnsafeBlock() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + unsafe { - unsafe - { - [|int * p;|] - } + [|int * p;|] } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UpgradeProject/UpgradeProjectTests.cs b/src/Analyzers/CSharp/Tests/UpgradeProject/UpgradeProjectTests.cs index 33aa38939b9f2..26456b8caa2ce 100644 --- a/src/Analyzers/CSharp/Tests/UpgradeProject/UpgradeProjectTests.cs +++ b/src/Analyzers/CSharp/Tests/UpgradeProject/UpgradeProjectTests.cs @@ -15,1281 +15,1280 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpgradeProject +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UpgradeProject; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUpgradeProject)] +public partial class UpgradeProjectTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUpgradeProject)] - public partial class UpgradeProjectTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UpgradeProjectTests(ITestOutputHelper logger) + : base(logger) { - public UpgradeProjectTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpUpgradeProjectCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpUpgradeProjectCodeFixProvider()); - private async Task TestLanguageVersionUpgradedAsync( - string initialMarkup, - LanguageVersion expected, - ParseOptions? parseOptions, - int index = 0) + private async Task TestLanguageVersionUpgradedAsync( + string initialMarkup, + LanguageVersion expected, + ParseOptions? parseOptions, + int index = 0) + { + var parameters = new TestParameters(parseOptions: parseOptions, index: index); + using (var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters)) { - var parameters = new TestParameters(parseOptions: parseOptions, index: index); - using (var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters)) - { - var (_, action) = await GetCodeActionsAsync(workspace, parameters); - var operations = await VerifyActionAndGetOperationsAsync(workspace, action); - - var appliedChanges = await ApplyOperationsAndGetSolutionAsync(workspace, operations); - var oldSolution = appliedChanges.Item1; - var newSolution = appliedChanges.Item2; - Assert.All(newSolution.Projects.Where(p => p.Language == LanguageNames.CSharp), - p => Assert.Equal(expected, ((CSharpParseOptions)p.ParseOptions!).SpecifiedLanguageVersion)); - - // Verify no document changes when upgrade project - var changedDocs = SolutionUtilities.GetTextChangedDocuments(oldSolution, newSolution); - Assert.Empty(changedDocs); - } + var (_, action) = await GetCodeActionsAsync(workspace, parameters); + var operations = await VerifyActionAndGetOperationsAsync(workspace, action); + + var appliedChanges = await ApplyOperationsAndGetSolutionAsync(workspace, operations); + var oldSolution = appliedChanges.Item1; + var newSolution = appliedChanges.Item2; + Assert.All(newSolution.Projects.Where(p => p.Language == LanguageNames.CSharp), + p => Assert.Equal(expected, ((CSharpParseOptions)p.ParseOptions!).SpecifiedLanguageVersion)); - await TestAsync(initialMarkup, initialMarkup, parseOptions); // no change to markup + // Verify no document changes when upgrade project + var changedDocs = SolutionUtilities.GetTextChangedDocuments(oldSolution, newSolution); + Assert.Empty(changedDocs); } - private async Task TestLanguageVersionNotUpgradedAsync(string initialMarkup, ParseOptions parseOptions, int index = 0) - { - var parameters = new TestParameters(parseOptions: parseOptions, index: index); - using var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters); - var (actions, actionsToInvoke) = await GetCodeActionsAsync(workspace, parameters); + await TestAsync(initialMarkup, initialMarkup, parseOptions); // no change to markup + } - Assert.Empty(actions); - Assert.Null(actionsToInvoke); - } + private async Task TestLanguageVersionNotUpgradedAsync(string initialMarkup, ParseOptions parseOptions, int index = 0) + { + var parameters = new TestParameters(parseOptions: parseOptions, index: index); + using var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters); + var (actions, actionsToInvoke) = await GetCodeActionsAsync(workspace, parameters); - [Fact] - public async Task UpgradeProjectFromCSharp7_2ToCSharp8() - { - await TestLanguageVersionUpgradedAsync( - """ - class C - { - object F = [|null!|]; - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_2)); - } + Assert.Empty(actions); + Assert.Null(actionsToInvoke); + } - [Fact] - public async Task UpgradeProjectFromCSharp7ToCSharp8() - { - await TestLanguageVersionUpgradedAsync( - """ - class C - { - object F = [|null!|]; - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7_2ToCSharp8() + { + await TestLanguageVersionUpgradedAsync( + """ + class C + { + object F = [|null!|]; + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_2)); + } - [Fact] - public async Task UpgradeProjectFromCSharp6ToCSharp7() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program - { - void A() - { - var x = [|(1, 2)|]; - } - } - """, - LanguageVersion.CSharp7, - new CSharpParseOptions(LanguageVersion.CSharp6)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7ToCSharp8() + { + await TestLanguageVersionUpgradedAsync( + """ + class C + { + object F = [|null!|]; + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectFromCSharp5ToCSharp6() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program + [Fact] + public async Task UpgradeProjectFromCSharp6ToCSharp7() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + void A() { - void A() - { - var x = [|nameof(A)|]; - } + var x = [|(1, 2)|]; } - """, - LanguageVersion.CSharp6, - new CSharpParseOptions(LanguageVersion.CSharp5)); - } + } + """, + LanguageVersion.CSharp7, + new CSharpParseOptions(LanguageVersion.CSharp6)); + } - [Fact] - public async Task UpgradeProjectFromCSharp4ToCSharp5() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program + [Fact] + public async Task UpgradeProjectFromCSharp5ToCSharp6() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + void A() { - void A() - { - Func> f = [|async|] x => x; - } + var x = [|nameof(A)|]; } - """, - LanguageVersion.CSharp5, - new CSharpParseOptions(LanguageVersion.CSharp4)); - } + } + """, + LanguageVersion.CSharp6, + new CSharpParseOptions(LanguageVersion.CSharp5)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7ToLatest() - { - await TestLanguageVersionUpgradedAsync( - $$""" - class Program + [Fact] + public async Task UpgradeProjectFromCSharp4ToCSharp5() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + void A() { - #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] + Func> f = [|async|] x => x; } - """, - LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + } + """, + LanguageVersion.CSharp5, + new CSharpParseOptions(LanguageVersion.CSharp4)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7To7_1_TriggeredByInferredTupleNames() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program + [Fact] + public async Task UpgradeProjectFromCSharp7ToLatest() + { + await TestLanguageVersionUpgradedAsync( + $$""" + class Program + { + #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] + } + """, + LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), + new CSharpParseOptions(LanguageVersion.CSharp7)); + } + + [Fact] + public async Task UpgradeProjectFromCSharp7To7_1_TriggeredByInferredTupleNames() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + void M() { - void M() - { - int b = 2; - var t = (1, b); - System.Console.Write(t.[|b|]); - } + int b = 2; + var t = (1, b); + System.Console.Write(t.[|b|]); } + } - namespace System + namespace System + { + public struct ValueTuple { - public struct ValueTuple + public T1 Item1; + public T2 Item2; + + public ValueTuple(T1 item1, T2 item2) { - public T1 Item1; - public T2 Item2; - - public ValueTuple(T1 item1, T2 item2) - { - this.Item1 = item1; - this.Item2 = item2; - } + this.Item1 = item1; + this.Item2 = item2; } } - """, - LanguageVersion.CSharp7_1, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + } + """, + LanguageVersion.CSharp7_1, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7_1ToLatest() - { - await TestLanguageVersionUpgradedAsync( - $$""" - class Program - { - #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] - } - """, - LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), - new CSharpParseOptions(LanguageVersion.CSharp7_1)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7_1ToLatest() + { + await TestLanguageVersionUpgradedAsync( + $$""" + class Program + { + #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] + } + """, + LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), + new CSharpParseOptions(LanguageVersion.CSharp7_1)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7ToCSharp7_1() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program - { - #error [|version:7.1|] - } - """, - LanguageVersion.CSharp7_1, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7ToCSharp7_1() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + #error [|version:7.1|] + } + """, + LanguageVersion.CSharp7_1, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectWithNonTrailingNamedArgumentToCSharp7_2() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program + [Fact] + public async Task UpgradeProjectWithNonTrailingNamedArgumentToCSharp7_2() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + void M() { - void M() - { - [|M2(a: 1, 2);|] - } + [|M2(a: 1, 2);|] } - """, - LanguageVersion.CSharp7_2, - new CSharpParseOptions(LanguageVersion.CSharp7_1)); - } + } + """, + LanguageVersion.CSharp7_2, + new CSharpParseOptions(LanguageVersion.CSharp7_1)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7ToCSharp7_1_B() - { - await TestLanguageVersionUpgradedAsync( - """ - public class Base { } - public class Derived : Base { } - public class Program + [Fact] + public async Task UpgradeProjectFromCSharp7ToCSharp7_1_B() + { + await TestLanguageVersionUpgradedAsync( + """ + public class Base { } + public class Derived : Base { } + public class Program + { + public static void M(T x) where T: Base { - public static void M(T x) where T: Base - { - System.Console.Write(x is [|Derived|] b0); - } + System.Console.Write(x is [|Derived|] b0); } - """, - LanguageVersion.CSharp7_1, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + } + """, + LanguageVersion.CSharp7_1, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - #region C# 7.3 - [Fact] - public async Task UpgradeProjectFromCSharp7_2ToLatest() - { - await TestLanguageVersionUpgradedAsync( - $$""" - class Program - { - #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] - } - """, - LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), - new CSharpParseOptions(LanguageVersion.CSharp7_2)); - } + #region C# 7.3 + [Fact] + public async Task UpgradeProjectFromCSharp7_2ToLatest() + { + await TestLanguageVersionUpgradedAsync( + $$""" + class Program + { + #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] + } + """, + LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), + new CSharpParseOptions(LanguageVersion.CSharp7_2)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7_2To7_3_TriggeredByAttributeOnBackingField() - { - await TestLanguageVersionUpgradedAsync( - """ - class A : System.Attribute { } - class Program - { - [|[field: A]|] - int P { get; set; } - } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7_2)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7_2To7_3_TriggeredByAttributeOnBackingField() + { + await TestLanguageVersionUpgradedAsync( + """ + class A : System.Attribute { } + class Program + { + [|[field: A]|] + int P { get; set; } + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7_2)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7_2To7_3_EnumConstraint() - { - await TestLanguageVersionUpgradedAsync( - """ - public class X where T : [|System.Enum|] - { - } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7_2)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7_2To7_3_EnumConstraint() + { + await TestLanguageVersionUpgradedAsync( + """ + public class X where T : [|System.Enum|] + { + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7_2)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7_2To7_3_DelegateConstraint() - { - await TestLanguageVersionUpgradedAsync( - """ - public class X where T : [|System.Delegate|] - { - } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7_2)); - } + [Fact] + public async Task UpgradeProjectFromCSharp7_2To7_3_DelegateConstraint() + { + await TestLanguageVersionUpgradedAsync( + """ + public class X where T : [|System.Delegate|] + { + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7_2)); + } - [Fact] - public async Task UpgradeProjectFromCSharp7_2To7_3_MulticastDelegateConstraint() - { - await TestLanguageVersionUpgradedAsync( - """ - public class X where T : [|System.MulticastDelegate|] - { - } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7_2)); - } - #endregion C# 7.3 + [Fact] + public async Task UpgradeProjectFromCSharp7_2To7_3_MulticastDelegateConstraint() + { + await TestLanguageVersionUpgradedAsync( + """ + public class X where T : [|System.MulticastDelegate|] + { + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7_2)); + } + #endregion C# 7.3 - #region C# 8.0 - [Fact(Skip = "https://github.com/dotnet/roslyn/pull/29820")] - public async Task UpgradeProjectFromCSharp7_3ToLatest() - { - await TestLanguageVersionUpgradedAsync( - $$""" - class Program - { - #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] - } - """, - LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + #region C# 8.0 + [Fact(Skip = "https://github.com/dotnet/roslyn/pull/29820")] + public async Task UpgradeProjectFromCSharp7_3ToLatest() + { + await TestLanguageVersionUpgradedAsync( + $$""" + class Program + { + #error version:[|{{LanguageVersion.Latest.MapSpecifiedToEffectiveVersion().ToDisplayString()}}|] + } + """, + LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact(Skip = "https://github.com/dotnet/roslyn/pull/29820")] - public async Task UpgradeProjectFromCSharp7_3To8_0() - { - await TestLanguageVersionUpgradedAsync( - $$""" - class Program - { - #error version:[|{{LanguageVersion.CSharp8.ToDisplayString()}}|] - } - """, - LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact(Skip = "https://github.com/dotnet/roslyn/pull/29820")] + public async Task UpgradeProjectFromCSharp7_3To8_0() + { + await TestLanguageVersionUpgradedAsync( + $$""" + class Program + { + #error version:[|{{LanguageVersion.CSharp8.ToDisplayString()}}|] + } + """, + LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(), + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectForVerbatimInterpolatedString() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program + [Fact] + public async Task UpgradeProjectForVerbatimInterpolatedString() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program + { + void A() { - void A() - { - var x = [|@$"hello"|]; - } + var x = [|@$"hello"|]; } - """, - expected: LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } - #endregion + } + """, + expected: LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } + #endregion - [Fact] - public async Task UpgradeAllProjectsToCSharp7() - { - await TestLanguageVersionUpgradedAsync( - """ - - - - class C + [Fact] + public async Task UpgradeAllProjectsToCSharp7() + { + await TestLanguageVersionUpgradedAsync( + """ + + + + class C + { + void A() { - void A() - { - var x = [|(1, 2)|]; - } + var x = [|(1, 2)|]; } - - - - - - - - - - """, - LanguageVersion.CSharp7, - parseOptions: null, - index: 1); - } + } + + + + + + + + + + """, + LanguageVersion.CSharp7, + parseOptions: null, + index: 1); + } - [Fact] - public async Task UpgradeAllProjectsToCSharp8() - { - await TestLanguageVersionUpgradedAsync( - """ - - - - class C - { - object F = [|null!|]; - } - - - - - - - - - - """, - LanguageVersion.CSharp8, - parseOptions: null, - index: 1); - } + [Fact] + public async Task UpgradeAllProjectsToCSharp8() + { + await TestLanguageVersionUpgradedAsync( + """ + + + + class C + { + object F = [|null!|]; + } + + + + + + + + + + """, + LanguageVersion.CSharp8, + parseOptions: null, + index: 1); + } - [Fact] - public async Task UpgradeAllProjectsToCSharp8_NullableReferenceType() - { - await TestLanguageVersionUpgradedAsync( - """ - - - - class C + [Fact] + public async Task UpgradeAllProjectsToCSharp8_NullableReferenceType() + { + await TestLanguageVersionUpgradedAsync( + """ + + + + class C + { + void A(string[|?|] s) { - void A(string[|?|] s) - { - } } - - - - - - - - - - - - """, - LanguageVersion.CSharp8, - parseOptions: null, - index: 1); - } + } + + + + + + + + + + + + """, + LanguageVersion.CSharp8, + parseOptions: null, + index: 1); + } - [Fact] - public async Task UpgradeAllProjectsToCSharp9() - { - await TestLanguageVersionUpgradedAsync( - """ - - - - [|System.Console.WriteLine();|] - - - - - - - - - - - - """, - LanguageVersion.CSharp9, - parseOptions: null, - index: 1); - } + [Fact] + public async Task UpgradeAllProjectsToCSharp9() + { + await TestLanguageVersionUpgradedAsync( + """ + + + + [|System.Console.WriteLine();|] + + + + + + + + + + + + """, + LanguageVersion.CSharp9, + parseOptions: null, + index: 1); + } - [Fact] - public async Task ListAllSuggestions() - { - await TestExactActionSetOfferedAsync( + [Fact] + public async Task ListAllSuggestions() + { + await TestExactActionSetOfferedAsync( - """ - - - - class C + """ + + + + class C + { + void A() { - void A() - { - var x = [|(1, 2)|]; - } + var x = [|(1, 2)|]; } - - - - - - - - """, - [ - string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "7.0"), - string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, "7.0") - ]); - } + } + + + + + + + + """, + [ + string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "7.0"), + string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, "7.0") + ]); + } - [Fact] - public async Task ListAllSuggestions_CSharp8() - { - await TestExactActionSetOfferedAsync( + [Fact] + public async Task ListAllSuggestions_CSharp8() + { + await TestExactActionSetOfferedAsync( - """ - - - - class C + """ + + + + class C + { + void A() { - void A() - { - #error version:[|8|] - } + #error version:[|8|] } - - - - - - - - """, - [ - string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "8.0"), - string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, "8.0") - ] - ); - } + } + + + + + + + + """, + [ + string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "8.0"), + string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, "8.0") + ] +); + } - [Fact] - public async Task FixAllProjectsNotOffered() - { - await TestExactActionSetOfferedAsync( + [Fact] + public async Task FixAllProjectsNotOffered() + { + await TestExactActionSetOfferedAsync( - """ - - - - class C + """ + + + + class C + { + void A() { - void A() - { - var x = [|(1, 2)|]; - } + var x = [|(1, 2)|]; } - - - - - - """, - [ - string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "7.0") - ]); - } - - [Fact] - public async Task OnlyOfferFixAllProjectsFromCSharp6ToCSharp7WhenApplicable() - { - await TestExactActionSetOfferedAsync( + } + + + + + + """, + [ + string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "7.0") + ]); + } - """ - - - - class C - { - void A() - { - var x = [|(1, 2)|]; - } - } - - - - - - - - """, - [ - string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "7.0") - ]); - } + [Fact] + public async Task OnlyOfferFixAllProjectsFromCSharp6ToCSharp7WhenApplicable() + { + await TestExactActionSetOfferedAsync( - [Fact] - public async Task OnlyOfferFixAllProjectsFromCSharp6ToDefaultWhenApplicable() - { - var defaultVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion().ToDisplayString(); - await TestExactActionSetOfferedAsync( - - $$""" - - - - class C + """ + + + + class C + { + void A() { - void A() - { - #error version:[|{{defaultVersion}}|] - } + var x = [|(1, 2)|]; } - - - - - - - - """, - [ - string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, defaultVersion), - string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, defaultVersion) + } + + + + + + + + """, + [ + string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "7.0") ]); - } + } - [Fact] - public async Task OnlyOfferFixAllProjectsToCSharp8WhenApplicable() - { - await TestExactActionSetOfferedAsync( - """ - - - - class C + [Fact] + public async Task OnlyOfferFixAllProjectsFromCSharp6ToDefaultWhenApplicable() + { + var defaultVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion().ToDisplayString(); + await TestExactActionSetOfferedAsync( + + $$""" + + + + class C + { + void A() { - object F = [|null!|]; + #error version:[|{{defaultVersion}}|] } - - - - - - - - """, - [string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "8.0")]); - } + } + + + + + + + + """, + [ + string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, defaultVersion), + string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, defaultVersion) + ]); + } - [Fact] - public async Task OnlyOfferFixAllProjectsToDefaultWhenApplicable() - { - var defaultEffectiveVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion().ToDisplayString(); - await TestExactActionSetOfferedAsync( - $$""" - - - - class C + [Fact] + public async Task OnlyOfferFixAllProjectsToCSharp8WhenApplicable() + { + await TestExactActionSetOfferedAsync( + """ + + + + class C + { + object F = [|null!|]; + } + + + + + + + + """, + [string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, "8.0")]); + } + + [Fact] + public async Task OnlyOfferFixAllProjectsToDefaultWhenApplicable() + { + var defaultEffectiveVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion().ToDisplayString(); + await TestExactActionSetOfferedAsync( + $$""" + + + + class C + { + void A() { - void A() - { - #error version:[|{{defaultEffectiveVersion}}|] - } + #error version:[|{{defaultEffectiveVersion}}|] } - - - - - - - - """, - [ - string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, defaultEffectiveVersion), - string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, defaultEffectiveVersion) - ]); - } + } + + + + + + + + """, + [ + string.Format(CSharpCodeFixesResources.Upgrade_this_project_to_csharp_language_version_0, defaultEffectiveVersion), + string.Format(CSharpCodeFixesResources.Upgrade_all_csharp_projects_to_language_version_0, defaultEffectiveVersion) + ]); + } - [Fact] - public async Task UpgradeProjectWithUnconstrainedNullableTypeParameter() - { - await TestLanguageVersionUpgradedAsync( - """ - #nullable enable - class C - { - static void F([|T?|] t) { } - } - """, - LanguageVersion.CSharp9, - new CSharpParseOptions(LanguageVersion.CSharp8)); - } + [Fact] + public async Task UpgradeProjectWithUnconstrainedNullableTypeParameter() + { + await TestLanguageVersionUpgradedAsync( + """ + #nullable enable + class C + { + static void F([|T?|] t) { } + } + """, + LanguageVersion.CSharp9, + new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Type() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test where T : [|unmanaged|] - { - } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Type() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test where T : [|unmanaged|] + { + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Type_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface unmanaged { } - class Test<T> where T : [|unmanaged|] - { - } - - - - """, - expectedActionSet: []); - } + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Type_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface unmanaged { } + class Test<T> where T : [|unmanaged|] + { + } + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Method() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test - { - public void M() where T : [|unmanaged|] { } - } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Method() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + public void M() where T : [|unmanaged|] { } + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Method_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface unmanaged { } - class Test - { - public void M<T>() where T : [|unmanaged|] { } - } - - - - """, - expectedActionSet: []); - } + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Method_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface unmanaged { } + class Test + { + public void M<T>() where T : [|unmanaged|] { } + } + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Delegate() - { - await TestLanguageVersionUpgradedAsync( - @"delegate void D() where T : [|unmanaged|];", - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Delegate() + { + await TestLanguageVersionUpgradedAsync( + @"delegate void D() where T : [|unmanaged|];", + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Delegate_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface unmanaged { } - delegate void D<T>() where T : [| unmanaged |]; - - - - """, - expectedActionSet: []); - } + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_Delegate_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface unmanaged { } + delegate void D<T>() where T : [| unmanaged |]; + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_LocalFunction() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_LocalFunction() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + public void N() { - public void N() - { - void M() where T : [|unmanaged|] { } - } + void M() where T : [|unmanaged|] { } } - """, - LanguageVersion.CSharp7_3, - new CSharpParseOptions(LanguageVersion.CSharp7)); - } + } + """, + LanguageVersion.CSharp7_3, + new CSharpParseOptions(LanguageVersion.CSharp7)); + } - [Fact] - public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_LocalFunction_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface unmanaged { } - class Test + [Fact] + public async Task UpgradeProjectWithUnmanagedConstraintTo7_3_LocalFunction_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface unmanaged { } + class Test + { + public void N() { - public void N() - { - void M<T>() where T : [|unmanaged|] { } - } + void M<T>() where T : [|unmanaged|] { } } - - - - """, - expectedActionSet: []); - } + } + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectForDefaultInterfaceImplementation_CS8703() - { - await TestLanguageVersionUpgradedAsync( - """ - public interface I1 - { - public void [|M01|](); - } - """, - expected: LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact] + public async Task UpgradeProjectForDefaultInterfaceImplementation_CS8703() + { + await TestLanguageVersionUpgradedAsync( + """ + public interface I1 + { + public void [|M01|](); + } + """, + expected: LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectForDefaultInterfaceImplementation_CS8706() - { - await TestLanguageVersionNotUpgradedAsync( - """ - - - Assembly2 - - class Test1 : [|I1|] - {} - - - - - public interface I1 + [Fact] + public async Task UpgradeProjectForDefaultInterfaceImplementation_CS8706() + { + await TestLanguageVersionNotUpgradedAsync( + """ + + + Assembly2 + + class Test1 : [|I1|] + {} + + + + + public interface I1 + { + void M1() { - void M1() - { - } } - - - - """, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + } + + + + """, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithOpenTypeMatchingConstantPattern_01() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test - { - bool M(T t) => t is [|null|]; - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact] + public async Task UpgradeProjectWithOpenTypeMatchingConstantPattern_01() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + bool M(T t) => t is [|null|]; + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithOpenTypeMatchingConstantPattern_02() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test - { - bool M(T t) => t is [|100|]; - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact] + public async Task UpgradeProjectWithOpenTypeMatchingConstantPattern_02() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + bool M(T t) => t is [|100|]; + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithOpenTypeMatchingConstantPattern_03() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test - { - bool M(T t) => t is [|"frog"|]; - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact] + public async Task UpgradeProjectWithOpenTypeMatchingConstantPattern_03() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + bool M(T t) => t is [|"frog"|]; + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_Type() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test where T : [|notnull|] - { - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_Type() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test where T : [|notnull|] + { + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_Type_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface notnull { } - class Test<T> where T : [|notnull|] - { - } - - - - """, - expectedActionSet: []); - } + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_Type_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface notnull { } + class Test<T> where T : [|notnull|] + { + } + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_Method() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test - { - public void M() where T : [|notnull|] { } - } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_Method() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + public void M() where T : [|notnull|] { } + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_Method_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface notnull { } - class Test - { - public void M<T>() where T : [|notnull|] { } - } - - - - """, - expectedActionSet: []); - } + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_Method_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface notnull { } + class Test + { + public void M<T>() where T : [|notnull|] { } + } + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_Delegate() - { - await TestLanguageVersionUpgradedAsync( + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_Delegate() + { + await TestLanguageVersionUpgradedAsync( @"delegate void D() where T : [|notnull|];", - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_Delegate_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface notnull { } - delegate void D<T>() where T : [| notnull |]; - - - - """, - expectedActionSet: []); - } + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_Delegate_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface notnull { } + delegate void D<T>() where T : [| notnull |]; + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_LocalFunction() - { - await TestLanguageVersionUpgradedAsync( - """ - class Test + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_LocalFunction() + { + await TestLanguageVersionUpgradedAsync( + """ + class Test + { + public void N() { - public void N() - { - void M() where T : [|notnull|] { } - } + void M() where T : [|notnull|] { } } - """, - LanguageVersion.CSharp8, - new CSharpParseOptions(LanguageVersion.CSharp7_3)); - } + } + """, + LanguageVersion.CSharp8, + new CSharpParseOptions(LanguageVersion.CSharp7_3)); + } - [Fact] - public async Task UpgradeProjectWithNotNullConstraintTo8_0_LocalFunction_AlreadyDefined() - { - await TestExactActionSetOfferedAsync( - """ - - - - interface notnull { } - class Test + [Fact] + public async Task UpgradeProjectWithNotNullConstraintTo8_0_LocalFunction_AlreadyDefined() + { + await TestExactActionSetOfferedAsync( + """ + + + + interface notnull { } + class Test + { + public void N() { - public void N() - { - void M<T>() where T : [|notnull|] { } - } + void M<T>() where T : [|notnull|] { } } - - - - """, - expectedActionSet: []); - } + } + + + + """, + expectedActionSet: []); + } - [Fact] - public async Task UpgradeProjectForVarianceSafetyForStaticInterfaceMembers_CS8904() - { - await TestLanguageVersionUpgradedAsync( - """ - interface I2 - { - static T1 M1([|T1|] x) => x; - } - """, - expected: LanguageVersion.CSharp9, - new CSharpParseOptions(LanguageVersion.CSharp8)); - } + [Fact] + public async Task UpgradeProjectForVarianceSafetyForStaticInterfaceMembers_CS8904() + { + await TestLanguageVersionUpgradedAsync( + """ + interface I2 + { + static T1 M1([|T1|] x) => x; + } + """, + expected: LanguageVersion.CSharp9, + new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact] - public async Task UpgradeProjectForSealedToStringInRecords_CS8912() - { - await TestLanguageVersionUpgradedAsync( - """ - - - Assembly2 - - record [|Derived|] : Base; - - - - - public record Base - { - public sealed override string ToString() => throw null; - } - - - - """, - expected: LanguageVersion.CSharp10, - new CSharpParseOptions(LanguageVersion.CSharp9)); - } + [Fact] + public async Task UpgradeProjectForSealedToStringInRecords_CS8912() + { + await TestLanguageVersionUpgradedAsync( + """ + + + Assembly2 + + record [|Derived|] : Base; + + + + + public record Base + { + public sealed override string ToString() => throw null; + } + + + + """, + expected: LanguageVersion.CSharp10, + new CSharpParseOptions(LanguageVersion.CSharp9)); + } - [Fact] - public async Task UpgradeProjectForPrimaryConstructors_Class() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program[|()|]; - """, - LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + [Fact] + public async Task UpgradeProjectForPrimaryConstructors_Class() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program[|()|]; + """, + LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); + } - [Fact] - public async Task UpgradeProjectForPrimaryConstructors_Struct() - { - await TestLanguageVersionUpgradedAsync( - """ - struct Program[|()|]; - """, - LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + [Fact] + public async Task UpgradeProjectForPrimaryConstructors_Struct() + { + await TestLanguageVersionUpgradedAsync( + """ + struct Program[|()|]; + """, + LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); + } - [Fact] - public async Task UpgradeProjectForSemicolonBody_Class() - { - await TestLanguageVersionUpgradedAsync( - """ - class Program[|;|] - """, - LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + [Fact] + public async Task UpgradeProjectForSemicolonBody_Class() + { + await TestLanguageVersionUpgradedAsync( + """ + class Program[|;|] + """, + LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); + } - [Fact] - public async Task UpgradeProjectForSemicolonBody_Struct() - { - await TestLanguageVersionUpgradedAsync( - """ - struct Program[|;|] - """, - LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + [Fact] + public async Task UpgradeProjectForSemicolonBody_Struct() + { + await TestLanguageVersionUpgradedAsync( + """ + struct Program[|;|] + """, + LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); + } - [Fact] - public async Task UpgradeProjectForSemicolonBody_Interface() - { - await TestLanguageVersionUpgradedAsync( - """ - interface Program[|;|] - """, - LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + [Fact] + public async Task UpgradeProjectForSemicolonBody_Interface() + { + await TestLanguageVersionUpgradedAsync( + """ + interface Program[|;|] + """, + LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); + } - [Fact] - public async Task UpgradeProjectForSemicolonBody_Enum() - { - await TestLanguageVersionUpgradedAsync( - """ - enum Program[|;|] - """, - LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + [Fact] + public async Task UpgradeProjectForSemicolonBody_Enum() + { + await TestLanguageVersionUpgradedAsync( + """ + enum Program[|;|] + """, + LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); + } - [Fact] - public async Task UpgradeProjectForTargetTypedNew() - { - await TestLanguageVersionUpgradedAsync(""" - class Test - { - Test t = [|new()|]; - } - """, - LanguageVersion.CSharp9, - new CSharpParseOptions(LanguageVersion.CSharp8)); - } + [Fact] + public async Task UpgradeProjectForTargetTypedNew() + { + await TestLanguageVersionUpgradedAsync(""" + class Test + { + Test t = [|new()|]; + } + """, + LanguageVersion.CSharp9, + new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact] - public async Task UpgradeProjectForGlobalUsing() - { - await TestLanguageVersionUpgradedAsync(""" - [|global using System;|] - """, - LanguageVersion.CSharp10, - new CSharpParseOptions(LanguageVersion.CSharp9)); - } + [Fact] + public async Task UpgradeProjectForGlobalUsing() + { + await TestLanguageVersionUpgradedAsync(""" + [|global using System;|] + """, + LanguageVersion.CSharp10, + new CSharpParseOptions(LanguageVersion.CSharp9)); + } - [Fact] - public async Task UpgradeProjectForImplicitImplementationOfNonPublicMembers_CS8704() - { - await TestLanguageVersionUpgradedAsync( - """ - public interface I1 - { - protected void M01(); - } + [Fact] + public async Task UpgradeProjectForImplicitImplementationOfNonPublicMembers_CS8704() + { + await TestLanguageVersionUpgradedAsync( + """ + public interface I1 + { + protected void M01(); + } - class C1 : I1 - { - public void [|M01|]() {} - } - """, - expected: LanguageVersion.CSharp10, - new CSharpParseOptions(LanguageVersion.CSharp9)); - } + class C1 : I1 + { + public void [|M01|]() {} + } + """, + expected: LanguageVersion.CSharp10, + new CSharpParseOptions(LanguageVersion.CSharp9)); + } - [Fact] - public async Task UpgradeProjectForTargetTypedConditional() - { - await TestLanguageVersionUpgradedAsync(""" - class C + [Fact] + public async Task UpgradeProjectForTargetTypedConditional() + { + await TestLanguageVersionUpgradedAsync(""" + class C + { + void M(bool b) { - void M(bool b) - { - int? i = [|b ? 1 : null|]; - } + int? i = [|b ? 1 : null|]; } - """, - expected: LanguageVersion.CSharp9, - new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, + expected: LanguageVersion.CSharp9, + new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57154")] - public async Task UpgradeProjectForNewLinesInInterpolations() - { - await TestLanguageVersionUpgradedAsync(""" - class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57154")] + public async Task UpgradeProjectForNewLinesInInterpolations() + { + await TestLanguageVersionUpgradedAsync(""" + class Test + { + void M() { - void M() - { - var v = $"x{ - 1 + 1 - [|}|]y"; - } + var v = $"x{ + 1 + 1 + [|}|]y"; } - """, - expected: LanguageVersion.CSharp11, - new CSharpParseOptions(LanguageVersion.CSharp8)); - } + } + """, + expected: LanguageVersion.CSharp11, + new CSharpParseOptions(LanguageVersion.CSharp8)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60167")] - public async Task UpgradeProjectForStructAutoDefaultError_1() - { - await TestLanguageVersionUpgradedAsync(""" - struct Test - { - public int X; - public [|Test|]() { } - } - """, - expected: LanguageVersion.CSharp11, - new CSharpParseOptions(LanguageVersion.CSharp10)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60167")] + public async Task UpgradeProjectForStructAutoDefaultError_1() + { + await TestLanguageVersionUpgradedAsync(""" + struct Test + { + public int X; + public [|Test|]() { } + } + """, + expected: LanguageVersion.CSharp11, + new CSharpParseOptions(LanguageVersion.CSharp10)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60167")] - public async Task UpgradeProjectForStructAutoDefaultError_2() - { - await TestLanguageVersionUpgradedAsync(""" - struct Test - { - public int X; - public [|Test|]() { this.ToString(); } - } - """, - expected: LanguageVersion.CSharp11, - new CSharpParseOptions(LanguageVersion.CSharp10)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60167")] + public async Task UpgradeProjectForStructAutoDefaultError_2() + { + await TestLanguageVersionUpgradedAsync(""" + struct Test + { + public int X; + public [|Test|]() { this.ToString(); } + } + """, + expected: LanguageVersion.CSharp11, + new CSharpParseOptions(LanguageVersion.CSharp10)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60167")] - public async Task UpgradeProjectForStructAutoDefaultError_3() - { - await TestLanguageVersionUpgradedAsync(""" - struct Test - { - public int X { get; set; } - public [|Test|]() { this.ToString(); } - } - """, - expected: LanguageVersion.CSharp11, - new CSharpParseOptions(LanguageVersion.CSharp10)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/60167")] + public async Task UpgradeProjectForStructAutoDefaultError_3() + { + await TestLanguageVersionUpgradedAsync(""" + struct Test + { + public int X { get; set; } + public [|Test|]() { this.ToString(); } + } + """, + expected: LanguageVersion.CSharp11, + new CSharpParseOptions(LanguageVersion.CSharp10)); + } - [Fact] - public async Task UpgradeProjectForRefInMismatch() - { - await TestLanguageVersionUpgradedAsync(""" - class C + [Fact] + public async Task UpgradeProjectForRefInMismatch() + { + await TestLanguageVersionUpgradedAsync(""" + class C + { + void M1(in int x) { } + void M2(ref int y) { - void M1(in int x) { } - void M2(ref int y) - { - M1(ref [|y|]); - } + M1(ref [|y|]); } - """, - expected: LanguageVersion.CSharp12, - new CSharpParseOptions(LanguageVersion.CSharp11)); - } + } + """, + expected: LanguageVersion.CSharp12, + new CSharpParseOptions(LanguageVersion.CSharp11)); } } diff --git a/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckTests.cs b/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckTests.cs index 10ff08095db83..82209e6409b9f 100644 --- a/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForIfNullStatementCheckTests.cs @@ -9,454 +9,453 @@ using Microsoft.CodeAnalysis.UseCoalesceExpression; using Xunit; -namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.UseCoalesceExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseCoalesceExpressionForIfNullStatementCheckDiagnosticAnalyzer, - UseCoalesceExpressionForIfNullStatementCheckCodeFixProvider>; +namespace Microsoft.CodeAnalysis.CSharp.Analyzers.UnitTests.UseCoalesceExpression; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseCoalesceExpressionForIfNullStatementCheckDiagnosticAnalyzer, + UseCoalesceExpressionForIfNullStatementCheckCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseCoalesceExpression)] - public class UseCoalesceExpressionForIfNullStatementCheckTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseCoalesceExpression)] +public class UseCoalesceExpressionForIfNullStatementCheckTests +{ + [Fact] + public async Task TestLocalDeclaration_ThrowStatement() { - [Fact] - public async Task TestLocalDeclaration_ThrowStatement() + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() - { - var item = FindItem() as C; - [|if|] (item == null) - throw new System.InvalidOperationException(); - } - - object FindItem() => null; + var item = FindItem() as C; + [|if|] (item == null) + throw new System.InvalidOperationException(); } - """, - FixedCode = """ - class C + + object FindItem() => null; + } + """, + FixedCode = """ + class C + { + void M() { - void M() - { - var item = FindItem() as C ?? throw new System.InvalidOperationException(); - } - - object FindItem() => null; + var item = FindItem() as C ?? throw new System.InvalidOperationException(); } - """ - }.RunAsync(); - } + + object FindItem() => null; + } + """ + }.RunAsync(); + } - [Fact] - public async Task TestLocalDeclaration_Block() + [Fact] + public async Task TestLocalDeclaration_Block() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() + var item = FindItem() as C; + [|if|] (item == null) { - var item = FindItem() as C; - [|if|] (item == null) - { - throw new System.InvalidOperationException(); - } + throw new System.InvalidOperationException(); } - - object FindItem() => null; } - """, - FixedCode = """ - class C + + object FindItem() => null; + } + """, + FixedCode = """ + class C + { + void M() { - void M() - { - var item = FindItem() as C ?? throw new System.InvalidOperationException(); - } - - object FindItem() => null; + var item = FindItem() as C ?? throw new System.InvalidOperationException(); } - """ - }.RunAsync(); - } + + object FindItem() => null; + } + """ + }.RunAsync(); + } - [Fact] - public async Task TestLocalDeclaration_IsPattern() + [Fact] + public async Task TestLocalDeclaration_IsPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() - { - var item = FindItem() as C; - [|if|] (item is null) - throw new System.InvalidOperationException(); - } - - object FindItem() => null; + var item = FindItem() as C; + [|if|] (item is null) + throw new System.InvalidOperationException(); } - """, - FixedCode = """ - class C + + object FindItem() => null; + } + """, + FixedCode = """ + class C + { + void M() { - void M() - { - var item = FindItem() as C ?? throw new System.InvalidOperationException(); - } - - object FindItem() => null; + var item = FindItem() as C ?? throw new System.InvalidOperationException(); } - """ - }.RunAsync(); - } + + object FindItem() => null; + } + """ + }.RunAsync(); + } - [Fact] - public async Task TestLocalDeclaration_Assignment1() + [Fact] + public async Task TestLocalDeclaration_Assignment1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() - { - var item = FindItem() as C; - [|if|] (item == null) - item = new C(); - } - - object FindItem() => null; + var item = FindItem() as C; + [|if|] (item == null) + item = new C(); } - """, - FixedCode = """ - class C + + object FindItem() => null; + } + """, + FixedCode = """ + class C + { + void M() { - void M() - { - var item = FindItem() as C ?? new C(); - } - - object FindItem() => null; + var item = FindItem() as C ?? new C(); } - """ - }.RunAsync(); - } + + object FindItem() => null; + } + """ + }.RunAsync(); + } - [Fact] - public async Task TestLocalDeclaration_Assignment2() + [Fact] + public async Task TestLocalDeclaration_Assignment2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = """ + class C { - TestCode = """ - class C + void M() { - void M() - { - var item = FindItem() as C; - [|if|] (item == null) - item = new(); - } + var item = FindItem() as C; + [|if|] (item == null) + item = new(); + } - object FindItem() => null; + object FindItem() => null; + } + """, + FixedCode = """ + class C + { + void M() + { + var item = FindItem() as C ?? new(); } - """, - FixedCode = """ - class C + + object FindItem() => null; + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestLocalDeclaration_NotWithWrongItemChecked() + { + var text = """ + class C + { + void M(C item1) { - void M() - { - var item = FindItem() as C ?? new(); - } - - object FindItem() => null; + var item = FindItem() as C; + if (item1 == null) + throw new System.InvalidOperationException(); } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - [Fact] - public async Task TestLocalDeclaration_NotWithWrongItemChecked() + object FindItem() => null; + } + """; + + await new VerifyCS.Test { - var text = """ - class C - { - void M(C item1) - { - var item = FindItem() as C; - if (item1 == null) - throw new System.InvalidOperationException(); - } + TestCode = text, + FixedCode = text, + }.RunAsync(); + } - object FindItem() => null; + [Fact] + public async Task TestLocalDeclaration_NotWithWrongCondition() + { + var text = """ + class C + { + void M() + { + var item = FindItem() as C; + if (item != null) + throw new System.InvalidOperationException(); } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithWrongCondition() + await new VerifyCS.Test { - var text = """ - class C - { - void M() - { - var item = FindItem() as C; - if (item != null) - throw new System.InvalidOperationException(); - } + TestCode = text, + FixedCode = text, + }.RunAsync(); + } - object FindItem() => null; + [Fact] + public async Task TestLocalDeclaration_NotWithWrongPattern() + { + var text = """ + class C + { + void M() + { + var item = FindItem() as C; + if (item is not null) + throw new System.InvalidOperationException(); } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithWrongPattern() + await new VerifyCS.Test { - var text = """ - class C - { - void M() - { - var item = FindItem() as C; - if (item is not null) - throw new System.InvalidOperationException(); - } + TestCode = text, + FixedCode = text, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - object FindItem() => null; + [Fact] + public async Task TestLocalDeclaration_NotWithWrongAssignment() + { + var text = """ + class C + { + void M(C item1) + { + var item = FindItem() as C; + if (item == null) + item1 = new C(); } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestLocalDeclaration_NotWithWrongAssignment() + object FindItem() => null; + } + """; + + await new VerifyCS.Test { - var text = """ - class C - { - void M(C item1) - { - var item = FindItem() as C; - if (item == null) - item1 = new C(); - } + TestCode = text, + FixedCode = text, + }.RunAsync(); + } - object FindItem() => null; + [Fact] + public async Task TestLocalDeclaration_NotWithElseBlock() + { + var text = """ + class C + { + void M(C item1) + { + var item = FindItem() as C; + if (item == null) + item = new C(); + else + item = null; } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithElseBlock() + await new VerifyCS.Test { - var text = """ - class C + TestCode = text, + FixedCode = text, + }.RunAsync(); + } + + [Fact] + public async Task TestLocalDeclaration_NotWithMultipleWhenTrueStatements() + { + var text = """ + class C + { + void M(C item1) { - void M(C item1) + var item = FindItem() as C; + if (item == null) { - var item = FindItem() as C; - if (item == null) - item = new C(); - else - item = null; + item = new C(); + item = null; } - - object FindItem() => null; } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithMultipleWhenTrueStatements() + await new VerifyCS.Test { - var text = """ - class C + TestCode = text, + FixedCode = text, + }.RunAsync(); + } + + [Fact] + public async Task TestLocalDeclaration_NotWithNoWhenTrueStatements() + { + var text = """ + class C + { + void M(C item1) { - void M(C item1) + var item = FindItem() as C; + if (item == null) { - var item = FindItem() as C; - if (item == null) - { - item = new C(); - item = null; - } } - - object FindItem() => null; } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithNoWhenTrueStatements() + await new VerifyCS.Test { - var text = """ - class C + TestCode = text, + FixedCode = text, + }.RunAsync(); + } + + [Fact] + public async Task TestLocalDeclaration_NotWithThrowWithoutExpression() + { + var text = """ + class C + { + void M() { - void M(C item1) + try + { + } + catch { var item = FindItem() as C; if (item == null) - { - } + throw; } - - object FindItem() => null; } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithThrowWithoutExpression() + await new VerifyCS.Test { - var text = """ - class C - { - void M() - { - try - { - } - catch - { - var item = FindItem() as C; - if (item == null) - throw; - } - } - - object FindItem() => null; - } - """; + TestCode = text, + FixedCode = text, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestLocalDeclaration_NotWithLocalWithoutInitializer() + { + var text = """ + class C { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } - - [Fact] - public async Task TestLocalDeclaration_NotWithLocalWithoutInitializer() - { - var text = """ - class C + void M() { - void M() - { - C item; - if ({|CS0165:item|} == null) - throw new System.InvalidOperationException(); - } - - object FindItem() => null; + C item; + if ({|CS0165:item|} == null) + throw new System.InvalidOperationException(); } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithValueTypeInitializer() + await new VerifyCS.Test { - var text = """ - class C - { - void M() - { - object item = 0; - if (item == null) - item = null; - } + TestCode = text, + FixedCode = text, + }.RunAsync(); + } - object FindItem() => null; + [Fact] + public async Task TestLocalDeclaration_NotWithValueTypeInitializer() + { + var text = """ + class C + { + void M() + { + object item = 0; + if (item == null) + item = null; } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - }.RunAsync(); - } + object FindItem() => null; + } + """; - [Fact] - public async Task TestLocalDeclaration_NotWithReferenceToVariableInThrow() + await new VerifyCS.Test { - var text = """ - class C - { - void M() - { - var item = FindItem() as C; - if (item is null) - throw new System.InvalidOperationException(nameof(item)); - } + TestCode = text, + FixedCode = text, + }.RunAsync(); + } - object FindItem() => null; + [Fact] + public async Task TestLocalDeclaration_NotWithReferenceToVariableInThrow() + { + var text = """ + class C + { + void M() + { + var item = FindItem() as C; + if (item is null) + throw new System.InvalidOperationException(nameof(item)); } - """; - await new VerifyCS.Test - { - TestCode = text, - FixedCode = text, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + object FindItem() => null; + } + """; + + await new VerifyCS.Test + { + TestCode = text, + FixedCode = text, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckTests.cs b/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckTests.cs index 6a8bc64328d97..88285c3565dc9 100644 --- a/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForNullableTernaryConditionalCheckTests.cs @@ -13,333 +13,332 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCoalesceExpression +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCoalesceExpression; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseCoalesceExpression)] +public class UseCoalesceExpressionForNullableTernaryConditionalCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseCoalesceExpression)] - public class UseCoalesceExpressionForNullableTernaryConditionalCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseCoalesceExpressionForNullableTernaryConditionalCheckTests(ITestOutputHelper logger) + : base(logger) { - public UseCoalesceExpressionForNullableTernaryConditionalCheckTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticAnalyzer(), - new UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider()); - - [Fact] - public async Task TestOnLeft_Equals() - { - await TestInRegularAndScriptAsync( - """ - using System; - - class C - { - void M(int? x, int? y) - { - var z = [||]!x.HasValue ? y : x.Value; - } - } - """, - """ - using System; + } - class C - { - void M(int? x, int? y) - { - var z = x ?? y ; - } - } - """); - } + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseCoalesceExpressionForNullableTernaryConditionalCheckDiagnosticAnalyzer(), + new UseCoalesceExpressionForNullableTernaryConditionalCheckCodeFixProvider()); - [Fact] - public async Task TestOnLeft_NotEquals() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestOnLeft_Equals() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z = [||]x.HasValue ? x.Value : y; - } + var z = [||]!x.HasValue ? y : x.Value; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z = x ?? y; - } + var z = x ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestComplexExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestOnLeft_NotEquals() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z = [||]!(x + y).HasValue ? y : (x + y).Value; - } + var z = [||]x.HasValue ? x.Value : y; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z = (x + y) ?? y ; - } + var z = x ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestParens1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestComplexExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z = [||](x.HasValue) ? x.Value : y; - } + var z = [||]!(x + y).HasValue ? y : (x + y).Value; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z = x ?? y; - } + var z = (x + y) ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestParens1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z1 = {|FixAllInDocument:x|}.HasValue ? x.Value : y; - var z2 = !x.HasValue ? y : x.Value; - } + var z = [||](x.HasValue) ? x.Value : y; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - var z1 = x ?? y; - var z2 = x ?? y ; - } + var z = x ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y) { - void M(int? x, int? y, int? z) - { - var w = {|FixAllInDocument:x|}.HasValue ? x.Value : y.ToString(z.HasValue ? z.Value : y); - } + var z1 = {|FixAllInDocument:x|}.HasValue ? x.Value : y; + var z2 = !x.HasValue ? y : x.Value; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x, int? y) { - void M(int? x, int? y, int? z) - { - var w = x ?? y.ToString(z ?? y); - } + var z1 = x ?? y; + var z2 = x ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll3() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y, int? z) + { + var w = {|FixAllInDocument:x|}.HasValue ? x.Value : y.ToString(z.HasValue ? z.Value : y); + } + } + """, + """ + using System; + + class C + { + void M(int? x, int? y, int? z) { - void M(int? x, int? y, int? z) - { - var w = {|FixAllInDocument:x|}.HasValue ? x.Value : y.HasValue ? y.Value : z; - } + var w = x ?? y.ToString(z ?? y); } - """, - """ - using System; + } + """); + } + + [Fact] + public async Task TestFixAll3() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x, int? y, int? z) { - void M(int? x, int? y, int? z) - { - var w = x ?? y ?? z; - } + var w = {|FixAllInDocument:x|}.HasValue ? x.Value : y.HasValue ? y.Value : z; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17028")] - public async Task TestInExpressionOfT() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x, int? y, int? z) { - void M(int? x, int? y) - { - Expression> e = () => [||]!x.HasValue ? y : x.Value; - } + var w = x ?? y ?? z; } - """, - """ - using System; - using System.Linq.Expressions; + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17028")] + public async Task TestInExpressionOfT() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; + + class C + { + void M(int? x, int? y) { - void M(int? x, int? y) - { - Expression> e = () => {|Warning:x ?? y|} ; - } + Expression> e = () => [||]!x.HasValue ? y : x.Value; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] - public async Task TestNotWithTargetTyping1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C + } + """, + """ + using System; + using System.Linq.Expressions; + + class C + { + void M(int? x, int? y) { - void M(int? x) - { - object z = [||]x.HasValue ? x.Value : ""; - } + Expression> e = () => {|Warning:x ?? y|}; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] - public async Task TestWithNonTargetTyping1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] + public async Task TestNotWithTargetTyping1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x) { - void M(int? x) - { - object z = [||]x.HasValue ? x.Value : 0; - } + object z = [||]x.HasValue ? x.Value : ""; } - """, - """ - using System; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] + public async Task TestWithNonTargetTyping1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(int? x) { - void M(int? x) - { - object z = x ?? 0; - } + object z = [||]x.HasValue ? x.Value : 0; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] - public async Task TestNotWithTargetTyping2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(int? x) { - public int? Index { get; set; } - - public string InterpolatedText => $"{([||]Index.HasValue ? Index.Value : "???")}: rest of the text"; + object z = x ?? 0; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] - public async Task TestWithNonTargetTyping2() - { - await TestInRegularAndScriptAsync( - """ - using System; + } + """); + } - class C - { - public int? Index { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] + public async Task TestNotWithTargetTyping2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - public string InterpolatedText => $"{([||]Index.HasValue ? Index.Value : 0)}: rest of the text"; - } - """, - """ - using System; + class C + { + public int? Index { get; set; } - class C - { - public int? Index { get; set; } + public string InterpolatedText => $"{([||]Index.HasValue ? Index.Value : "???")}: rest of the text"; + } + """); + } - public string InterpolatedText => $"{(Index ?? 0)}: rest of the text"; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69087")] + public async Task TestWithNonTargetTyping2() + { + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + public int? Index { get; set; } + + public string InterpolatedText => $"{([||]Index.HasValue ? Index.Value : 0)}: rest of the text"; + } + """, + """ + using System; + + class C + { + public int? Index { get; set; } + + public string InterpolatedText => $"{(Index ?? 0)}: rest of the text"; + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckTests.cs b/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckTests.cs index 846ff7b6ea6c4..5a1493542ca07 100644 --- a/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCoalesceExpression/UseCoalesceExpressionForTernaryConditionalCheckTests.cs @@ -13,662 +13,661 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCoalesceExpression +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCoalesceExpression; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseCoalesceExpression)] +public class UseCoalesceExpressionForTernaryConditionalCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseCoalesceExpression)] - public class UseCoalesceExpressionForTernaryConditionalCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseCoalesceExpressionForTernaryConditionalCheckTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseCoalesceExpressionForTernaryConditionalCheckDiagnosticAnalyzer(), + new UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider()); + + [Fact] + public async Task TestOnLeft_Equals() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||]x == null ? y : x; + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) + { + var z = x ?? y; + } + } + """); + } + + [Fact] + public async Task TestOnLeft_NotEquals() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||]x != null ? x : y; + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) + { + var z = x ?? y; + } + } + """); + } + + [Fact] + public async Task TestOnRight_Equals() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||]null == x ? y : x; + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) + { + var z = x ?? y; + } + } + """); + } + + [Fact] + public async Task TestOnRight_NotEquals() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||]null != x ? x : y; + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) + { + var z = x ?? y; + } + } + """); + } + + [Fact] + public async Task TestComplexExpression() { - public UseCoalesceExpressionForTernaryConditionalCheckTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseCoalesceExpressionForTernaryConditionalCheckDiagnosticAnalyzer(), - new UseCoalesceExpressionForTernaryConditionalCheckCodeFixProvider()); - - [Fact] - public async Task TestOnLeft_Equals() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||]x.ToString() == null ? y : x.ToString(); + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = [||]x == null ? y : x; - } + var z = x.ToString() ?? y; } - """, - """ - using System; - - class C - { - void M(string x, string y) - { - var z = x ?? y; - } - } - """); - } - - [Fact] - public async Task TestOnLeft_NotEquals() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + } + """); + } + + [Fact] + public async Task TestParens1() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = [||]x != null ? x : y; - } + var z = [||](x == null) ? y : x; } - """, - """ - using System; - - class C - { - void M(string x, string y) - { - var z = x ?? y; - } - } - """); - } - - [Fact] - public async Task TestOnRight_Equals() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = [||]null == x ? y : x; - } + var z = x ?? y; } - """, - """ - using System; - - class C - { - void M(string x, string y) - { - var z = x ?? y; - } - } - """); - } - - [Fact] - public async Task TestOnRight_NotEquals() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + } + """); + } + + [Fact] + public async Task TestParens2() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||](x) == null ? y : x; + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) + { + var z = x ?? y; + } + } + """); + } + + [Fact] + public async Task TestParens3() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) + { + var z = [||]x == null ? y : (x); + } + } + """, + """ + using System; + + class C + { + void M(string x, string y) + { + var z = x ?? y; + } + } + """); + } + + [Fact] + public async Task TestParens4() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = [||]null != x ? x : y; - } + var z = [||]x == null ? (y) : x; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = x ?? y; - } + var z = x ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestComplexExpression() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = [||]x.ToString() == null ? y : x.ToString(); - } + var z1 = {|FixAllInDocument:x|} == null ? y : x; + var z2 = x != null ? x : y; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string x, string y) { - void M(string x, string y) - { - var z = x.ToString() ?? y; - } + var z1 = x ?? y; + var z2 = x ?? y; } - """); - } + } + """); + } - [Fact] - public async Task TestParens1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string x, string y, string z) { - void M(string x, string y) - { - var z = [||](x == null) ? y : x; - } + var w = {|FixAllInDocument:x|} != null ? x : y.ToString(z != null ? z : y); } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string x, string y, string z) { - void M(string x, string y) - { - var z = x ?? y; - } + var w = x ?? y.ToString(z ?? y); } - """); - } + } + """); + } - [Fact] - public async Task TestParens2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll3() + { + await TestInRegularAndScript1Async( + """ + using System; - class C - { - void M(string x, string y) - { - var z = [||](x) == null ? y : x; - } + class C + { + void M(string x, string y, string z) + { + var w = {|FixAllInDocument:x|} != null ? x : y != null ? y : z; } - """, - """ - using System; - - class C - { - void M(string x, string y) - { - var z = x ?? y; - } + } + """, + """ + using System; + + class C + { + void M(string x, string y, string z) + { + var w = x ?? y ?? z; } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16025")] + public async Task TestTrivia1() + { + await TestInRegularAndScript1Async( + """ + using System; - [Fact] - public async Task TestParens3() - { - await TestInRegularAndScript1Async( - """ - using System; + class Program + { + public Program() + { + string x = "; - class C - { - void M(string x, string y) - { - var z = [||]x == null ? y : (x); - } + string y = [|x|] == null ? string.Empty : x; } - """, - """ - using System; - - class C - { - void M(string x, string y) - { - var z = x ?? y; - } + } + """, + """ + using System; + + class Program + { + public Program() + { + string x = "; + + string y = x ?? string.Empty; } - """); - } + } + """); + } - [Fact] - public async Task TestParens4() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17028")] + public async Task TestInExpressionOfT() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Linq.Expressions; - class C - { - void M(string x, string y) - { - var z = [||]x == null ? (y) : x; - } + class C + { + void Main(string s, string y) + { + Expression> e = () => [||]s != null ? s : y; + } + } + """, + """ + using System; + using System.Linq.Expressions; + + class C + { + void Main(string s, string y) + { + Expression> e = () => {|Warning:s ?? y|}; } - """, - """ - using System; - - class C - { - void M(string x, string y) - { - var z = x ?? y; - } + } + """); + } + + [Fact] + public async Task TestUnconstrainedTypeParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void Main(T t) + { + var v = [||]t == null ? throw new Exception() : t; + } + } + """); + } + + [Fact] + public async Task TestStructConstrainedTypeParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + class C where T : struct + { + void Main(T t) + { + var v = [||]t == null ? throw new Exception() : t; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestClassConstrainedTypeParameter() + { + await TestInRegularAndScript1Async( + """ + class C where T : class + { + void Main(T t) + { + var v = [||]t == null ? throw new Exception() : t; + } + } + """, + """ + class C where T : class + { + void Main(T t) + { + var v = t ?? throw new Exception(); + } + } + """); + } - class C + [Fact] + public async Task TestNotOnNullable() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void Main(int? t) { - void M(string x, string y) - { - var z1 = {|FixAllInDocument:x|} == null ? y : x; - var z2 = x != null ? x : y; - } + var v = [||]t == null ? throw new Exception() : t; } - """, - """ - using System; + } + """); + } - class C + [Fact] + public async Task TestOnArray() + { + await TestInRegularAndScript1Async( + """ + class C + { + void Main(int[] t) { - void M(string x, string y) - { - var z1 = x ?? y; - var z2 = x ?? y; - } + var v = [||]t == null ? throw new Exception() : t; } - """); - } + } + """, + """ + class C + { + void Main(int[] t) + { + var v = t ?? throw new Exception(); + } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + [Fact] + public async Task TestOnInterface() + { + await TestInRegularAndScript1Async( + """ + class C + { + void Main(System.ICloneable t) + { + var v = [||]t == null ? throw new Exception() : t; + } + } + """, + """ + class C + { + void Main(System.ICloneable t) { - void M(string x, string y, string z) - { - var w = {|FixAllInDocument:x|} != null ? x : y.ToString(z != null ? z : y); - } + var v = t ?? throw new Exception(); } - """, - """ - using System; + } + """); + } - class C + [Fact] + public async Task TestOnDynamic() + { + await TestInRegularAndScript1Async( + """ + class C + { + void Main(dynamic t) + { + var v = [||]t == null ? throw new Exception() : t; + } + } + """, + """ + class C + { + void Main(dynamic t) { - void M(string x, string y, string z) - { - var w = x ?? y.ToString(z ?? y); - } + var v = t ?? throw new Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll3() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C - { - void M(string x, string y, string z) - { - var w = {|FixAllInDocument:x|} != null ? x : y != null ? y : z; - } - } - """, - """ - using System; - - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38066")] + public async Task TestSemicolonPlacement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string s) + { + _ = [||]s == null + ? "" + : s; + } + } + """, + """ + class C + { + void M(string s) + { + _ = s ?? ""; + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38066")] + public async Task TestParenthesisPlacement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string s) + { + M([||]s == null + ? "" + : s); + } + } + """, + """ + class C + { + void M(string s) + { + M(s ?? ""); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38066")] + public async Task TestAnotherConditionalPlacement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string s) + { + _ = cond + ? [||]s == null + ? "" + : s + : ""; + } + } + """, + """ + class C + { + void M(string s) + { + _ = cond + ? s ?? "" + : ""; + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53190")] + public async Task TestNotWithTargetTyping() + { + await TestMissingAsync( + """ + class Program + { + class A { } + class B { } + + static void Main(string[] args) { - void M(string x, string y, string z) - { - var w = x ?? y ?? z; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16025")] - public async Task TestTrivia1() - { - await TestInRegularAndScript1Async( - """ - using System; - - class Program - { - public Program() - { - string x = "; - - string y = [|x|] == null ? string.Empty : x; - } - } - """, - """ - using System; - - class Program - { - public Program() - { - string x = "; - - string y = x ?? string.Empty; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17028")] - public async Task TestInExpressionOfT() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Linq.Expressions; - - class C - { - void Main(string s, string y) - { - Expression> e = () => [||]s != null ? s : y; - } - } - """, - """ - using System; - using System.Linq.Expressions; - - class C - { - void Main(string s, string y) - { - Expression> e = () => {|Warning:s ?? y|}; - } - } - """); - } - - [Fact] - public async Task TestUnconstrainedTypeParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void Main(T t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """); - } - - [Fact] - public async Task TestStructConstrainedTypeParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - class C where T : struct - { - void Main(T t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """); - } - - [Fact] - public async Task TestClassConstrainedTypeParameter() - { - await TestInRegularAndScript1Async( - """ - class C where T : class - { - void Main(T t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """, - """ - class C where T : class - { - void Main(T t) - { - var v = t ?? throw new Exception(); - } - } - """); - } - - [Fact] - public async Task TestNotOnNullable() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void Main(int? t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """); - } - - [Fact] - public async Task TestOnArray() - { - await TestInRegularAndScript1Async( - """ - class C - { - void Main(int[] t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """, - """ - class C - { - void Main(int[] t) - { - var v = t ?? throw new Exception(); - } - } - """); - } - - [Fact] - public async Task TestOnInterface() - { - await TestInRegularAndScript1Async( - """ - class C - { - void Main(System.ICloneable t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """, - """ - class C - { - void Main(System.ICloneable t) - { - var v = t ?? throw new Exception(); - } - } - """); - } - - [Fact] - public async Task TestOnDynamic() - { - await TestInRegularAndScript1Async( - """ - class C - { - void Main(dynamic t) - { - var v = [||]t == null ? throw new Exception() : t; - } - } - """, - """ - class C - { - void Main(dynamic t) - { - var v = t ?? throw new Exception(); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38066")] - public async Task TestSemicolonPlacement() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(string s) - { - _ = [||]s == null - ? "" - : s; - } - } - """, - """ - class C - { - void M(string s) - { - _ = s ?? ""; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38066")] - public async Task TestParenthesisPlacement() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(string s) - { - M([||]s == null - ? "" - : s); - } - } - """, - """ - class C - { - void M(string s) - { - M(s ?? ""); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38066")] - public async Task TestAnotherConditionalPlacement() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(string s) - { - _ = cond - ? [||]s == null - ? "" - : s - : ""; - } - } - """, - """ - class C - { - void M(string s) - { - _ = cond - ? s ?? "" - : ""; - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53190")] - public async Task TestNotWithTargetTyping() - { - await TestMissingAsync( - """ - class Program - { - class A { } - class B { } - - static void Main(string[] args) - { - var a = new A(); - var b = new B(); - - object x = [||]a != null ? a : b; - } - } - """); - } + var a = new A(); + var b = new B(); + + object x = [||]a != null ? a : b; + } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs index fec3c88739190..7c6f60d5b98e3 100644 --- a/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCollectionExpression/UseCollectionExpressionForArrayTests.cs @@ -5306,78 +5306,6 @@ public async Task TestDynamic6() using System.Collections.Generic; using System.Linq.Expressions; - class C - { - public void Test(dynamic obj) - { - Test1(obj, new int?[] { 3 }); - } - - private void Test1(dynamic obj, params int?[][] args) - { - } - } - """, - LanguageVersion = LanguageVersion.Preview, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72640")] - public async Task TestDynamic7() - { - await new VerifyCS.Test - { - TestCode = - """ - using System; - using System.Collections.Generic; - using System.Linq.Expressions; - - class C - { - public void Test(dynamic obj) - { - Test1(obj, [|[|new|] int?[]|] { 3 }); - } - - private void Test1(dynamic obj, int?[] args) - { - } - } - """, - FixedCode = - """ - using System; - using System.Collections.Generic; - using System.Linq.Expressions; - - class C - { - public void Test(dynamic obj) - { - Test1(obj, [3]); - } - - private void Test1(dynamic obj, int?[] args) - { - } - } - """, - LanguageVersion = LanguageVersion.Preview, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72640")] - public async Task TestDynamic6_CSharp12() - { - await new VerifyCS.Test - { - TestCode = - """ - using System; - using System.Collections.Generic; - using System.Linq.Expressions; - class C { public void Test(dynamic obj) @@ -5395,7 +5323,7 @@ private void Test1(dynamic obj, params int?[][] args) } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72640")] - public async Task TestDynamic7_CSharp12() + public async Task TestDynamic7() { await new VerifyCS.Test { diff --git a/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundAssignmentTests.cs b/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundAssignmentTests.cs index 87be034e7fb29..fb61260019e04 100644 --- a/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundAssignmentTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundAssignmentTests.cs @@ -11,1567 +11,1566 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCompoundAssignment -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseCompoundAssignmentDiagnosticAnalyzer, - CSharpUseCompoundAssignmentCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCompoundAssignment; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseCompoundAssignmentDiagnosticAnalyzer, + CSharpUseCompoundAssignmentCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseCompoundAssignment)] - public class UseCompoundAssignmentTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseCompoundAssignment)] +public class UseCompoundAssignmentTests +{ + [Fact] + public async Task TestAddExpression() { - [Fact] - public async Task TestAddExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a + 10; - } + a [|=|] a + 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a += 10; - } + a += 10; } - """); - } + } + """); + } - [Fact] - public async Task TestSubtractExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestSubtractExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a - 10; - } + a [|=|] a - 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a -= 10; - } + a -= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestMultiplyExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestMultiplyExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a * 10; - } + a [|=|] a * 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a *= 10; - } + a *= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestDivideExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestDivideExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a / 10; - } + a [|=|] a / 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a /= 10; - } + a /= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestModuloExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestModuloExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a % 10; - } + a [|=|] a % 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a %= 10; - } + a %= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestBitwiseAndExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestBitwiseAndExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a & 10; - } + a [|=|] a & 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a &= 10; - } + a &= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestExclusiveOrExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestExclusiveOrExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a ^ 10; - } + a [|=|] a ^ 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a ^= 10; - } + a ^= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestBitwiseOrExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestBitwiseOrExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a | 10; - } + a [|=|] a | 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a |= 10; - } + a |= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestLeftShiftExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestLeftShiftExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a << 10; - } + a [|=|] a << 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a <<= 10; - } + a <<= 10; } - """); - } + } + """); + } - [Fact] - public async Task TestRightShiftExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestRightShiftExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a >> 10; - } + a [|=|] a >> 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a >>= 10; - } + a >>= 10; } - """); - } - - [Fact] - public async Task TestCoalesceExpressionCSharp8OrGreater() - { - await new VerifyCS.Test() - { - TestCode = """ - public class C - { - void M(int? a) - { - a [|=|] a ?? 10; - } - } - """, - FixedCode = """ - public class C - { - void M(int? a) - { - a ??= 10; - } - } - """, - LanguageVersion = LanguageVersion.CSharp8 - }.RunAsync(); - } + } + """); + } - [Fact] - public async Task TestCoalesceExpressionCSharp7() + [Fact] + public async Task TestCoalesceExpressionCSharp8OrGreater() + { + await new VerifyCS.Test() { - var code = """ + TestCode = """ public class C { void M(int? a) { - a = a ?? 10; + a [|=|] a ?? 10; } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_3 - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36467")] - public async Task TestNotSuggestedWhenRightHandIsThrowExpression() - { - var code = """ - using System; + """, + FixedCode = """ public class C { void M(int? a) { - a = a ?? throw new Exception(); + a ??= 10; } } - """; + """, + LanguageVersion = LanguageVersion.CSharp8 + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestCoalesceExpressionCSharp7() + { + var code = """ + public class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp8 - }.RunAsync(); - } + void M(int? a) + { + a = a ?? 10; + } + } + """; - [Fact] - public async Task TestField() + await new VerifyCS.Test() { - await VerifyCS.VerifyCodeFixAsync(""" - public class C - { - int a; + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_3 + }.RunAsync(); + } - void M() - { - a [|=|] a + 10; - } - } - """, """ - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36467")] + public async Task TestNotSuggestedWhenRightHandIsThrowExpression() + { + var code = """ + using System; + public class C + { + void M(int? a) { - int a; - - void M() - { - a += 10; - } + a = a ?? throw new Exception(); } - """); - } + } + """; - [Fact] - public async Task TestFieldWithThis() + await new VerifyCS.Test() { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp8 + }.RunAsync(); + } + + [Fact] + public async Task TestField() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a; + + void M() { - int a; + a [|=|] a + 10; + } + } + """, """ + public class C + { + int a; - void M() - { - this.a [|=|] this.a + 10; - } + void M() + { + a += 10; } - """, """ - public class C + } + """); + } + + [Fact] + public async Task TestFieldWithThis() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a; + + void M() { - int a; + this.a [|=|] this.a + 10; + } + } + """, """ + public class C + { + int a; - void M() - { - this.a += 10; - } + void M() + { + this.a += 10; } - """); - } + } + """); + } - [Fact] - public async Task TestTriviaInsensitive() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestTriviaInsensitive() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a; + + void M() { - int a; + this . /*trivia*/ a [|=|] this /*comment*/ .a + 10; + } + } + """, """ + public class C + { + int a; - void M() - { - this . /*trivia*/ a [|=|] this /*comment*/ .a + 10; - } + void M() + { + this . /*trivia*/ a += 10; } - """, """ - public class C + } + """); + } + + [Fact] + public async Task TestStaticFieldThroughType() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + static int a; + + void M() { - int a; + C.a [|=|] C.a + 10; + } + } + """, """ + public class C + { + static int a; - void M() - { - this . /*trivia*/ a += 10; - } + void M() + { + C.a += 10; } - """); - } + } + """); + } - [Fact] - public async Task TestStaticFieldThroughType() - { - await VerifyCS.VerifyCodeFixAsync(""" + [Fact] + public async Task TestStaticFieldThroughNamespaceAndType() + { + await VerifyCS.VerifyCodeFixAsync(""" + namespace NS + { public class C { static int a; void M() { - C.a [|=|] C.a + 10; + NS.C.a [|=|] NS.C.a + 10; } } - """, """ + } + """, """ + namespace NS + { public class C { static int a; void M() { - C.a += 10; + NS.C.a += 10; } } - """); - } + } + """); + } - [Fact] - public async Task TestStaticFieldThroughNamespaceAndType() - { - await VerifyCS.VerifyCodeFixAsync(""" - namespace NS - { - public class C - { - static int a; + [Fact] + public async Task TestParenthesized() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a; - void M() - { - NS.C.a [|=|] NS.C.a + 10; - } - } - } - """, """ - namespace NS + void M() { - public class C - { - static int a; - - void M() - { - NS.C.a += 10; - } - } + (a) [|=|] (a) + 10; } - """); - } + } + """, """ + public class C + { + int a; - [Fact] - public async Task TestParenthesized() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + void M() { - int a; - - void M() - { - (a) [|=|] (a) + 10; - } + (a) += 10; } - """, """ - public class C - { - int a; + } + """); + } - void M() - { - (a) += 10; - } - } - """); - } + [Fact] + public async Task TestThroughBase() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + public int a; + } - [Fact] - public async Task TestThroughBase() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + public class D : C + { + void M() { - public int a; + base.a [|=|] base.a + 10; } + } + """, """ + public class C + { + public int a; + } - public class D : C + public class D : C + { + void M() { - void M() - { - base.a [|=|] base.a + 10; - } + base.a += 10; } - """, """ - public class C + } + """); + } + + [Fact] + public async Task TestMultiAccess() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + public int a; + } + + public class D + { + C c; + + void M() { - public int a; + this.c.a [|=|] this.c.a + 10; } + } + """, """ + public class C + { + public int a; + } + + public class D + { + C c; - public class D : C + void M() { - void M() - { - base.a += 10; - } + this.c.a += 10; } - """); - } + } + """); + } - [Fact] - public async Task TestMultiAccess() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestOnTopLevelProp1() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a { get; set; } + + void M() { - public int a; + a [|=|] a + 10; } + } + """, """ + public class C + { + int a { get; set; } - public class D + void M() { - C c; - - void M() - { - this.c.a [|=|] this.c.a + 10; - } - } - """, """ - public class C - { - public int a; + a += 10; } + } + """); + } - public class D - { - C c; + [Fact] + public async Task TestOnTopLevelProp2() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a { get; set; } - void M() - { - this.c.a += 10; - } + void M() + { + this.a [|=|] this.a + 10; } - """); - } + } + """, """ + public class C + { + int a { get; set; } - [Fact] - public async Task TestOnTopLevelProp1() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + void M() { - int a { get; set; } - - void M() - { - a [|=|] a + 10; - } + this.a += 10; } - """, """ - public class C - { - int a { get; set; } + } + """); + } - void M() - { - a += 10; - } - } - """); - } + [Fact] + public async Task TestOnTopLevelProp3() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + int a { get; set; } - [Fact] - public async Task TestOnTopLevelProp2() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + void M() { - int a { get; set; } - - void M() - { - this.a [|=|] this.a + 10; - } + (this.a) [|=|] (this.a) + 10; } - """, """ - public class C - { - int a { get; set; } + } + """, """ + public class C + { + int a { get; set; } - void M() - { - this.a += 10; - } + void M() + { + (this.a) += 10; } - """); - } + } + """); + } - [Fact] - public async Task TestOnTopLevelProp3() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C - { - int a { get; set; } + [Fact] + public async Task TestNotOnTopLevelRefProp() + { + var code = """ + public class C + { + int x; + ref int a { get { return ref x; } } - void M() - { - (this.a) [|=|] (this.a) + 10; - } - } - """, """ - public class C + void M() { - int a { get; set; } - - void M() - { - (this.a) += 10; - } + a = a + 10; } - """); - } + } + """; - [Fact] - public async Task TestNotOnTopLevelRefProp() - { - var code = """ - public class C - { - int x; - ref int a { get { return ref x; } } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - void M() - { - a = a + 10; - } - } - """; + [Fact] + public async Task TestNotOnNestedProp1() + { + var code = """ + public class A + { + public int x; + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + public class C + { + A a { get; } - [Fact] - public async Task TestNotOnNestedProp1() - { - var code = """ - public class A + void M() { - public int x; + a.x = a.x + 10; } + } + """; - public class C - { - A a { get; } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - void M() - { - a.x = a.x + 10; - } - } - """; + [Fact] + public async Task TestNotOnNestedProp2() + { + var code = """ + public class A + { + public int x; + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + public class C + { + A a { get; } - [Fact] - public async Task TestNotOnNestedProp2() - { - var code = """ - public class A + void M() { - public int x; + this.a.x = this.a.x + 10; } + } + """; - public class C - { - A a { get; } - - void M() - { - this.a.x = this.a.x + 10; - } - } - """; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - await VerifyCS.VerifyCodeFixAsync(code, code); - } + [Fact] + public async Task TestNotOnNestedProp3() + { + var code = """ + public class A + { + public int x; + } - [Fact] - public async Task TestNotOnNestedProp3() - { - var code = """ - public class A - { - public int x; - } + public class C + { + A a { get; } - public class C + void M() { - A a { get; } - - void M() - { - (a.x) = (a.x) + 10; - } + (a.x) = (a.x) + 10; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestNotOnUnboundSymbol() - { - var code = """ - public class C + [Fact] + public async Task TestNotOnUnboundSymbol() + { + var code = """ + public class C + { + void M() { - void M() - { - {|CS0103:a|} = {|CS0103:a|} + 10; - } + {|CS0103:a|} = {|CS0103:a|} + 10; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestNotOnUnboundThisAccess() - { - var code = """ - public class C + [Fact] + public async Task TestNotOnUnboundThisAccess() + { + var code = """ + public class C + { + void M() { - void M() - { - this.{|CS1061:a|} = this.{|CS1061:a|} + 10; - } + this.{|CS1061:a|} = this.{|CS1061:a|} + 10; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestNotWithSideEffects() - { - var code = """ - public class C - { - int i; + [Fact] + public async Task TestNotWithSideEffects() + { + var code = """ + public class C + { + int i; - C Goo() => this; + C Goo() => this; - void M() - { - this.Goo().i = this.Goo().i + 10; - } + void M() + { + this.Goo().i = this.Goo().i + 10; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35870")] - public async Task TestRightExpressionOnNextLine() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35870")] + public async Task TestRightExpressionOnNextLine() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a + - 10; - } + a [|=|] a + + 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a += 10; - } + a += 10; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35870")] - public async Task TestRightExpressionSeparatedWithSeveralLines() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35870")] + public async Task TestRightExpressionSeparatedWithSeveralLines() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a + + a [|=|] a + - 10; - } + 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a += 10; - } + a += 10; } - """); - } + } + """); + } - [Fact] - public async Task TestTrivia() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestTrivia() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - // before - a [|=|] a + 10; // after - } + // before + a [|=|] a + 10; // after } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - // before - a += 10; // after - } + // before + a += 10; // after } - """); - } + } + """); + } - [Fact] - public async Task TestTrivia2() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestTrivia2() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a /*mid1*/ [|=|] /*mid2*/ a + 10; - } + a /*mid1*/ [|=|] /*mid2*/ a + 10; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a /*mid1*/ += /*mid2*/ 10; - } + a /*mid1*/ += /*mid2*/ 10; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestFixAll() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a, int b) { - void M(int a, int b) - { - a [|=|] a + 10; - b [|=|] b - a; - } + a [|=|] a + 10; + b [|=|] b - a; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a, int b) { - void M(int a, int b) - { - a += 10; - b -= a; - } + a += 10; + b -= a; } - """); - } + } + """); + } - [Fact] - public async Task TestNestedAssignment() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact] + public async Task TestNestedAssignment() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a, int b) { - void M(int a, int b) - { - b = (a [|=|] a + 10); - } + b = (a [|=|] a + 10); } - """, """ - public class C + } + """, """ + public class C + { + void M(int a, int b) { - void M(int a, int b) - { - b = (a += 10); - } + b = (a += 10); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33382")] - public async Task TestNotOnObjectInitializer() - { - var code = """ - struct InsertionPoint - { - int level; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33382")] + public async Task TestNotOnObjectInitializer() + { + var code = """ + struct InsertionPoint + { + int level; - InsertionPoint Up() + InsertionPoint Up() + { + return new InsertionPoint { - return new InsertionPoint - { - level = level - 1, - }; - } + level = level - 1, + }; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49294")] - public async Task TestNotOnImplicitObjectInitializer() - { - var code = """ - struct InsertionPoint - { - int level; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49294")] + public async Task TestNotOnImplicitObjectInitializer() + { + var code = """ + struct InsertionPoint + { + int level; - InsertionPoint Up() + InsertionPoint Up() + { + return new InsertionPoint() { - return new InsertionPoint() - { - level = level - 1, - }; - } + level = level - 1, + }; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49294")] - public async Task TestNotOnRecord() - { - var code = """ - record InsertionPoint(int level) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49294")] + public async Task TestNotOnRecord() + { + var code = """ + record InsertionPoint(int level) + { + InsertionPoint Up() { - InsertionPoint Up() + return this with { - return this with - { - level = level - 1, - }; - } + level = level - 1, + }; } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp9, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - await new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38137")] + public async Task TestParenthesizedExpression() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) + { + a [|=|] (a + 10); + } + } + """, """ + public class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp9, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + void M(int a) + { + a += 10; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38137")] - public async Task TestParenthesizedExpression() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrement() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] (a + 10); - } + a [|=|] a + 1; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a += 10; - } + a++; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrement() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestDecrement() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a + 1; - } + a [|=|] a - 1; } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a++; - } + a--; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestDecrement() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestMinusIncrement() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int a) { - void M(int a) - { - a [|=|] a - 1; - } + a [|=|] a + (-1); } - """, """ - public class C + } + """, """ + public class C + { + void M(int a) { - void M(int a) - { - a--; - } + a--; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestMinusIncrement() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrementDouble() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(double a) { - void M(int a) - { - a [|=|] a + (-1); - } + a [|=|] a + 1.0; } - """, """ - public class C + } + """, """ + public class C + { + void M(double a) { - void M(int a) - { - a--; - } + a++; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrementDouble() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrementNotOnString() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(string a) { - void M(double a) - { - a [|=|] a + 1.0; - } + a [|=|] a + "1"; } - """, """ - public class C + } + """, """ + public class C + { + void M(string a) { - void M(double a) - { - a++; - } + a += "1"; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrementNotOnString() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrementChar() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(char a) { - void M(string a) - { - a [|=|] a + "1"; - } + a [|=|] {|CS0266:a + 1|}; } - """, """ - public class C + } + """, """ + public class C + { + void M(char a) { - void M(string a) - { - a += "1"; - } + a++; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrementChar() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrementEnum() + { + await VerifyCS.VerifyCodeFixAsync(""" + public enum E {} + public class C + { + void M(E a) { - void M(char a) - { - a [|=|] {|CS0266:a + 1|}; - } + a [|=|] a + 1; } - """, """ - public class C + } + """, """ + public enum E {} + public class C + { + void M(E a) { - void M(char a) - { - a++; - } + a++; + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrementDecimal() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(decimal a) + { + a [|=|] a + 1.0m; } - """); - } + } + """, """ + public class C + { + void M(decimal a) + { + a++; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrementEnum() + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + [InlineData("byte")] + [InlineData("short")] + [InlineData("long")] + [InlineData("float")] + [InlineData("decimal")] + public async Task TestIncrementLiteralConversion(string typeName) + { + await new VerifyCS.Test() { - await VerifyCS.VerifyCodeFixAsync(""" - public enum E {} + TestCode = $$""" public class C { - void M(E a) + void M({{typeName}} a) { - a [|=|] a + 1; + a [|=|] (a + ({{typeName}})1); } } - """, """ - public enum E {} + """, + FixedCode = $$""" public class C { - void M(E a) + void M({{typeName}} a) { a++; } } - """); - } + """, + CompilerDiagnostics = CompilerDiagnostics.None + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrementDecimal() + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + [InlineData("byte")] + [InlineData("short")] + [InlineData("long")] + [InlineData("float")] + [InlineData("decimal")] + public async Task TestIncrementImplicitLiteralConversion(string typeName) + { + await new VerifyCS.Test() { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = $$""" public class C { - void M(decimal a) + void M({{typeName}} a) { - a [|=|] a + 1.0m; + a [|=|] a + 1; } } - """, """ + """, + FixedCode = $$""" public class C { - void M(decimal a) + void M({{typeName}} a) { a++; } } - """); - } + """, + CompilerDiagnostics = CompilerDiagnostics.None + }.RunAsync(); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - [InlineData("byte")] - [InlineData("short")] - [InlineData("long")] - [InlineData("float")] - [InlineData("decimal")] - public async Task TestIncrementLiteralConversion(string typeName) - { - await new VerifyCS.Test() - { - TestCode = $$""" - public class C - { - void M({{typeName}} a) - { - a [|=|] (a + ({{typeName}})1); - } - } - """, - FixedCode = $$""" - public class C - { - void M({{typeName}} a) - { - a++; - } - } - """, - CompilerDiagnostics = CompilerDiagnostics.None - }.RunAsync(); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - [InlineData("byte")] - [InlineData("short")] - [InlineData("long")] - [InlineData("float")] - [InlineData("decimal")] - public async Task TestIncrementImplicitLiteralConversion(string typeName) - { - await new VerifyCS.Test() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] + public async Task TestIncrementLoopVariable() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C { - TestCode = $$""" - public class C - { - void M({{typeName}} a) - { - a [|=|] a + 1; - } - } - """, - FixedCode = $$""" - public class C - { - void M({{typeName}} a) - { - a++; - } - } - """, - CompilerDiagnostics = CompilerDiagnostics.None - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38054")] - public async Task TestIncrementLoopVariable() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + void M() { - void M() + for (int i = 0; i < 10; i [|=|] i + 1) { - for (int i = 0; i < 10; i [|=|] i + 1) - { - } } } - """, """ - public class C + } + """, """ + public class C + { + void M() { - void M() + for (int i = 0; i < 10; i++) { - for (int i = 0; i < 10; i++) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] - public async Task TestIncrementInExpressionContext() - { - await VerifyCS.VerifyCodeFixAsync(""" - public class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] + public async Task TestIncrementInExpressionContext() + { + await VerifyCS.VerifyCodeFixAsync(""" + public class C + { + void M(int i) { - void M(int i) - { - M(i [|=|] i + 1); - } + M(i [|=|] i + 1); } - """, """ - public class C + } + """, """ + public class C + { + void M(int i) { - void M(int i) - { - M(++i); - } + M(++i); } - """); - } + } + """); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] - [InlineData("switch($$) { }")] - [InlineData("while(($$) > 0) { }")] - [InlineData("_ = true ? $$ : 0;")] - [InlineData("_ = ($$);")] - public async Task TestPrefixIncrement1(string expressionContext) - { - var before = expressionContext.Replace("$$", "i [|=|] i + 1"); - var after = expressionContext.Replace("$$", "++i"); - await VerifyCS.VerifyCodeFixAsync($$""" - public class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] + [InlineData("switch($$) { }")] + [InlineData("while(($$) > 0) { }")] + [InlineData("_ = true ? $$ : 0;")] + [InlineData("_ = ($$);")] + public async Task TestPrefixIncrement1(string expressionContext) + { + var before = expressionContext.Replace("$$", "i [|=|] i + 1"); + var after = expressionContext.Replace("$$", "++i"); + await VerifyCS.VerifyCodeFixAsync($$""" + public class C + { + void M(int i) { - void M(int i) - { - {{before}} - } + {{before}} } - """, $$""" - public class C + } + """, $$""" + public class C + { + void M(int i) { - void M(int i) - { - {{after}} - } + {{after}} } - """); - } + } + """); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] - [InlineData("return $$;")] - [InlineData("return true ? $$ : 0;")] - [InlineData("return ($$);")] - public async Task TestPrefixIncrement2(string expressionContext) - { - var before = expressionContext.Replace("$$", "i [|=|] i + 1"); - var after = expressionContext.Replace("$$", "++i"); - await VerifyCS.VerifyCodeFixAsync($$""" - public class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] + [InlineData("return $$;")] + [InlineData("return true ? $$ : 0;")] + [InlineData("return ($$);")] + public async Task TestPrefixIncrement2(string expressionContext) + { + var before = expressionContext.Replace("$$", "i [|=|] i + 1"); + var after = expressionContext.Replace("$$", "++i"); + await VerifyCS.VerifyCodeFixAsync($$""" + public class C + { + int M(int i) { - int M(int i) - { - {{before}} - } + {{before}} } - """, $$""" - public class C + } + """, $$""" + public class C + { + int M(int i) { - int M(int i) - { - {{after}} - } + {{after}} } - """); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] - [InlineData( - "/* Before */ i [|=|] i + 1; /* After */", - "/* Before */ i++; /* After */")] - [InlineData( - "M( /* Before */ i [|=|] i + 1 /* After */ );", - "M( /* Before */ ++i /* After */ );")] - [InlineData( - "M( /* Before */ i [|=|] i - 1 /* After */ );", - "M( /* Before */ --i /* After */ );")] - public async Task TestTriviaPreserved(string before, string after) - { - await VerifyCS.VerifyCodeFixAsync($$""" - public class C + } + """); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/53969")] + [InlineData( + "/* Before */ i [|=|] i + 1; /* After */", + "/* Before */ i++; /* After */")] + [InlineData( + "M( /* Before */ i [|=|] i + 1 /* After */ );", + "M( /* Before */ ++i /* After */ );")] + [InlineData( + "M( /* Before */ i [|=|] i - 1 /* After */ );", + "M( /* Before */ --i /* After */ );")] + public async Task TestTriviaPreserved(string before, string after) + { + await VerifyCS.VerifyCodeFixAsync($$""" + public class C + { + void M(int i) { - void M(int i) - { - {{before}} - } + {{before}} } - """, $$""" - public class C + } + """, $$""" + public class C + { + void M(int i) { - void M(int i) - { - {{after}} - } + {{after}} } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] - public async Task TestIncrementWithUserDefinedOperators_IncrementOperatorNotDefined() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C - { - int data; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] + public async Task TestIncrementWithUserDefinedOperators_IncrementOperatorNotDefined() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int data; - public C(int data) - { - this.data = data; - } + public C(int data) + { + this.data = data; + } - public static C operator +(C left, int right) - { - return new C(left.data + right); - } + public static C operator +(C left, int right) + { + return new C(left.data + right); + } - void M() - { - var c = new C(0); - c [|=|] c + 1; - } + void M() + { + var c = new C(0); + c [|=|] c + 1; } - """, """ - class C + } + """, """ + class C + { + int data; + + public C(int data) { - int data; - - public C(int data) - { - this.data = data; - } - - public static C operator +(C left, int right) - { - return new C(left.data + right); - } - - void M() - { - var c = new C(0); - c += 1; - } + this.data = data; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] - public async Task TestIncrementWithUserDefinedOperators_IncrementOperatorDefined() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + + public static C operator +(C left, int right) { - int data; - - public C(int data) - { - this.data = data; - } - - public static C operator +(C left, int right) - { - return new C(left.data + right); - } + return new C(left.data + right); + } + + void M() + { + var c = new C(0); + c += 1; + } + } + """); + } - public static C operator ++(C operand) - { - return new C(operand.data + 1); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] + public async Task TestIncrementWithUserDefinedOperators_IncrementOperatorDefined() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int data; - void M() - { - var c = new C(0); - c [|=|] c + 1; - } + public C(int data) + { + this.data = data; } - """, """ - class C + + public static C operator +(C left, int right) { - int data; - - public C(int data) - { - this.data = data; - } - - public static C operator +(C left, int right) - { - return new C(left.data + right); - } + return new C(left.data + right); + } - public static C operator ++(C operand) - { - return new C(operand.data + 1); - } + public static C operator ++(C operand) + { + return new C(operand.data + 1); + } - void M() - { - var c = new C(0); - c++; - } + void M() + { + var c = new C(0); + c [|=|] c + 1; + } + } + """, """ + class C + { + int data; + + public C(int data) + { + this.data = data; + } + + public static C operator +(C left, int right) + { + return new C(left.data + right); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] - public async Task TestDecrementWithUserDefinedOperators_DecrementOperatorNotDefined() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + public static C operator ++(C operand) { - int data; + return new C(operand.data + 1); + } - public C(int data) - { - this.data = data; - } + void M() + { + var c = new C(0); + c++; + } + } + """); + } - public static C operator -(C left, int right) - { - return new C(left.data - right); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] + public async Task TestDecrementWithUserDefinedOperators_DecrementOperatorNotDefined() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int data; - void M() - { - var c = new C(0); - c [|=|] c - 1; - } + public C(int data) + { + this.data = data; } - """, """ - class C + + public static C operator -(C left, int right) { - int data; - - public C(int data) - { - this.data = data; - } - - public static C operator -(C left, int right) - { - return new C(left.data - right); - } - - void M() - { - var c = new C(0); - c -= 1; - } + return new C(left.data - right); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] - public async Task TestDecrementWithUserDefinedOperators_DecrementOperatorDefined() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + void M() + { + var c = new C(0); + c [|=|] c - 1; + } + } + """, """ + class C + { + int data; + + public C(int data) + { + this.data = data; + } + + public static C operator -(C left, int right) { - int data; + return new C(left.data - right); + } + + void M() + { + var c = new C(0); + c -= 1; + } + } + """); + } - public C(int data) - { - this.data = data; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70651")] + public async Task TestDecrementWithUserDefinedOperators_DecrementOperatorDefined() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + int data; - public static C operator -(C left, int right) - { - return new C(left.data - right); - } + public C(int data) + { + this.data = data; + } - public static C operator --(C operand) - { - return new C(operand.data - 1); - } + public static C operator -(C left, int right) + { + return new C(left.data - right); + } - void M() - { - var c = new C(0); - c [|=|] c - 1; - } + public static C operator --(C operand) + { + return new C(operand.data - 1); } - """, """ - class C + + void M() { - int data; - - public C(int data) - { - this.data = data; - } - - public static C operator -(C left, int right) - { - return new C(left.data - right); - } + var c = new C(0); + c [|=|] c - 1; + } + } + """, """ + class C + { + int data; + + public C(int data) + { + this.data = data; + } + + public static C operator -(C left, int right) + { + return new C(left.data - right); + } - public static C operator --(C operand) - { - return new C(operand.data - 1); - } + public static C operator --(C operand) + { + return new C(operand.data - 1); + } - void M() - { - var c = new C(0); - c--; - } + void M() + { + var c = new C(0); + c--; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundCoalesceAssignmentTests.cs b/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundCoalesceAssignmentTests.cs index bf479f677e23c..eb005bef46ee7 100644 --- a/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundCoalesceAssignmentTests.cs +++ b/src/Analyzers/CSharp/Tests/UseCompoundAssignment/UseCompoundCoalesceAssignmentTests.cs @@ -11,994 +11,993 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCompoundAssignment -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseCompoundCoalesceAssignmentDiagnosticAnalyzer, - CSharpUseCompoundCoalesceAssignmentCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseCompoundAssignment; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseCompoundCoalesceAssignmentDiagnosticAnalyzer, + CSharpUseCompoundCoalesceAssignmentCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseCompoundAssignment)] - public class UseCompoundCoalesceAssignmentTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseCompoundAssignment)] +public class UseCompoundCoalesceAssignmentTests +{ + private static async Task TestInRegularAndScriptAsync(string testCode, string fixedCode) { - private static async Task TestInRegularAndScriptAsync(string testCode, string fixedCode) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - }.RunAsync(); - } - private static async Task TestMissingAsync(string testCode, LanguageVersion languageVersion = LanguageVersion.CSharp8) + TestCode = testCode, + FixedCode = fixedCode, + }.RunAsync(); + } + private static async Task TestMissingAsync(string testCode, LanguageVersion languageVersion = LanguageVersion.CSharp8) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = testCode, + FixedCode = testCode, + LanguageVersion = languageVersion, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestBaseCase() + { + await TestInRegularAndScriptAsync( + """ + class Program { - TestCode = testCode, - FixedCode = testCode, - LanguageVersion = languageVersion, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - }.RunAsync(); - } + private static string s_goo; + private static string Goo => s_goo [|??|] (s_goo = new string('c', 42)); + } + """, + """ + class Program + { + private static string s_goo; + private static string Goo => s_goo ??= new string('c', 42); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestBaseCase() - { - await TestInRegularAndScriptAsync( - """ - class Program - { - private static string s_goo; - private static string Goo => s_goo [|??|] (s_goo = new string('c', 42)); - } - """, - """ - class Program - { - private static string s_goo; - private static string Goo => s_goo ??= new string('c', 42); - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44793")] + public async Task TestMissingBeforeCSharp8() + { + await TestMissingAsync( + """ + class Program + { + private static string s_goo; + private static string Goo => s_goo ?? (s_goo = new string('c', 42)); + } + """, LanguageVersion.CSharp7_3); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44793")] - public async Task TestMissingBeforeCSharp8() - { - await TestMissingAsync( - """ - class Program - { - private static string s_goo; - private static string Goo => s_goo ?? (s_goo = new string('c', 42)); - } - """, LanguageVersion.CSharp7_3); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestRightMustBeParenthesized() + { + await TestMissingAsync( + """ + class Program + { + private static string s_goo; + private static string Goo => {|CS0131:s_goo ?? s_goo|} = new string('c', 42); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestRightMustBeParenthesized() - { - await TestMissingAsync( - """ - class Program - { - private static string s_goo; - private static string Goo => {|CS0131:s_goo ?? s_goo|} = new string('c', 42); - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestRightMustBeAssignment() + { + await TestMissingAsync( + """ + class Program + { + private static string s_goo; + private static string Goo => {|CS0019:s_goo ?? (s_goo == new string('c', 42))|}; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestRightMustBeAssignment() - { - await TestMissingAsync( - """ - class Program - { - private static string s_goo; - private static string Goo => {|CS0019:s_goo ?? (s_goo == new string('c', 42))|}; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestRightMustBeSimpleAssignment() + { + await TestMissingAsync( + """ + class Program + { + private static string s_goo; + private static string Goo => s_goo ?? (s_goo ??= new string('c', 42)); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestRightMustBeSimpleAssignment() - { - await TestMissingAsync( - """ - class Program - { - private static string s_goo; - private static string Goo => s_goo ?? (s_goo ??= new string('c', 42)); - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestShapesMustBeTheSame() + { + await TestMissingAsync( + """ + class Program + { + private static string s_goo; + private static string s_goo2; + private static string Goo => s_goo ?? (s_goo2 = new string('c', 42)); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestShapesMustBeTheSame() - { - await TestMissingAsync( - """ - class Program - { - private static string s_goo; - private static string s_goo2; - private static string Goo => s_goo ?? (s_goo2 = new string('c', 42)); - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestNoSideEffects1() + { + await TestMissingAsync( + """ + class Program + { + private static string s_goo; + private static string Goo => s_goo.GetType() ?? ({|CS0131:s_goo.GetType()|} = new string('c', 42)); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestNoSideEffects1() - { - await TestMissingAsync( - """ - class Program - { - private static string s_goo; - private static string Goo => s_goo.GetType() ?? ({|CS0131:s_goo.GetType()|} = new string('c', 42)); - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestNoSideEffects2() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + private string goo; + private string Goo => this.goo [|??|] (this.goo = new string('c', 42)); + } + """, + """ + class Program + { + private string goo; + private string Goo => this.goo ??= new string('c', 42); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestNoSideEffects2() - { - await TestInRegularAndScriptAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestNullableValueType() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + void Goo() { - private string goo; - private string Goo => this.goo [|??|] (this.goo = new string('c', 42)); + int? a = null; + var x = a [|??|] (a = 1); } - """, - """ - class Program + } + """, + """ + class Program + { + void Goo() { - private string goo; - private string Goo => this.goo ??= new string('c', 42); + int? a = null; + var x = (int?)(a ??= 1); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestNullableValueType() - { - await TestInRegularAndScriptAsync( - """ - class Program - { - void Goo() - { - int? a = null; - var x = a [|??|] (a = 1); - } - } - """, - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestCastIfWouldAffectSemantics() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void M(int a) { } + static void M(int? a) { } + + static void Main() { - void Goo() - { - int? a = null; - var x = (int?)(a ??= 1); - } + int? a = null; + M(a [|??|] (a = 1)); } - """); - } + } + """, + """ + using System; + class C + { + static void M(int a) { } + static void M(int? a) { } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestCastIfWouldAffectSemantics() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + static void Main() { - static void M(int a) { } - static void M(int? a) { } - - static void Main() - { - int? a = null; - M(a [|??|] (a = 1)); - } + int? a = null; + M((int?)(a ??= 1)); } - """, - """ - using System; - class C - { - static void M(int a) { } - static void M(int? a) { } + } + """); + } - static void Main() - { - int? a = null; - M((int?)(a ??= 1)); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] + public async Task TestDoNotCastIfNotNecessary() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void M(int? a) { } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38059")] - public async Task TestDoNotCastIfNotNecessary() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + static void Main() { - static void M(int? a) { } - - static void Main() - { - int? a = null; - M(a [|??|] (a = 1)); - } + int? a = null; + M(a [|??|] (a = 1)); } - """, - """ - using System; - class C - { - static void M(int? a) { } + } + """, + """ + using System; + class C + { + static void M(int? a) { } - static void Main() - { - int? a = null; - M(a ??= 1); - } + static void Main() + { + int? a = null; + M(a ??= 1); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement1() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement1() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (o is null) { - [|if|] (o is null) - { - o = ""; - } + o = ""; } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_NotBeforeCSharp8() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_NotBeforeCSharp8() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - o = ""; - } + o = ""; } } - """, LanguageVersion.CSharp7_3); - } + } + """, LanguageVersion.CSharp7_3); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_NotWithElseClause() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_NotWithElseClause() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - o = ""; - } - else - { - Console.WriteLine(); - } + o = ""; + } + else + { + Console.WriteLine(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatementWithoutBlock() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatementWithoutBlock() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - [|if|] (o is null) - o = ""; - } + [|if|] (o is null) + o = ""; } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_WithEmptyBlock() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_WithEmptyBlock() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_WithMultipleStatements() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_WithMultipleStatements() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - o = ""; - o = ""; - } + o = ""; + o = ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_EqualsEqualsCheck() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_EqualsEqualsCheck() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (o == null) { - [|if|] (o == null) - { - o = ""; - } + o = ""; } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_ReferenceEqualsCheck1() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_ReferenceEqualsCheck1() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (ReferenceEquals(o, null)) { - [|if|] (ReferenceEquals(o, null)) - { - o = ""; - } + o = ""; } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_ReferenceEqualsCheck2() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_ReferenceEqualsCheck2() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (ReferenceEquals(null, o)) { - [|if|] (ReferenceEquals(null, o)) - { - o = ""; - } + o = ""; } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_ReferenceEqualsCheck3() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_ReferenceEqualsCheck3() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (object.ReferenceEquals(null, o)) { - [|if|] (object.ReferenceEquals(null, o)) - { - o = ""; - } + o = ""; } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_ReferenceEqualsCheck4() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_ReferenceEqualsCheck4() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (!object.ReferenceEquals(null, o)) { - if (!object.ReferenceEquals(null, o)) - { - o = ""; - } + o = ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_NotSimpleAssignment() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_NotSimpleAssignment() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - o ??= ""; - } + o ??= ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_OverloadedEquals_OkForString() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_OverloadedEquals_OkForString() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(string o) { - static void Main(string o) + [|if|] (o == null) { - [|if|] (o == null) - { - o = ""; - } + o = ""; } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(string o) { - static void Main(string o) - { - o ??= ""; - } + o ??= ""; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_OverloadedEquals() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_OverloadedEquals() + { + await TestMissingAsync( + """ + using System; - class X - { - public static bool operator ==(X x1, X x2) => true; - public static bool operator !=(X x1, X x2) => !(x1 == x2); - } + class X + { + public static bool operator ==(X x1, X x2) => true; + public static bool operator !=(X x1, X x2) => !(x1 == x2); + } - class C + class C + { + static void Main(X o) { - static void Main(X o) + if (o == null) { - if (o == null) - { - o = new X(); - } + o = new X(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_AssignmentToDifferentValue() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_AssignmentToDifferentValue() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + static void Main(object o1, object o2) { - static void Main(object o1, object o2) + if (o1 is null) { - if (o1 is null) - { - o2 = ""; - } + o2 = ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_SideEffects1() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_SideEffects1() + { + await TestMissingAsync( + """ + using System; - class C - { - private object o; + class C + { + private object o; - static void Main() + static void Main() + { + if (new C().o is null) { - if (new C().o is null) - { - new C().o = ""; - } + new C().o = ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_SideEffects2() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_SideEffects2() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (o is null) { - [|if|] (o is null) - { - o = new C(); - } + o = new C(); } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - o ??= new C(); - } + o ??= new C(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_Trivia1() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_Trivia1() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + // Before + [|if|] (o is null) { - // Before - [|if|] (o is null) - { - o = new C(); - } // After - } + o = new C(); + } // After } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - // Before - o ??= new C(); // After - } + // Before + o ??= new C(); // After } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_Trivia2() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_Trivia2() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + [|if|] (o is null) { - [|if|] (o is null) - { - // Before - o = new C(); // After - } + // Before + o = new C(); // After } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - // Before - o ??= new C(); // After - } + // Before + o ??= new C(); // After } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] - public async Task TestIfStatement_Trivia3() - { - await TestInRegularAndScriptAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32985")] + public async Task TestIfStatement_Trivia3() + { + await TestInRegularAndScriptAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + // Before1 + [|if|] (o is null) { - // Before1 - [|if|] (o is null) - { - // Before2 - o = new C(); // After - } + // Before2 + o = new C(); // After } } - """, - """ - using System; - class C + } + """, + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - // Before1 - // Before2 - o ??= new C(); // After - } + // Before1 + // Before2 + o ??= new C(); // After } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock1() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock1() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - #if true - o = ""; - #endif - } + #if true + o = ""; + #endif } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock2() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock2() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - #if X - Console.WriteLine("Only run if o is null"); - #endif - o = ""; - } + #if X + Console.WriteLine("Only run if o is null"); + #endif + o = ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock3() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock3() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - #if X - Console.WriteLine("Only run if o is null"); - #else - o = ""; - #endif - } + #if X + Console.WriteLine("Only run if o is null"); + #else + o = ""; + #endif } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock4() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock4() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - #if X - Console.WriteLine("Only run if o is null"); - #elif true - o = ""; - #endif - } + #if X + Console.WriteLine("Only run if o is null"); + #elif true + o = ""; + #endif } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock5() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock5() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - #if true - o = ""; - #else - Console.WriteLine("Only run if o is null"); - #endif - } + #if true + o = ""; + #else + Console.WriteLine("Only run if o is null"); + #endif } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock6() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock6() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) + if (o is null) { - if (o is null) - { - #if true - o = ""; - #elif X - Console.WriteLine("Only run if o is null"); - #endif - } + #if true + o = ""; + #elif X + Console.WriteLine("Only run if o is null"); + #endif } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock7() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock7() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - if (o is null) - #if true - o = ""; - #endif - } + if (o is null) + #if true + o = ""; + #endif } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] - public async Task TestIfStatementWithPreprocessorBlock8() - { - await TestMissingAsync( - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63552")] + public async Task TestIfStatementWithPreprocessorBlock8() + { + await TestMissingAsync( + """ + using System; + class C + { + static void Main(object o) { - static void Main(object o) - { - if (o is null) - #if true - o = ""; - #else - o = ""; - #endif - } + if (o is null) + #if true + o = ""; + #else + o = ""; + #endif } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62473")] - public async Task TestPointerCannotUseCoalesceAssignment() - { - // The purpose of this test is to keep track of whether the language - // allows ??= for pointers in future. It should be kept in 'Preview'. - // If the test failed because language added support and this is no longer - // an error. The behavior for test 'TestPointer' below should be updated as well to suggest ??= - // Note that, when ??= is supported for pointers, the analyzer should check the language version which supports it. - await TestMissingAsync(""" - unsafe class Program - { - private static void Main() - { - byte* ptr = null; - {|CS0019:ptr ??= Get()|}; - } + } + """); + } - static byte* Get() => null; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62473")] + public async Task TestPointerCannotUseCoalesceAssignment() + { + // The purpose of this test is to keep track of whether the language + // allows ??= for pointers in future. It should be kept in 'Preview'. + // If the test failed because language added support and this is no longer + // an error. The behavior for test 'TestPointer' below should be updated as well to suggest ??= + // Note that, when ??= is supported for pointers, the analyzer should check the language version which supports it. + await TestMissingAsync(""" + unsafe class Program + { + private static void Main() + { + byte* ptr = null; + {|CS0019:ptr ??= Get()|}; } - """, LanguageVersion.CSharp12); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62473")] - public async Task TestPointer() - { - await TestMissingAsync(""" - unsafe class Program + static byte* Get() => null; + } + """, LanguageVersion.CSharp12); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/62473")] + public async Task TestPointer() + { + await TestMissingAsync(""" + unsafe class Program + { + private static void Main() { - private static void Main() + byte* ptr = null; + if (ptr is null) { - byte* ptr = null; - if (ptr is null) - { - ptr = Get(); - } + ptr = Get(); } - - static byte* Get() => null; } - """, LanguageVersion.CSharp12); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63551")] - public async Task TestFunctionPointer() - { - await TestMissingAsync(""" - using System.Runtime.InteropServices; - public unsafe class C { - [DllImport("A")] - private static extern delegate* unmanaged GetFunc(); - - private delegate* unmanaged s_func; - - public delegate* unmanaged M() { - delegate* unmanaged func = s_func; - if (func == null) - { - func = s_func = GetFunc(); - } - return func; + static byte* Get() => null; + } + """, LanguageVersion.CSharp12); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63551")] + public async Task TestFunctionPointer() + { + await TestMissingAsync(""" + using System.Runtime.InteropServices; + public unsafe class C { + [DllImport("A")] + private static extern delegate* unmanaged GetFunc(); + + private delegate* unmanaged s_func; + + public delegate* unmanaged M() { + delegate* unmanaged func = s_func; + if (func == null) + { + func = s_func = GetFunc(); } + return func; } - """, LanguageVersion.CSharp12); - } + } + """, LanguageVersion.CSharp12); } } diff --git a/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForAssignmentTests.cs b/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForAssignmentTests.cs index cabf22483c332..b390f823c05cb 100644 --- a/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForAssignmentTests.cs +++ b/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForAssignmentTests.cs @@ -12,2095 +12,2094 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseConditionalExpression -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseConditionalExpressionForAssignmentDiagnosticAnalyzer, - CSharpUseConditionalExpressionForAssignmentCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseConditionalExpression; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)] - public partial class UseConditionalExpressionForAssignmentTests - { - private static async Task TestMissingAsync( - string testCode, - LanguageVersion languageVersion = LanguageVersion.CSharp8, - OptionsCollection? options = null) - { - var test = new VerifyCS.Test - { - TestCode = testCode, - FixedCode = testCode, - LanguageVersion = languageVersion, - Options = { options }, - }; - - await test.RunAsync(); - } - - private static async Task TestInRegularAndScript1Async( - string testCode, - string fixedCode, - LanguageVersion languageVersion = LanguageVersion.CSharp8, - OptionsCollection? options = null, - string? equivalenceKey = null) - { - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = languageVersion, - CodeActionEquivalenceKey = equivalenceKey, - Options = { options }, - }.RunAsync(); - } +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseConditionalExpressionForAssignmentDiagnosticAnalyzer, + CSharpUseConditionalExpressionForAssignmentCodeFixProvider>; - private static readonly OptionsCollection PreferImplicitTypeAlways = new(LanguageNames.CSharp) +[Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)] +public partial class UseConditionalExpressionForAssignmentTests +{ + private static async Task TestMissingAsync( + string testCode, + LanguageVersion languageVersion = LanguageVersion.CSharp8, + OptionsCollection? options = null) + { + var test = new VerifyCS.Test { - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, CodeStyleOption2.TrueWithSilentEnforcement }, - { CSharpCodeStyleOptions.VarElsewhere, CodeStyleOption2.TrueWithSilentEnforcement }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, CodeStyleOption2.TrueWithSilentEnforcement }, + TestCode = testCode, + FixedCode = testCode, + LanguageVersion = languageVersion, + Options = { options }, }; - [Fact] - public async Task TestOnSimpleAssignment() - { - await TestInRegularAndScript1Async( - """ - class C + await test.RunAsync(); + } + + private static async Task TestInRegularAndScript1Async( + string testCode, + string fixedCode, + LanguageVersion languageVersion = LanguageVersion.CSharp8, + OptionsCollection? options = null, + string? equivalenceKey = null) + { + await new VerifyCS.Test + { + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = languageVersion, + CodeActionEquivalenceKey = equivalenceKey, + Options = { options }, + }.RunAsync(); + } + + private static readonly OptionsCollection PreferImplicitTypeAlways = new(LanguageNames.CSharp) + { + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, CodeStyleOption2.TrueWithSilentEnforcement }, + { CSharpCodeStyleOptions.VarElsewhere, CodeStyleOption2.TrueWithSilentEnforcement }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, CodeStyleOption2.TrueWithSilentEnforcement }, + }; + + [Fact] + public async Task TestOnSimpleAssignment() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + [|if|] (true) { - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + i = 0; } - } - """, - """ - class C - { - void M(int i) + else { - i = true ? 0 : 1; + i = 1; } } - """); - } + } + """, + """ + class C + { + void M(int i) + { + i = true ? 0 : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnSimpleAssignment_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnSimpleAssignment_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + [|if|] (true) { - [|if|] (true) - { - throw new System.Exception(); - } - else - { - i = 1; - } + throw new System.Exception(); } - } - """, - """ - class C - { - void M(int i) + else { - i = true ? throw new System.Exception() : 1; + i = 1; } } - """); - } + } + """, + """ + class C + { + void M(int i) + { + i = true ? throw new System.Exception() : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnSimpleAssignment_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnSimpleAssignment_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + [|if|] (true) { - [|if|] (true) - { - i = 0; - } - else - { - throw new System.Exception(); - } + i = 0; } - } - """, - """ - class C - { - void M(int i) + else { - i = true ? 0 : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + void M(int i) + { + i = true ? 0 : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotWithTwoThrows() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotWithTwoThrows() + { + await TestMissingAsync( + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - if (true) - { - throw new System.Exception(); - } - else - { - throw new System.Exception(); - } + throw new System.Exception(); + } + else + { + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotOnSimpleAssignment_Throw1_CSharp6() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotOnSimpleAssignment_Throw1_CSharp6() + { + await TestMissingAsync( + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - if (true) - { - throw new System.Exception(); - } - else - { - i = 1; - } + throw new System.Exception(); + } + else + { + i = 1; } } - """, LanguageVersion.CSharp6); - } + } + """, LanguageVersion.CSharp6); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestWithSimpleThrow() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestWithSimpleThrow() + { + await TestMissingAsync( + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - if (true) - { - {|CS0156:throw|}; - } - else - { - i = 1; - } + {|CS0156:throw|}; + } + else + { + i = 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestOnSimpleAssignmentNoBlocks() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnSimpleAssignmentNoBlocks() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) - { + [|if|] (true) + i = 0; + else + i = 1; + } + } + """, + """ + class C + { + void M(int i) + { + i = true ? 0 : 1; + } + } + """); + } + + [Fact] + public async Task TestOnSimpleAssignmentNoBlocks_NotInBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) + { + if (true) [|if|] (true) i = 0; else i = 1; - } } - """, - """ - class C + } + """, + """ + class C + { + void M(int i) { - void M(int i) - { + if (true) i = true ? 0 : 1; - } } - """); - } + } + """); + } - [Fact] - public async Task TestOnSimpleAssignmentNoBlocks_NotInBlock() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestNotOnSimpleAssignmentToDifferentTargets() + { + await TestMissingAsync( + """ + class C + { + void M(int i, int j) { - void M(int i) + if (true) { - if (true) - [|if|] (true) - i = 0; - else - i = 1; + i = 0; } - } - """, - """ - class C - { - void M(int i) + else { - if (true) - i = true ? 0 : 1; + j = 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnSimpleAssignmentToDifferentTargets() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestOnAssignmentToUndefinedField() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M(int i, int j) + [|if|] (true) { - if (true) - { - i = 0; - } - else - { - j = 1; - } + this.{|CS1061:i|} = 0; } + else + { + this.{|CS1061:i|} = 1; + } + } + } + """, + """ + class C + { + void M() + { + this.{|CS1061:i|} = true ? 0 : 1; } - """); - } + } + """); + } - [Fact] - public async Task TestOnAssignmentToUndefinedField() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnAssignmentToUndefinedField_Throw() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|if|] (true) { - [|if|] (true) - { - this.{|CS1061:i|} = 0; - } - else - { - this.{|CS1061:i|} = 1; - } + this.{|CS1061:i|} = 0; } - } - """, - """ - class C - { - void M() + else { - this.{|CS1061:i|} = true ? 0 : 1; + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + void M() + { + this.{|CS1061:i|} = true ? 0 : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnAssignmentToUndefinedField_Throw() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnNonUniformTargetSyntax() + { + await TestInRegularAndScript1Async( + """ + class C + { + private int i; + + void M() { - void M() + [|if|] (true) { - [|if|] (true) - { - this.{|CS1061:i|} = 0; - } - else - { - throw new System.Exception(); - } + this.i = 0; } - } - """, - """ - class C - { - void M() + else { - this.{|CS1061:i|} = true ? 0 : throw new System.Exception(); + this . i = 1; } } - """); - } + } + """, + """ + class C + { + private int i; - [Fact] - public async Task TestOnNonUniformTargetSyntax() - { - await TestInRegularAndScript1Async( - """ - class C + void M() { - private int i; + this.i = true ? 0 : 1; + } + } + """); + } + + [Fact] + public async Task TestOnAssignmentToDefinedField() + { + await TestInRegularAndScript1Async( + """ + class C + { + int i; - void M() + void M() + { + [|if|] (true) { - [|if|] (true) - { - this.i = 0; - } - else - { - this . i = 1; - } + this.i = 0; + } + else + { + this.i = 1; } } - """, - """ - class C + } + """, + """ + class C + { + int i; + + void M() { - private int i; + this.i = true ? 0 : 1; + } + } + """); + } - void M() + [Fact] + public async Task TestOnAssignmentToAboveLocalNoInitializer() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + int i; + [|if|] (true) { - this.i = true ? 0 : 1; + i = 0; } + else + { + i = 1; + } + } + } + """, + """ + class C + { + void M() + { + int i = true ? 0 : 1; } - """); - } + } + """); + } - [Fact] - public async Task TestOnAssignmentToDefinedField() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnAssignmentToAboveLocalNoInitializer_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { int i; - - void M() + [|if|] (true) { - [|if|] (true) - { - this.i = 0; - } - else - { - this.i = 1; - } + i = 0; + } + else + { + throw new System.Exception(); } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - int i; + int i = true ? 0 : throw new System.Exception(); + } + } + """); + } - void M() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnAssignmentToAboveLocalNoInitializer_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + int i; + [|if|] (true) { - this.i = true ? 0 : 1; + throw new System.Exception(); + } + else + { + i = 1; } } - """); - } + } + """, + """ + class C + { + void M() + { + int i = true ? throw new System.Exception() : 1; + } + } + """); + } - [Fact] - public async Task TestOnAssignmentToAboveLocalNoInitializer() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnAssignmentToAboveLocalLiteralInitializer() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int i = 0; + [|if|] (true) { - int i; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + i = 0; } - } - """, - """ - class C - { - void M() + else { - int i = true ? 0 : 1; + i = 1; } } - """); - } + } + """, + """ + class C + { + void M() + { + int i = true ? 0 : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnAssignmentToAboveLocalNoInitializer_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnAssignmentToAboveLocalDefaultLiteralInitializer() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int i = default; + [|if|] (true) { - int i; - [|if|] (true) - { - i = 0; - } - else - { - throw new System.Exception(); - } + i = 0; } - } - """, - """ - class C - { - void M() + else { - int i = true ? 0 : throw new System.Exception(); + i = 1; } } - """); - } + } + """, + """ + class C + { + void M() + { + int i = true ? 0 : 1; + } + } + """, LanguageVersion.Latest); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnAssignmentToAboveLocalNoInitializer_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnAssignmentToAboveLocalDefaultExpressionInitializer() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int i = default(int); + [|if|] (true) { - int i; - [|if|] (true) - { - throw new System.Exception(); - } - else - { - i = 1; - } + i = 0; + } + else + { + i = 1; } } - """, - """ - class C + } + """, + """ + class C + { + void M() + { + int i = true ? 0 : 1; + } + } + """); + } + + [Fact] + public async Task TestDoNotMergeAssignmentToAboveLocalWithComplexInitializer() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int i = Foo(); + [|if|] (true) { - int i = true ? throw new System.Exception() : 1; + i = 0; + } + else + { + i = 1; } } - """); - } - [Fact] - public async Task TestOnAssignmentToAboveLocalLiteralInitializer() - { - await TestInRegularAndScript1Async( - """ - class C + int Foo() => 0; + } + """, + """ + class C + { + void M() + { + int i = Foo(); + i = true ? 0 : 1; + } + + int Foo() => 0; + } + """); + } + + [Fact] + public async Task TestDoNotMergeAssignmentToAboveLocalIfIntermediaryStatement() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() { - void M() + int i = 0; + Console.WriteLine(); + [|if|] (true) { - int i = 0; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + i = 0; + } + else + { + i = 1; } } - """, - """ - class C + } + """, + """ + using System; + + class C + { + void M() { - void M() + int i = 0; + Console.WriteLine(); + i = true ? 0 : 1; + } + } + """); + } + + [Fact] + public async Task TestDoNotMergeAssignmentToAboveIfLocalUsedInIfCondition() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + int i = 0; + [|if|] (Bar(i)) { - int i = true ? 0 : 1; + i = 0; + } + else + { + i = 1; } } - """); - } - [Fact] - public async Task TestOnAssignmentToAboveLocalDefaultLiteralInitializer() - { - await TestInRegularAndScript1Async( - """ - class C + bool Bar(int i) => true; + } + """, + """ + class C + { + void M() { - void M() + int i = 0; + i = Bar(i) ? 0 : 1; + } + + bool Bar(int i) => true; + } + """); + } + + [Fact] + public async Task TestDoNotMergeAssignmentToAboveIfMultiDecl() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + int i = 0, j = 0; + [|if|] (true) { - int i = default; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + i = 0; + } + else + { + i = 1; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + int i = 0, j = 0; + i = true ? 0 : 1; + } + } + """); + } + + [Fact] + public async Task TestUseImplicitTypeForIntrinsicTypes() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() + { + int i = 0; + [|if|] (true) + { + i = 0; + } + else { - int i = true ? 0 : 1; + i = 1; } } - """, LanguageVersion.Latest); - } + } + """, + """ + class C + { + void M() + { + var i = true ? 0 : 1; + } + } + """, options: new OptionsCollection(LanguageNames.CSharp) { { CSharpCodeStyleOptions.VarForBuiltInTypes, CodeStyleOption2.TrueWithSilentEnforcement } }); + } - [Fact] - public async Task TestOnAssignmentToAboveLocalDefaultExpressionInitializer() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestUseImplicitTypeWhereApparent() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int i = 0; + [|if|] (true) + { + i = 0; + } + else { - int i = default(int); - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + i = 1; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int i = true ? 0 : 1; - } + int i = true ? 0 : 1; } - """); - } + } + """, options: new OptionsCollection(LanguageNames.CSharp) { { CSharpCodeStyleOptions.VarWhenTypeIsApparent, CodeStyleOption2.TrueWithSilentEnforcement } }); + } - [Fact] - public async Task TestDoNotMergeAssignmentToAboveLocalWithComplexInitializer() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestUseImplicitTypeWherePossible() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + int i = 0; + [|if|] (true) { - int i = Foo(); - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + i = 0; } - - int Foo() => 0; - } - """, - """ - class C - { - void M() + else { - int i = Foo(); - i = true ? 0 : 1; + i = 1; } - - int Foo() => 0; } - """); - } - - [Fact] - public async Task TestDoNotMergeAssignmentToAboveLocalIfIntermediaryStatement() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C + } + """, + """ + class C + { + void M() { - void M() - { - int i = 0; - Console.WriteLine(); - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } - } + int i = true ? 0 : 1; } - """, - """ - using System; + } + """, options: new OptionsCollection(LanguageNames.CSharp) { { CSharpCodeStyleOptions.VarElsewhere, CodeStyleOption2.TrueWithSilentEnforcement } }); + } - class C + [Fact] + public async Task TestMissingWithoutElse() + { + await TestMissingAsync( + """ + class C + { + void M(int i) { - void M() + if (true) { - int i = 0; - Console.WriteLine(); - i = true ? 0 : 1; + i = 0; } } - """); - } + } + """); + } - [Fact] - public async Task TestDoNotMergeAssignmentToAboveIfLocalUsedInIfCondition() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestMissingWithoutElseWithStatementAfterwards() + { + await TestMissingAsync( + """ + class C + { + void M(int i) { - void M() + if (true) { - int i = 0; - [|if|] (Bar(i)) - { - i = 0; - } - else - { - i = 1; - } + i = 0; } - bool Bar(int i) => true; + i = 1; } - """, - """ - class C + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestMissingWithoutElseWithThrowStatementAfterwards() + { + await TestMissingAsync( + """ + class C + { + void M(int i) { - void M() + if (true) { - int i = 0; - i = Bar(i) ? 0 : 1; + i = 0; } - bool Bar(int i) => true; + throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestDoNotMergeAssignmentToAboveIfMultiDecl() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + // cast will be necessary, otherwise 'var' would get the type 'string'. + object o; + [|if|] (true) { - int i = 0, j = 0; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + o = "a"; } - } - """, - """ - class C - { - void M() + else { - int i = 0, j = 0; - i = true ? 0 : 1; + o = "b"; } } - """); - } + } + """, + """ + class C + { + void M() + { + // cast will be necessary, otherwise 'var' would get the type 'string'. + var o = true ? "a" : (object)"b"; + } + } + """, options: PreferImplicitTypeAlways); + } - [Fact] - public async Task TestUseImplicitTypeForIntrinsicTypes() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw1_CSharp8() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + object o; + [|if|] (true) { - int i = 0; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + throw new System.Exception(); } - } - """, - """ - class C - { - void M() + else { - var i = true ? 0 : 1; + o = "b"; } } - """, options: new OptionsCollection(LanguageNames.CSharp) { { CSharpCodeStyleOptions.VarForBuiltInTypes, CodeStyleOption2.TrueWithSilentEnforcement } }); - } + } + """, + """ + class C + { + void M() + { + var o = true ? throw new System.Exception() : (object)"b"; + } + } + """, LanguageVersion.CSharp8, PreferImplicitTypeAlways); + } - [Fact] - public async Task TestUseImplicitTypeWhereApparent() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw1_CSharp9() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + object o; + [|if|] (true) { - int i = 0; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + throw new System.Exception(); } - } - """, - """ - class C - { - void M() + else { - int i = true ? 0 : 1; + o = "b"; } } - """, options: new OptionsCollection(LanguageNames.CSharp) { { CSharpCodeStyleOptions.VarWhenTypeIsApparent, CodeStyleOption2.TrueWithSilentEnforcement } }); - } + } + """, + """ + class C + { + void M() + { + var o = true ? throw new System.Exception() : (object)"b"; + } + } + """, LanguageVersion.CSharp9, options: PreferImplicitTypeAlways); + } - [Fact] - public async Task TestUseImplicitTypeWherePossible() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + object o; + [|if|] (true) { - int i = 0; - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } + o = "a"; } - } - """, - """ - class C - { - void M() + else { - int i = true ? 0 : 1; + throw new System.Exception(); } } - """, options: new OptionsCollection(LanguageNames.CSharp) { { CSharpCodeStyleOptions.VarElsewhere, CodeStyleOption2.TrueWithSilentEnforcement } }); - } - - [Fact] - public async Task TestMissingWithoutElse() - { - await TestMissingAsync( - """ - class C + } + """, + """ + class C + { + void M() { - void M(int i) - { - if (true) - { - i = 0; - } - } + var o = true ? (object)"a" : throw new System.Exception(); } - """); - } + } + """, options: PreferImplicitTypeAlways); + } - [Fact] - public async Task TestMissingWithoutElseWithStatementAfterwards() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M(int i) + string s; + [|if|] (true) { - if (true) - { - i = 0; - } - - i = 1; + s = "a"; + } + else + { + s = null; } } - """); - } + } + """, + """ + class C + { + void M() + { + var s = true ? "a" : null; + } + } + """, options: PreferImplicitTypeAlways); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestMissingWithoutElseWithThrowStatementAfterwards() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M(int i) + string s; + [|if|] (true) { - if (true) - { - i = 0; - } - throw new System.Exception(); } - } - """); - } - - [Fact] - public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M() + else { - // cast will be necessary, otherwise 'var' would get the type 'string'. - object o; - [|if|] (true) - { - o = "a"; - } - else - { - o = "b"; - } + s = null; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - // cast will be necessary, otherwise 'var' would get the type 'string'. - var o = true ? "a" : (object)"b"; - } + var s = true ? throw new System.Exception() : (string)null; } - """, options: PreferImplicitTypeAlways); - } + } + """, options: PreferImplicitTypeAlways); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw1_CSharp8() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + string s; + [|if|] (true) { - object o; - [|if|] (true) - { - throw new System.Exception(); - } - else - { - o = "b"; - } + s = "a"; } - } - """, - """ - class C - { - void M() + else { - var o = true ? throw new System.Exception() : (object)"b"; + throw new System.Exception(); } } - """, LanguageVersion.CSharp8, PreferImplicitTypeAlways); - } + } + """, + """ + class C + { + void M() + { + var s = true ? "a" : throw new System.Exception(); + } + } + """, options: PreferImplicitTypeAlways); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw1_CSharp9() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestConversionWithUseVarForAll_CanUseVarButRequiresCastOfConditionalBranch_CSharp8() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + string s; + [|if|] (true) { - object o; - [|if|] (true) - { - throw new System.Exception(); - } - else - { - o = "b"; - } + s = null; } - } - """, - """ - class C - { - void M() + else { - var o = true ? throw new System.Exception() : (object)"b"; + s = null; } } - """, LanguageVersion.CSharp9, options: PreferImplicitTypeAlways); - } + } + """, + """ + class C + { + void M() + { + var s = true ? null : (string)null; + } + } + """, LanguageVersion.CSharp8, PreferImplicitTypeAlways); + } - [Fact] - public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestConversionWithUseVarForAll_CanUseVarButRequiresCastOfConditionalBranch_CSharp9() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + string s; + [|if|] (true) { - object o; - [|if|] (true) - { - o = "a"; - } - else - { - throw new System.Exception(); - } + s = null; } - } - """, - """ - class C - { - void M() + else { - var o = true ? (object)"a" : throw new System.Exception(); + s = null; } } - """, options: PreferImplicitTypeAlways); - } + } + """, + """ + class C + { + void M() + { + var s = true ? null : (string)null; + } + } + """, LanguageVersion.CSharp9, options: PreferImplicitTypeAlways); + } - [Fact] - public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestKeepTriviaAroundIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M() + // leading + [|if|] (true) { - string s; - [|if|] (true) - { - s = "a"; - } - else - { - s = null; - } + i = 0; } + else + { + i = 1; + } // trailing } - """, - """ - class C + } + """, + """ + class C + { + void M(int i) { - void M() - { - var s = true ? "a" : null; - } + // leading + i = true ? 0 : 1; // trailing } - """, options: PreferImplicitTypeAlways); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M() + [|if|] (true) { - string s; - [|if|] (true) - { - throw new System.Exception(); - } - else - { - s = null; - } + i = 0; } - } - """, - """ - class C - { - void M() + else { - var s = true ? throw new System.Exception() : (string)null; + i = 1; } - } - """, options: PreferImplicitTypeAlways); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M() + string s; + [|if|] (true) { - string s; - [|if|] (true) - { - s = "a"; - } - else - { - throw new System.Exception(); - } + s = "a"; } - } - """, - """ - class C - { - void M() + else { - var s = true ? "a" : throw new System.Exception(); + s = "b"; } } - """, options: PreferImplicitTypeAlways); - } + } + """, + """ + class C + { + void M(int i) + { + i = true ? 0 : 1; + + string s = true ? "a" : "b"; + } + } + """); + } - [Fact] - public async Task TestConversionWithUseVarForAll_CanUseVarButRequiresCastOfConditionalBranch_CSharp8() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestMultiLine1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M() + [|if|] (true) { - string s; - [|if|] (true) - { - s = null; - } - else - { - s = null; - } + i = Foo( + 1, 2, 3); } - } - """, - """ - class C - { - void M() + else { - var s = true ? null : (string)null; + i = 1; } } - """, LanguageVersion.CSharp8, PreferImplicitTypeAlways); - } - [Fact] - public async Task TestConversionWithUseVarForAll_CanUseVarButRequiresCastOfConditionalBranch_CSharp9() - { - await TestInRegularAndScript1Async( - """ - class C + int Foo(int x, int y, int z) => 0; + } + """, + """ + class C + { + void M(int i) { - void M() - { - string s; - [|if|] (true) - { - s = null; - } - else - { - s = null; - } - } + i = true + ? Foo( + 1, 2, 3) + : 1; } - """, - """ - class C + + int Foo(int x, int y, int z) => 0; + } + """); + } + + [Fact] + public async Task TestMultiLine2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M() + [|if|] (true) + { + i = 0; + } + else { - var s = true ? null : (string)null; + i = Foo( + 1, 2, 3); } } - """, LanguageVersion.CSharp9, options: PreferImplicitTypeAlways); - } - [Fact] - public async Task TestKeepTriviaAroundIf() - { - await TestInRegularAndScript1Async( - """ - class C + int Foo(int x, int y, int z) => 0; + } + """, + """ + class C + { + void M(int i) { - void M(int i) - { - // leading - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } // trailing - } + i = true + ? 0 + : Foo( + 1, 2, 3); } - """, - """ - class C + + int Foo(int x, int y, int z) => 0; + } + """); + } + + [Fact] + public async Task TestMultiLine3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + [|if|] (true) + { + i = Foo( + 1, 2, 3); + } + else { - // leading - i = true ? 0 : 1; // trailing + i = Foo( + 4, 5, 6); } } - """); - } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - class C + int Foo(int x, int y, int z) => 0; + } + """, + """ + class C + { + void M(int i) { - void M(int i) - { - [|if|] (true) - { - i = 0; - } - else - { - i = 1; - } - - string s; - [|if|] (true) - { - s = "a"; - } - else - { - s = "b"; - } - } + i = true + ? Foo( + 1, 2, 3) + : Foo( + 4, 5, 6); } - """, - """ - class C + + int Foo(int x, int y, int z) => 0; + } + """); + } + + [Fact] + public async Task TestElseIfWithBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + if (true) + { + } + else [|if|] (false) + { + i = 1; + } + else { - i = true ? 0 : 1; - - string s = true ? "a" : "b"; + i = 0; } } - """); - } - - [Fact] - public async Task TestMultiLine1() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - [|if|] (true) - { - i = Foo( - 1, 2, 3); - } - else - { - i = 1; - } } - - int Foo(int x, int y, int z) => 0; - } - """, - """ - class C - { - void M(int i) + else { - i = true - ? Foo( - 1, 2, 3) - : 1; + i = false ? 1 : 0; } - - int Foo(int x, int y, int z) => 0; } - """); - } + } + """); + } - [Fact] - public async Task TestMultiLine2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestElseIfWithBlock_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - [|if|] (true) - { - i = 0; - } - else - { - i = Foo( - 1, 2, 3); - } } - - int Foo(int x, int y, int z) => 0; - } - """, - """ - class C - { - void M(int i) + else [|if|] (false) { - i = true - ? 0 - : Foo( - 1, 2, 3); + throw new System.Exception(); } - - int Foo(int x, int y, int z) => 0; - } - """); - } - - [Fact] - public async Task TestMultiLine3() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(int i) + else { - [|if|] (true) - { - i = Foo( - 1, 2, 3); - } - else - { - i = Foo( - 4, 5, 6); - } + i = 0; } - - int Foo(int x, int y, int z) => 0; } - """, - """ - class C + } + """, + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - i = true - ? Foo( - 1, 2, 3) - : Foo( - 4, 5, 6); } - - int Foo(int x, int y, int z) => 0; + else + { + i = false ? throw new System.Exception() : 0; + } } - """); - } + } + """); + } - [Fact] - public async Task TestElseIfWithBlock() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestElseIfWithBlock_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - if (true) - { - } - else [|if|] (false) - { - i = 1; - } - else - { - i = 0; - } } - } - """, - """ - class C - { - void M(int i) + else [|if|] (false) { - if (true) - { - } - else - { - i = false ? 1 : 0; - } + i = 1; } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestElseIfWithBlock_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(int i) - { - if (true) - { - } - else [|if|] (false) - { - throw new System.Exception(); - } - else - { - i = 0; - } + else + { + throw new System.Exception(); } } - """, - """ - class C + } + """, + """ + class C + { + void M(int i) { - void M(int i) + if (true) { - if (true) - { - } - else - { - i = false ? throw new System.Exception() : 0; - } + } + else + { + i = false ? 1 : throw new System.Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestElseIfWithBlock_Throw2() + [Fact] + public async Task TestElseIfWithoutBlock() + { + await new VerifyCS.Test { - await TestInRegularAndScript1Async( - """ - class C + TestCode = """ + class C + { + void M(int i) { - void M(int i) - { - if (true) - { - } - else [|if|] (false) - { - i = 1; - } - else - { - throw new System.Exception(); - } - } + if (true) i = 2; + else [|if|] (false) i = 1; + else i = 0; } - """, - """ - class C + } + """, + FixedCode = """ + class C + { + void M(int i) { - void M(int i) - { - if (true) - { - } - else - { - i = false ? 1 : throw new System.Exception(); - } - } + if (true) i = 2; + else i = false ? 1 : 0; } - """); - } + } + """, + CodeFixTestBehaviors = Testing.CodeFixTestBehaviors.FixOne, + FixedState = + { + ExpectedDiagnostics = + { + // /0/Test0.cs(6,9): hidden IDE0045: 'if' statement can be simplified + VerifyCS.Diagnostic().WithSpan(5, 9, 5, 11).WithSpan(5, 9, 6, 32), + } + } + }.RunAsync(); + } - [Fact] - public async Task TestElseIfWithoutBlock() - { - await new VerifyCS.Test + [Fact] + public async Task TestRefAssignment1() + { + await TestInRegularAndScript1Async( + """ + class C { - TestCode = """ - class C + void M(ref int i, ref int j) { - void M(int i) + ref int x = ref i; + [|if|] (true) { - if (true) i = 2; - else [|if|] (false) i = 1; - else i = 0; + x = ref i; } - } - """, - FixedCode = """ - class C - { - void M(int i) + else { - if (true) i = 2; - else i = false ? 1 : 0; + x = ref j; } } - """, - CodeFixTestBehaviors = Testing.CodeFixTestBehaviors.FixOne, - FixedState = + } + """, + """ + class C + { + void M(ref int i, ref int j) { - ExpectedDiagnostics = - { - // /0/Test0.cs(6,9): hidden IDE0045: 'if' statement can be simplified - VerifyCS.Diagnostic().WithSpan(5, 9, 5, 11).WithSpan(5, 9, 6, 32), - } + ref int x = ref i; + x = ref true ? ref i : ref j; } - }.RunAsync(); - } + } + """); + } - [Fact] - public async Task TestRefAssignment1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestRefAssignment1_Throw1() + { + await TestMissingAsync( + """ + class C + { + void M(ref int i, ref int j) { - void M(ref int i, ref int j) + ref int x = ref i; + if (true) { - ref int x = ref i; - [|if|] (true) - { - x = ref i; - } - else - { - x = ref j; - } + throw new System.Exception(); } - } - """, - """ - class C - { - void M(ref int i, ref int j) + else { - ref int x = ref i; - x = ref true ? ref i : ref j; + x = ref j; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestRefAssignment1_Throw1() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestRefAssignment1_Throw2() + { + await TestMissingAsync( + """ + class C + { + void M(ref int i, ref int j) { - void M(ref int i, ref int j) + ref int x = ref i; + if (true) { - ref int x = ref i; - if (true) - { - throw new System.Exception(); - } - else - { - x = ref j; - } + x = ref i; } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestRefAssignment1_Throw2() - { - await TestMissingAsync( - """ - class C - { - void M(ref int i, ref int j) + else { - ref int x = ref i; - if (true) - { - x = ref i; - } - else - { - throw new System.Exception(); - } + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact] - public async Task TestTrueFalse1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestTrueFalse1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool i, int j) { - void M(bool i, int j) + [|if|] (j == 0) { - [|if|] (j == 0) - { - i = true; - } - else - { - i = false; - } + i = true; } - } - """, - """ - class C - { - void M(bool i, int j) + else { - i = j == 0; + i = false; } } - """); - } + } + """, + """ + class C + { + void M(bool i, int j) + { + i = j == 0; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestTrueFalse_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestTrueFalse_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool i, int j) { - void M(bool i, int j) + [|if|] (j == 0) { - [|if|] (j == 0) - { - i = true; - } - else - { - throw new System.Exception(); - } + i = true; } - } - """, - """ - class C - { - void M(bool i, int j) + else { - i = j == 0 ? true : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + void M(bool i, int j) + { + i = j == 0 ? true : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestTrueFalse_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestTrueFalse_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool i, int j) { - void M(bool i, int j) + [|if|] (j == 0) { - [|if|] (j == 0) - { - throw new System.Exception(); - } - else - { - i = false; - } + throw new System.Exception(); } - } - """, - """ - class C - { - void M(bool i, int j) + else { - i = j == 0 ? throw new System.Exception() : false; + i = false; } } - """); - } + } + """, + """ + class C + { + void M(bool i, int j) + { + i = j == 0 ? throw new System.Exception() : false; + } + } + """); + } - [Fact] - public async Task TestTrueFalse2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestTrueFalse2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool i, int j) { - void M(bool i, int j) + [|if|] (j == 0) { - [|if|] (j == 0) - { - i = false; - } - else - { - i = true; - } + i = false; } - } - """, - """ - class C - { - void M(bool i, int j) + else { - i = j != 0; + i = true; } } - """); - } + } + """, + """ + class C + { + void M(bool i, int j) + { + i = j != 0; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestFalseTrue_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestFalseTrue_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool i, int j) { - void M(bool i, int j) + [|if|] (j == 0) { - [|if|] (j == 0) - { - throw new System.Exception(); - } - else - { - i = true; - } + throw new System.Exception(); } - } - """, - """ - class C - { - void M(bool i, int j) + else { - i = j == 0 ? throw new System.Exception() : true; + i = true; } } - """); - } + } + """, + """ + class C + { + void M(bool i, int j) + { + i = j == 0 ? throw new System.Exception() : true; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestFalseTrue_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestFalseTrue_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(bool i, int j) { - void M(bool i, int j) + [|if|] (j == 0) { - [|if|] (j == 0) - { - i = false; - } - else - { - throw new System.Exception(); - } + i = false; } - } - """, - """ - class C - { - void M(bool i, int j) + else { - i = j == 0 ? false : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + void M(bool i, int j) + { + i = j == 0 ? false : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58898")] - public async Task TestRemoveRedundantCast() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58898")] + public async Task TestRemoveRedundantCast() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Guid? id; + Guid? id; - [|if|] (true) - { - id = Guid.NewGuid(); - } - else - { - id = Guid.Empty; - } + [|if|] (true) + { + id = Guid.NewGuid(); + } + else + { + id = Guid.Empty; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - var id = true ? Guid.NewGuid() : (Guid?)Guid.Empty; - } + var id = true ? Guid.NewGuid() : (Guid?)Guid.Empty; } - """, options: PreferImplicitTypeAlways); - } + } + """, options: PreferImplicitTypeAlways); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33284")] - public async Task TestConditionalWithLambdas() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33284")] + public async Task TestConditionalWithLambdas() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(bool containsHighBits) { - void M(bool containsHighBits) - { - Action write; + Action write; - [|if|] (containsHighBits) - { - write = (char character) => Console.WriteLine(1); - } - else - { - write = (char character) => Console.WriteLine(2); - } + [|if|] (containsHighBits) + { + write = (char character) => Console.WriteLine(1); + } + else + { + write = (char character) => Console.WriteLine(2); } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(bool containsHighBits) { - void M(bool containsHighBits) - { - Action write = containsHighBits ? ((char character) => Console.WriteLine(1)) : ((char character) => Console.WriteLine(2)); - } + Action write = containsHighBits ? ((char character) => Console.WriteLine(1)) : ((char character) => Console.WriteLine(2)); } - """, LanguageVersion.CSharp9); - } + } + """, LanguageVersion.CSharp9); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39260")] - public async Task TestTitleWhenSimplifying() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39260")] + public async Task TestTitleWhenSimplifying() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string node1, string node2) { - void M(string node1, string node2) + bool b; + [|if|] (AreSimilarCore(node1, node2)) { - bool b; - [|if|] (AreSimilarCore(node1, node2)) - { - b = true; - } - else - { - b = false; - } + b = true; } - - private bool AreSimilarCore(string node1, string node2) + else { - throw new NotImplementedException(); + b = false; } } - """, - """ - using System; - class C + private bool AreSimilarCore(string node1, string node2) { - void M(string node1, string node2) - { - bool b = AreSimilarCore(node1, node2); - } - - private bool AreSimilarCore(string node1, string node2) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """, LanguageVersion.CSharp9, equivalenceKey: nameof(AnalyzersResources.Simplify_check)); - } + } + """, + """ + using System; - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/67649")] - [InlineData("int", "int")] - [InlineData("string", "string")] - [InlineData("string", "object")] - [InlineData("object", "string")] - [InlineData("int", "long")] - [InlineData("long", "int")] - public async Task TestForDiscardsWithMatchingOrConvertibleExpressionTypes(string originalFirstType, string originalSecondType) - { - await TestInRegularAndScript1Async($$""" - class MyClass + class C + { + void M(string node1, string node2) { - void M(bool flag) - { - [|if|] (flag) - { - _ = A(); - } - else - { - _ = B(); - } - } + bool b = AreSimilarCore(node1, node2); + } - {{originalFirstType}} A() => default; - {{originalSecondType}} B() => default; + private bool AreSimilarCore(string node1, string node2) + { + throw new NotImplementedException(); } - """, $$""" - class MyClass + } + """, LanguageVersion.CSharp9, equivalenceKey: nameof(AnalyzersResources.Simplify_check)); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/67649")] + [InlineData("int", "int")] + [InlineData("string", "string")] + [InlineData("string", "object")] + [InlineData("object", "string")] + [InlineData("int", "long")] + [InlineData("long", "int")] + public async Task TestForDiscardsWithMatchingOrConvertibleExpressionTypes(string originalFirstType, string originalSecondType) + { + await TestInRegularAndScript1Async($$""" + class MyClass + { + void M(bool flag) { - void M(bool flag) + [|if|] (flag) + { + _ = A(); + } + else { - _ = flag ? A() : B(); + _ = B(); } - - {{originalFirstType}} A() => default; - {{originalSecondType}} B() => default; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67649")] - public async Task TestMissingForDiscardsWithDifferentTypes() - { - await TestMissingAsync(""" - class MyClass + {{originalFirstType}} A() => default; + {{originalSecondType}} B() => default; + } + """, $$""" + class MyClass + { + void M(bool flag) { - void M(bool flag) - { - if (flag) - { - _ = A(); - } - else - { - _ = B(); - } - } - - int A() => default; - string B() => default; + _ = flag ? A() : B(); } - """); - } + + {{originalFirstType}} A() => default; + {{originalSecondType}} B() => default; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67649")] - public async Task TestMissingForDiscardsWithBothImplicitConversions() - { - await TestMissingAsync(""" - class MyClass + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67649")] + public async Task TestMissingForDiscardsWithDifferentTypes() + { + await TestMissingAsync(""" + class MyClass + { + void M(bool flag) { - void M(bool flag) + if (flag) { - if (flag) - { - _ = GetC(); - } - else - { - _ = GetString(); - } + _ = A(); + } + else + { + _ = B(); } - - C GetC() => new C(); - string GetString() => ""; } + + int A() => default; + string B() => default; + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67649")] + public async Task TestMissingForDiscardsWithBothImplicitConversions() + { + await TestMissingAsync(""" + class MyClass + { + void M(bool flag) { - public static implicit operator C(string c) => new C(); - public static implicit operator string(C c) => ""; + if (flag) + { + _ = GetC(); + } + else + { + _ = GetString(); + } } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68578")] - public async Task TestMissingWhenAssignmentReferencesPatternVariable() - { - await TestMissingAsync(""" - using System; + C GetC() => new C(); + string GetString() => ""; + } - public class Class1 - { - public int i; - } + class C + { + public static implicit operator C(string c) => new C(); + public static implicit operator string(C c) => ""; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68578")] + public async Task TestMissingWhenAssignmentReferencesPatternVariable() + { + await TestMissingAsync(""" + using System; + + public class Class1 + { + public int i; + } - public class Program + public class Program + { + public static void Test(object obj) { - public static void Test(object obj) + if (obj is Class1 c) { - if (obj is Class1 c) - { - c.i = 1; - } - else - { - throw new Exception(); - } + c.i = 1; + } + else + { + throw new Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68578")] - public async Task TestMissingWhenAssignmentReferencesOutVariable() - { - await TestMissingAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68578")] + public async Task TestMissingWhenAssignmentReferencesOutVariable() + { + await TestMissingAsync(""" + using System; - public class Class1 - { - public int i; - } + public class Class1 + { + public int i; + } - public class Program + public class Program + { + public static void Test(object obj) { - public static void Test(object obj) + if (TryGetValue(out var c)) { - if (TryGetValue(out var c)) - { - c.i = 1; - } - else - { - throw new Exception(); - } + c.i = 1; + } + else + { + throw new Exception(); } - - private static bool TryGetValue(out Class1 c) => throw new NotImplementedException(); } - """); - } + + private static bool TryGetValue(out Class1 c) => throw new NotImplementedException(); + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForReturnTests.cs b/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForReturnTests.cs index e4403ee95da29..fa03b73ac9ba4 100644 --- a/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForReturnTests.cs +++ b/src/Analyzers/CSharp/Tests/UseConditionalExpression/UseConditionalExpressionForReturnTests.cs @@ -13,2273 +13,2272 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseConditionalExpression +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseConditionalExpression; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)] +public partial class UseConditionalExpressionForReturnTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)] - public partial class UseConditionalExpressionForReturnTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor - { - private static readonly ParseOptions CSharp8 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); - private static readonly ParseOptions CSharp9 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9); + private static readonly ParseOptions CSharp8 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); + private static readonly ParseOptions CSharp9 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9); - public UseConditionalExpressionForReturnTests(ITestOutputHelper logger) - : base(logger) - { - } + public UseConditionalExpressionForReturnTests(ITestOutputHelper logger) + : base(logger) + { + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseConditionalExpressionForReturnDiagnosticAnalyzer(), - new CSharpUseConditionalExpressionForReturnCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseConditionalExpressionForReturnDiagnosticAnalyzer(), + new CSharpUseConditionalExpressionForReturnCodeFixProvider()); - [Fact] - public async Task TestOnSimpleReturn() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnSimpleReturn() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - return 0; - } - else - { - return 1; - } + return 0; } - } - """, - """ - class C - { - int M() + else { - return true ? 0 : 1; + return 1; } } - """); - } + } + """, + """ + class C + { + int M() + { + return true ? 0 : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnSimpleReturn_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnSimpleReturn_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return 1; - } + throw new System.Exception(); } - } - """, - """ - class C - { - int M() + else { - return true ? throw new System.Exception() : 1; + return 1; } } - """); - } + } + """, + """ + class C + { + int M() + { + return true ? throw new System.Exception() : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnSimpleReturn_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnSimpleReturn_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - return 0; - } - else - { - throw new System.Exception(); - } + return 0; } - } - """, - """ - class C - { - int M() + else { - return true ? 0 : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + int M() + { + return true ? 0 : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotWithTwoThrows() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotWithTwoThrows() + { + await TestMissingAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - throw new System.Exception(); - } + throw new System.Exception(); + } + else + { + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotOnSimpleReturn_Throw1_CSharp6() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotOnSimpleReturn_Throw1_CSharp6() + { + await TestMissingAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return 1; - } + throw new System.Exception(); + } + else + { + return 1; } } - """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotWithSimpleThrow() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotWithSimpleThrow() + { + await TestMissingAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - throw; - } - else - { - return 1; - } + throw; + } + else + { + return 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestOnSimpleReturnNoBlocks() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestOnSimpleReturnNoBlocks() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() + { + [||]if (true) + return 0; + else + return 1; + } + } + """, + """ + class C + { + int M() { - int M() - { + return true ? 0 : 1; + } + } + """); + } + + [Fact] + public async Task TestOnSimpleReturnNoBlocks_NotInBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() + { + if (true) [||]if (true) return 0; else return 1; - } } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { + if (true) return true ? 0 : 1; - } } - """); - } + } + """); + } - [Fact] - public async Task TestOnSimpleReturnNoBlocks_NotInBlock() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestMissingReturnValue1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - if (true) - [||]if (true) - return 0; - else - return 1; + return 0; } - } - """, - """ - class C - { - int M() + else { - if (true) - return true ? 0 : 1; + return; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingReturnValue1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestMissingReturnValue1_Throw() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - return 0; - } - else - { - return; - } + throw new System.Exception(); + } + else + { + return; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestMissingReturnValue1_Throw() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingReturnValue2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return; - } + return; + } + else + { + return 1; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingReturnValue2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestMissingReturnValue2_Throw() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - return; - } - else - { - return 1; - } + return; + } + else + { + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestMissingReturnValue2_Throw() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingReturnValue3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - return; - } - else - { - throw new System.Exception(); - } + return; + } + else + { + return; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingReturnValue3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithNoElseBlockButFollowingReturn() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - int M() + [||]if (true) { - [||]if (true) - { - return; - } - else - { - return; - } + return 0; } + + return 1; + } + } + """, + """ + class C + { + void M() + { + return true ? 0 : 1; } - """); - } + } + """); + } - [Fact] - public async Task TestWithNoElseBlockButFollowingReturn() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestWithNoElseBlockButFollowingReturn_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [||]if (true) { - [||]if (true) - { - return 0; - } - - return 1; + throw new System.Exception(); } + + return 1; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - return true ? 0 : 1; - } + return true ? throw new System.Exception() : 1; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestWithNoElseBlockButFollowingReturn_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestWithNoElseBlockButFollowingReturn_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - - return 1; + return 0; } + + throw new System.Exception(); + } + } + """, + """ + class C + { + void M() + { + return true ? 0 : throw new System.Exception(); } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestMissingWithoutElse() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - void M() + [||]if (true) { - return true ? throw new System.Exception() : 1; + return 0; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestWithNoElseBlockButFollowingReturn_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestMissingWithoutElse_Throw() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - void M() + [||]if (true) { - [||]if (true) - { - return 0; - } - throw new System.Exception(); } } - """, - """ - class C + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70750")] + public async Task TestMissingWithChecked() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - void M() + int x = 0; + int y = 0; + [||]if (x < 0) + { + throw new System.Exception(); + } + checked { - return true ? 0 : throw new System.Exception(); + return x - y; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingWithoutElse() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] + public async Task TestMissingWithCheckedInIf() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (checked(x == y)) { - [||]if (true) - { - return 0; - } + return 0; + } + else + { + return 1; } } - """); - } + } + """, + """ + class C + { + int M() + { + int x = 0; + int y = 0; + return checked(x == y) ? 0 : 1; + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestMissingWithoutElse_Throw() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] + public async Task TestMissingWithUncheckedInIf() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (unchecked(x == y)) { - [||]if (true) - { - throw new System.Exception(); - } - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70750")] - public async Task TestMissingWithChecked() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - int M() - { - int x = 0; - int y = 0; - [||]if (x < 0) - { - throw new System.Exception(); - } - checked - { - return x - y; - } - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] - public async Task TestMissingWithCheckedInIf() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int M() - { - int x = 0; - int y = 0; - [||]if (checked(x == y)) - { - return 0; - } - else - { - return 1; - } + return 0; } - } - """, - """ - class C - { - int M() + else { - int x = 0; - int y = 0; - return checked(x == y) ? 0 : 1; + return 1; } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + int M() + { + int x = 0; + int y = 0; + return unchecked(x == y) ? 0 : 1; + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] - public async Task TestMissingWithUncheckedInIf() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] + public async Task TestMissingWithCheckedInTrueStatement() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (x == y) { - int x = 0; - int y = 0; - [||]if (unchecked(x == y)) - { - return 0; - } - else - { - return 1; - } + return checked(x - y); } - } - """, - """ - class C - { - int M() + else { - int x = 0; - int y = 0; - return unchecked(x == y) ? 0 : 1; + return 1; } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + int M() + { + int x = 0; + int y = 0; + return x == y ? checked(x - y) : 1; + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] - public async Task TestMissingWithCheckedInTrueStatement() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] + public async Task TestMissingWithUncheckedInTrueStatement() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (x == y) { - int x = 0; - int y = 0; - [||]if (x == y) - { - return checked(x - y); - } - else - { - return 1; - } + return unchecked(x - y); } - } - """, - """ - class C - { - int M() + else { - int x = 0; - int y = 0; - return x == y ? checked(x - y) : 1; + return 1; } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + int M() + { + int x = 0; + int y = 0; + return x == y ? unchecked(x - y) : 1; + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] - public async Task TestMissingWithUncheckedInTrueStatement() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] + public async Task TestMissingWithCheckedInFalseStatement() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (x == y) { - int x = 0; - int y = 0; - [||]if (x == y) - { - return unchecked(x - y); - } - else - { - return 1; - } + return 1; } - } - """, - """ - class C - { - int M() + else { - int x = 0; - int y = 0; - return x == y ? unchecked(x - y) : 1; + return checked(x - y); } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + int M() + { + int x = 0; + int y = 0; + return x == y ? 1 : checked(x - y); + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] - public async Task TestMissingWithCheckedInFalseStatement() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] + public async Task TestMissingWithUncheckedInFalseStatement() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (x == y) { - int x = 0; - int y = 0; - [||]if (x == y) - { - return 1; - } - else - { - return checked(x - y); - } + return 1; } - } - """, - """ - class C - { - int M() + else { - int x = 0; - int y = 0; - return x == y ? 1 : checked(x - y); + return unchecked(x - y); } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + int M() + { + int x = 0; + int y = 0; + return x == y ? 1 : unchecked(x - y); + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70748")] - public async Task TestMissingWithUncheckedInFalseStatement() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70750")] + public async Task TestMissingWithUnchecked() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (x < 0) { - int x = 0; - int y = 0; - [||]if (x == y) - { - return 1; - } - else - { - return unchecked(x - y); - } + throw new System.Exception(); } - } - """, - """ - class C - { - int M() + unchecked { - int x = 0; - int y = 0; - return x == y ? 1 : unchecked(x - y); + return x - y; } } - """, parseOptions: CSharp8); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70750")] - public async Task TestMissingWithUnchecked() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70750")] + public async Task TestMissingWithUnsafe() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + int x = 0; + int y = 0; + [||]if (x < 0) + { + throw new System.Exception(); + } + unsafe { - int x = 0; - int y = 0; - [||]if (x < 0) - { - throw new System.Exception(); - } - unchecked - { - return x - y; - } + return x - y; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70750")] - public async Task TestMissingWithUnsafe() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestConversion1_CSharp8() + { + await TestInRegularAndScriptAsync( + """ + class C + { + object M() { - int M() + [||]if (true) { - int x = 0; - int y = 0; - [||]if (x < 0) - { - throw new System.Exception(); - } - unsafe - { - return x - y; - } + return "a"; + } + else + { + return "b"; } } - """); - } + } + """, + """ + class C + { + object M() + { + return true ? "a" : (object)"b"; + } + } + """, parseOptions: CSharp8); + } - [Fact] - public async Task TestConversion1_CSharp8() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestConversion1_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + class C + { + object M() { - object M() + [||]if (true) { - [||]if (true) - { - return "a"; - } - else - { - return "b"; - } + return "a"; } - } - """, - """ - class C - { - object M() + else { - return true ? "a" : (object)"b"; + return "b"; } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + object M() + { + return true ? "a" : (object)"b"; + } + } + """, parseOptions: CSharp9); + } - [Fact] - public async Task TestConversion1_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversion1_Throw1_CSharp8() + { + await TestInRegularAndScriptAsync( + """ + class C + { + object M() { - object M() + [||]if (true) { - [||]if (true) - { - return "a"; - } - else - { - return "b"; - } + throw new System.Exception(); } - } - """, - """ - class C - { - object M() + else { - return true ? "a" : (object)"b"; + return "b"; } } - """, parseOptions: CSharp9); - } + } + """, + """ + class C + { + object M() + { + return true ? throw new System.Exception() : (object)"b"; + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversion1_Throw1_CSharp8() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversion1_Throw1_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + class C + { + object M() { - object M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return "b"; - } + throw new System.Exception(); } - } - """, - """ - class C - { - object M() + else { - return true ? throw new System.Exception() : (object)"b"; + return "b"; } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + object M() + { + return true ? throw new System.Exception() : (object)"b"; + } + } + """, parseOptions: CSharp9); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversion1_Throw1_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversion1_Throw2_CSharp8() + { + await TestInRegularAndScriptAsync( + """ + class C + { + object M() { - object M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return "b"; - } + return "a"; } - } - """, - """ - class C - { - object M() + else { - return true ? throw new System.Exception() : (object)"b"; + throw new System.Exception(); } } - """, parseOptions: CSharp9); - } + } + """, + """ + class C + { + object M() + { + return true ? (object)"a" : throw new System.Exception(); + } + } + """, parseOptions: CSharp8); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversion1_Throw2_CSharp8() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversion1_Throw2_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + class C + { + object M() { - object M() + [||]if (true) { - [||]if (true) - { - return "a"; - } - else - { - throw new System.Exception(); - } + return "a"; } - } - """, - """ - class C - { - object M() + else { - return true ? (object)"a" : throw new System.Exception(); + throw new System.Exception(); } } - """, parseOptions: CSharp8); - } + } + """, + """ + class C + { + object M() + { + return true ? (object)"a" : throw new System.Exception(); + } + } + """, parseOptions: CSharp9); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversion1_Throw2_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestConversion2() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M() { - object M() + [||]if (true) { - [||]if (true) - { - return "a"; - } - else - { - throw new System.Exception(); - } + return "a"; } - } - """, - """ - class C - { - object M() + else { - return true ? (object)"a" : throw new System.Exception(); + return null; } } - """, parseOptions: CSharp9); - } + } + """, + """ + class C + { + string M() + { + return true ? "a" : null; + } + } + """); + } - [Fact] - public async Task TestConversion2() - { - await TestInRegularAndScript1Async( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + [InlineData(LanguageVersion.CSharp8, "(string)null")] + [InlineData(LanguageVersion.CSharp9, "null")] + public async Task TestConversion2_Throw1(LanguageVersion languageVersion, string expectedFalseExpression) + { + await TestInRegularAndScript1Async( + """ + class C + { + string M() { - string M() + [||]if (true) { - [||]if (true) - { - return "a"; - } - else - { - return null; - } + throw new System.Exception(); } - } - """, - """ - class C - { - string M() + else { - return true ? "a" : null; + return null; } } - """); - } + } + """, + """ + class C + { + string M() + { + return true ? throw new System.Exception() : + """ + expectedFalseExpression + """ + ; + } + } + """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - [InlineData(LanguageVersion.CSharp8, "(string)null")] - [InlineData(LanguageVersion.CSharp9, "null")] - public async Task TestConversion2_Throw1(LanguageVersion languageVersion, string expectedFalseExpression) - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestConversion2_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M() { - string M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return null; - } + return "a"; } - } - """, - """ - class C - { - string M() + else { - return true ? throw new System.Exception() : - """ + expectedFalseExpression + """ - ; + throw new System.Exception(); } } - """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); - } + } + """, + """ + class C + { + string M() + { + return true ? "a" : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestConversion2_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Theory] + [InlineData(LanguageVersion.CSharp8, "(string)null")] + [InlineData(LanguageVersion.CSharp9, "null")] + public async Task TestConversion3(LanguageVersion languageVersion, string expectedFalseExpression) + { + await TestInRegularAndScript1Async( + """ + class C + { + string M() { - string M() + [||]if (true) { - [||]if (true) - { - return "a"; - } - else - { - throw new System.Exception(); - } + return null; } - } - """, - """ - class C - { - string M() + else { - return true ? "a" : throw new System.Exception(); + return null; } } - """); - } + } + """, + """ + class C + { + string M() + { + return true ? null : + """ + expectedFalseExpression + """ + ; + } + } + """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); + } - [Theory] - [InlineData(LanguageVersion.CSharp8, "(string)null")] - [InlineData(LanguageVersion.CSharp9, "null")] - public async Task TestConversion3(LanguageVersion languageVersion, string expectedFalseExpression) - { - await TestInRegularAndScript1Async( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + [InlineData(LanguageVersion.CSharp8, "(string)null")] + [InlineData(LanguageVersion.CSharp9, "null")] + public async Task TestConversion3_Throw1(LanguageVersion languageVersion, string expectedFalseExpression) + { + await TestInRegularAndScript1Async( + """ + class C + { + string M() { - string M() + [||]if (true) { - [||]if (true) - { - return null; - } - else - { - return null; - } + throw new System.Exception(); } - } - """, - """ - class C - { - string M() + else { - return true ? null : - """ + expectedFalseExpression + """ - ; + return null; } } - """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); - } + } + """, + """ + class C + { + string M() + { + return true ? throw new System.Exception() : + """ + expectedFalseExpression + """ + ; + } + } + """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - [InlineData(LanguageVersion.CSharp8, "(string)null")] - [InlineData(LanguageVersion.CSharp9, "null")] - public async Task TestConversion3_Throw1(LanguageVersion languageVersion, string expectedFalseExpression) - { - await TestInRegularAndScript1Async( - """ - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + [InlineData(LanguageVersion.CSharp8, "(string)null")] + [InlineData(LanguageVersion.CSharp9, "null")] + public async Task TestConversion3_Throw2(LanguageVersion languageVersion, string expectedTrue) + { + await TestInRegularAndScript1Async( + """ + class C + { + string M() { - string M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return null; - } + return null; } - } - """, - """ - class C - { - string M() + else { - return true ? throw new System.Exception() : - """ + expectedFalseExpression + """ - ; + throw new System.Exception(); } } - """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); - } + } + """, + """ + class C + { + string M() + { + return true ? + """ + expectedTrue + """ + : throw new System.Exception(); + } + } + """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - [InlineData(LanguageVersion.CSharp8, "(string)null")] - [InlineData(LanguageVersion.CSharp9, "null")] - public async Task TestConversion3_Throw2(LanguageVersion languageVersion, string expectedTrue) - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestKeepTriviaAroundIf() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - string M() + // leading + [||]if (true) { - [||]if (true) - { - return null; - } - else - { - throw new System.Exception(); - } + return 0; } + else + { + return 1; + } // trailing } - """, - """ - class C + } + """, + """ + class C + { + int M() { - string M() - { - return true ? - """ + expectedTrue + """ - : throw new System.Exception(); - } + // leading + return true ? 0 : 1; // trailing } - """, parameters: new(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(languageVersion))); - } + } + """); + } - [Fact] - public async Task TestKeepTriviaAroundIf() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + {|FixAllInDocument:if|} (true) { - // leading - [||]if (true) - { - return 0; - } - else - { - return 1; - } // trailing + return 0; + } + else + { + return 1; + } + + if (true) + { + return 2; } + + return 3; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() + return true ? 0 : 1; + + return true ? 2 : 3; + } + } + """); + } + + [Fact] + public async Task TestMultiLine1() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() + { + [||]if (true) { - // leading - return true ? 0 : 1; // trailing + return Foo( + 1, 2, 3); + } + else + { + return 1; } } - """); - } + } + """, + """ + class C + { + int M() + { + return true + ? Foo( + 1, 2, 3) + : 1; + } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestMultiLine2() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - {|FixAllInDocument:if|} (true) - { - return 0; - } - else - { - return 1; - } - - if (true) - { - return 2; - } - - return 3; + return 0; + } + else + { + return Foo( + 1, 2, 3); } } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() - { - return true ? 0 : 1; + return true + ? 0 + : Foo( + 1, 2, 3); + } + } + """); + } - return true ? 2 : 3; + [Fact] + public async Task TestMultiLine3() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() + { + [||]if (true) + { + return Foo( + 1, 2, 3); + } + else + { + return Foo( + 4, 5, 6); } } - """); - } + } + """, + """ + class C + { + int M() + { + return true + ? Foo( + 1, 2, 3) + : Foo( + 4, 5, 6); + } + } + """); + } - [Fact] - public async Task TestMultiLine1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestElseIfWithBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + if (true) { - [||]if (true) - { - return Foo( - 1, 2, 3); - } - else - { - return 1; - } + } + else [||]if (false) + { + return 1; + } + else + { + return 0; } } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() + if (true) { - return true - ? Foo( - 1, 2, 3) - : 1; + } + else + { + return false ? 1 : 0; } } - """); - } + } + """); + } - [Fact] - public async Task TestMultiLine2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestElseIfWithBlock_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + if (true) { - [||]if (true) - { - return 0; - } - else - { - return Foo( - 1, 2, 3); - } } - } - """, - """ - class C - { - int M() + else [||]if (false) + { + throw new System.Exception(); + } + else { - return true - ? 0 - : Foo( - 1, 2, 3); + return 0; } } - """); - } - - [Fact] - public async Task TestMultiLine3() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + int M() { - int M() + if (true) { - [||]if (true) - { - return Foo( - 1, 2, 3); - } - else - { - return Foo( - 4, 5, 6); - } } - } - """, - """ - class C - { - int M() + else { - return true - ? Foo( - 1, 2, 3) - : Foo( - 4, 5, 6); + return false ? throw new System.Exception() : 0; } } - """); - } + } + """); + } - [Fact] - public async Task TestElseIfWithBlock() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestElseIfWithBlock_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + if (true) { - if (true) - { - } - else [||]if (false) - { - return 1; - } - else - { - return 0; - } } - } - """, - """ - class C - { - int M() + else [||]if (false) { - if (true) - { - } - else - { - return false ? 1 : 0; - } - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestElseIfWithBlock_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C - { - int M() - { - if (true) - { - } - else [||]if (false) - { - throw new System.Exception(); - } - else - { - return 0; - } + return 1; } - } - """, - """ - class C - { - int M() + else { - if (true) - { - } - else - { - return false ? throw new System.Exception() : 0; - } + throw new System.Exception(); } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestElseIfWithBlock_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + int M() { - int M() + if (true) { - if (true) - { - } - else [||]if (false) - { - return 1; - } - else - { - throw new System.Exception(); - } } - } - """, - """ - class C - { - int M() + else { - if (true) - { - } - else - { - return false ? 1 : throw new System.Exception(); - } + return false ? 1 : throw new System.Exception(); } } - """); - } + } + """); + } + + [Fact] + public async Task TestElseIfWithoutBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() + { + if (true) return 2; + else [||]if (false) return 1; + else return 0; + } + } + """, + """ + class C + { + int M() + { + if (true) return 2; + else return false ? 1 : 0; + } + } + """); + } - [Fact] - public async Task TestElseIfWithoutBlock() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestRefReturns1() + { + await TestInRegularAndScript1Async( + """ + class C + { + ref int M(ref int i, ref int j) { - int M() + [||]if (true) { - if (true) return 2; - else [||]if (false) return 1; - else return 0; + return ref i; } - } - """, - """ - class C - { - int M() + else { - if (true) return 2; - else return false ? 1 : 0; + return ref j; } } - """); - } + } + """, + """ + class C + { + ref int M(ref int i, ref int j) + { + return ref true ? ref i : ref j; + } + } + """); + } - [Fact] - public async Task TestRefReturns1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestRefReturns1_Throw1() + { + await TestMissingAsync( + """ + class C + { + ref int M(ref int i, ref int j) { - ref int M(ref int i, ref int j) + [||]if (true) { - [||]if (true) - { - return ref i; - } - else - { - return ref j; - } + throw new System.Exception(); } - } - """, - """ - class C - { - ref int M(ref int i, ref int j) + else { - return ref true ? ref i : ref j; + return ref j; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestRefReturns1_Throw1() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestRefReturns1_Throw2() + { + await TestMissingAsync( + """ + class C + { + ref int M(ref int i, ref int j) { - ref int M(ref int i, ref int j) + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - return ref j; - } + return ref i; } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestRefReturns1_Throw2() - { - await TestMissingAsync( - """ - class C - { - ref int M(ref int i, ref int j) + else { - [||]if (true) - { - return ref i; - } - else - { - throw new System.Exception(); - } + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - public async Task TestOnYieldReturn() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + public async Task TestOnYieldReturn() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - yield return 0; - } - else - { - yield return 1; - } + yield return 0; } - } - """, - """ - class C - { - int M() + else { - yield return true ? 0 : 1; + yield return 1; } } - """); - } + } + """, + """ + class C + { + int M() + { + yield return true ? 0 : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnYieldReturn_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnYieldReturn_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - else - { - yield return 1; - } + throw new System.Exception(); } - } - """, - """ - class C - { - int M() + else { - yield return true ? throw new System.Exception() : 1; + yield return 1; } } - """); - } + } + """, + """ + class C + { + int M() + { + yield return true ? throw new System.Exception() : 1; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestOnYieldReturn_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestOnYieldReturn_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - yield return 0; - } - else - { - throw new System.Exception(); - } + yield return 0; } - } - """, - """ - class C - { - int M() + else { - yield return true ? 0 : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + int M() + { + yield return true ? 0 : throw new System.Exception(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - public async Task TestOnYieldReturn_IEnumerableReturnType() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + public async Task TestOnYieldReturn_IEnumerableReturnType() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M() { - IEnumerable M() + [||]if (true) { - [||]if (true) - { - yield return 0; - } - else - { - yield return 1; - } + yield return 0; + } + else + { + yield return 1; } } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M() { - IEnumerable M() - { - yield return true ? 0 : 1; - } + yield return true ? 0 : 1; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - public async Task TestNotOnMixedYields() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + public async Task TestNotOnMixedYields() + { + await TestMissingAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - yield break; - } - else - { - yield return 1; - } + yield break; + } + else + { + yield return 1; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotOnMixedYields_Throw1() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotOnMixedYields_Throw1() + { + await TestMissingAsync( + """ + class C + { + int M() { - int M() + [||]if (true) { - [||]if (true) - { - yield break; - } - else - { - throw new System.Exception(); - } + yield break; + } + else + { + throw new System.Exception(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - public async Task TestNotOnMixedYields_IEnumerableReturnType() - { - await TestMissingAsync( - """ - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + public async Task TestNotOnMixedYields_IEnumerableReturnType() + { + await TestMissingAsync( + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M() { - IEnumerable M() + [||]if (true) { - [||]if (true) - { - yield break; - } - else - { - yield return 1; - } + yield break; } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - public async Task TestNotWithNoElseBlockButFollowingYieldReturn() - { - await TestMissingAsync( - """ - class C - { - void M() + else { - [||]if (true) - { - yield return 0; - } - yield return 1; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestWithNoElseBlockButFollowingYieldReturn_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + public async Task TestNotWithNoElseBlockButFollowingYieldReturn() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + [||]if (true) { - [||]if (true) - { - throw new System.Exception(); - } - - yield return 1; + yield return 0; } + + yield return 1; } - """, + } + """); + } - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestWithNoElseBlockButFollowingYieldReturn_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [||]if (true) { - yield return true ? throw new System.Exception() : 1; + throw new System.Exception(); } + + yield return 1; } - """); - } + } + """, - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestNotWithNoElseBlockButFollowingYieldReturn_Throw2() - { - await TestMissingAsync( - """ - class C + """ + class C + { + void M() { - void M() - { - [||]if (true) - { - yield return 0; - } + yield return true ? throw new System.Exception() : 1; + } + } + """); + } - throw new System.Exception(); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + [WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestNotWithNoElseBlockButFollowingYieldReturn_Throw2() + { + await TestMissingAsync( + """ + class C + { + void M() + { + [||]if (true) + { + yield return 0; } + + throw new System.Exception(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] - public async Task TestNotWithNoElseBlockButFollowingYieldReturn_IEnumerableReturnType() - { - await TestMissingAsync( - """ - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27960")] + public async Task TestNotWithNoElseBlockButFollowingYieldReturn_IEnumerableReturnType() + { + await TestMissingAsync( + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M() { - IEnumerable M() + [||]if (true) { - [||]if (true) - { - yield return 0; - } - - yield return 1; + yield return 0; } + + yield return 1; } - """); - } + } + """); + } - [Fact] - public async Task TestReturnTrueFalse1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestReturnTrueFalse1() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - return true; - } - else - { - return false; - } + return true; } - } - """, - """ - class C - { - bool M(int a) + else { - return a == 0; + return false; } } - """); - } + } + """, + """ + class C + { + bool M(int a) + { + return a == 0; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse1_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse1_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - throw new System.Exception(); - } - else - { - return false; - } + throw new System.Exception(); } - } - """, - """ - class C - { - bool M(int a) + else { - return a == 0 ? throw new System.Exception() : false; + return false; } } - """); - } + } + """, + """ + class C + { + bool M(int a) + { + return a == 0 ? throw new System.Exception() : false; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse1_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse1_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - return true; - } - else - { - throw new System.Exception(); - } + return true; } - } - """, - """ - class C - { - bool M(int a) + else { - return a == 0 ? true : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + bool M(int a) + { + return a == 0 ? true : throw new System.Exception(); + } + } + """); + } - [Fact] - public async Task TestReturnTrueFalse2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestReturnTrueFalse2() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - return false; - } - else - { - return true; - } + return false; } - } - """, - """ - class C - { - bool M(int a) + else { - return a != 0; + return true; } } - """); - } + } + """, + """ + class C + { + bool M(int a) + { + return a != 0; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse2_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse2_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - throw new System.Exception(); - } - else - { - return true; - } + throw new System.Exception(); } - } - """, - """ - class C - { - bool M(int a) + else { - return a == 0 ? throw new System.Exception() : true; + return true; } } - """); - } + } + """, + """ + class C + { + bool M(int a) + { + return a == 0 ? throw new System.Exception() : true; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse2_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse2_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - return false; - } - else - { - throw new System.Exception(); - } + return false; } - } - """, - """ - class C - { - bool M(int a) + else { - return a == 0 ? false : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + class C + { + bool M(int a) + { + return a == 0 ? false : throw new System.Exception(); + } + } + """); + } - [Fact] - public async Task TestReturnTrueFalse3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestReturnTrueFalse3() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - return false; - } - - return true; + return false; } + + return true; } - """, - """ - class C + } + """, + """ + class C + { + bool M(int a) { - bool M(int a) - { - return a != 0; - } + return a != 0; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse3_Throw1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse3_Throw1() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - throw new System.Exception(); - } - - return true; + throw new System.Exception(); } + + return true; } - """, - """ - class C + } + """, + """ + class C + { + bool M(int a) { - bool M(int a) - { - return a == 0 ? throw new System.Exception() : true; - } + return a == 0 ? throw new System.Exception() : true; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse3_Throw2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse3_Throw2() + { + await TestInRegularAndScript1Async( + """ + class C + { + bool M(int a) { - bool M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - return false; - } - - throw new System.Exception(); + return false; } + + throw new System.Exception(); } - """, - """ - class C + } + """, + """ + class C + { + bool M(int a) { - bool M(int a) - { - return a == 0 ? false : throw new System.Exception(); - } + return a == 0 ? false : throw new System.Exception(); } - """); - } + } + """); + } - [Fact] - public async Task TestReturnTrueFalse4() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; + [Fact] + public async Task TestReturnTrueFalse4() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M(int a) { - IEnumerable M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - yield return false; - } - else - { - yield return true; - } + yield return false; + } + else + { + yield return true; } } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M(int a) { - IEnumerable M(int a) - { - yield return a != 0; - } + yield return a != 0; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse4_Throw1() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse4_Throw1() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M(int a) { - IEnumerable M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - throw new System.Exception(); - } - else - { - yield return true; - } + throw new System.Exception(); + } + else + { + yield return true; } } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M(int a) { - IEnumerable M(int a) - { - yield return a == 0 ? throw new System.Exception() : true; - } + yield return a == 0 ? throw new System.Exception() : true; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] - public async Task TestReturnTrueFalse4_Throw2() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43291")] + public async Task TestReturnTrueFalse4_Throw2() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; - class C + class C + { + IEnumerable M(int a) { - IEnumerable M(int a) + [||]if (a == 0) { - [||]if (a == 0) - { - yield return false; - } - else - { - throw new System.Exception(); - } + yield return false; } - } - """, - """ - using System.Collections.Generic; - - class C - { - IEnumerable M(int a) + else { - yield return a == 0 ? false : throw new System.Exception(); + throw new System.Exception(); } } - """); - } + } + """, + """ + using System.Collections.Generic; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36117")] - public async Task TestMissingWhenCrossingPreprocessorDirective() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + class C + { + IEnumerable M(int a) { - int M() - { - bool check = true; - #if true - [||]if (check) - return 3; - #endif - return 2; - } + yield return a == 0 ? false : throw new System.Exception(); + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36117")] + public async Task TestMissingWhenCrossingPreprocessorDirective() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int M() + { + bool check = true; + #if true + [||]if (check) + return 3; + #endif + return 2; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39260")] - public async Task TestTitleWhenSimplifying() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39260")] + public async Task TestTitleWhenSimplifying() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M(string node1, string node2) { - void M(string node1, string node2) + [|if|] (AreSimilarCore(node1, node2)) { - [|if|] (AreSimilarCore(node1, node2)) - { - return true; - } - else - { - return false; - } + return true; } - - private bool AreSimilarCore(string node1, string node2) + else { - throw new NotImplementedException(); + return false; } } - """, - """ - class C + + private bool AreSimilarCore(string node1, string node2) + { + throw new NotImplementedException(); + } + } + """, + """ + class C + { + void M(string node1, string node2) { - void M(string node1, string node2) - { - return AreSimilarCore(node1, node2); - } + return AreSimilarCore(node1, node2); + } - private bool AreSimilarCore(string node1, string node2) - { - throw new NotImplementedException(); - } + private bool AreSimilarCore(string node1, string node2) + { + throw new NotImplementedException(); } - """, title: AnalyzersResources.Simplify_check); - } + } + """, title: AnalyzersResources.Simplify_check); } } diff --git a/src/Analyzers/CSharp/Tests/UseDeconstruction/UseDeconstructionTests.cs b/src/Analyzers/CSharp/Tests/UseDeconstruction/UseDeconstructionTests.cs index a895891077c77..4183d8a32b40a 100644 --- a/src/Analyzers/CSharp/Tests/UseDeconstruction/UseDeconstructionTests.cs +++ b/src/Analyzers/CSharp/Tests/UseDeconstruction/UseDeconstructionTests.cs @@ -11,906 +11,905 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseDeconstruction -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseDeconstructionDiagnosticAnalyzer, - CSharpUseDeconstructionCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseDeconstruction; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseDeconstructionDiagnosticAnalyzer, + CSharpUseDeconstructionCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseDeconstruction)] - public class UseDeconstructionTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseDeconstruction)] +public class UseDeconstructionTests +{ + [Fact] + public async Task TestVar() { - [Fact] - public async Task TestVar() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - var [|t1|] = GetPerson(); - } - - (string name, int age) GetPerson() => default; + var [|t1|] = GetPerson(); } - """, """ - class C - { - void M() - { - var (name, age) = GetPerson(); - } - (string name, int age) GetPerson() => default; + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() + { + var (name, age) = GetPerson(); } - """); - } - [Fact] - public async Task TestNotIfNameInInnerScope() - { - var code = """ - class C + (string name, int age) GetPerson() => default; + } + """); + } + + [Fact] + public async Task TestNotIfNameInInnerScope() + { + var code = """ + class C + { + void M() { - void M() + var t1 = GetPerson(); { - var t1 = GetPerson(); - { - int age; - } + int age; } - - (string name, int age) GetPerson() => default; } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """; - [Fact] - public async Task TestNotIfNameInOuterScope() - { - var code = """ - class C - { - int age; + await VerifyCS.VerifyCodeFixAsync(code, code); + } - void M() - { - var t1 = GetPerson(); - } + [Fact] + public async Task TestNotIfNameInOuterScope() + { + var code = """ + class C + { + int age; - (string name, int age) GetPerson() => default; + void M() + { + var t1 = GetPerson(); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """; - [Fact] - public async Task TestUpdateReference() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestUpdateReference() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - var [|t1|] = GetPerson(); - System.Console.WriteLine(t1.name + " " + t1.age); - } + var [|t1|] = GetPerson(); + System.Console.WriteLine(t1.name + " " + t1.age); + } - (string name, int age) GetPerson() => default; + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() + { + var (name, age) = GetPerson(); + System.Console.WriteLine(name + " " + age); } - """, """ - class C + + (string name, int age) GetPerson() => default; + } + """); + } + + [Fact] + public async Task TestTupleType() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - var (name, age) = GetPerson(); - System.Console.WriteLine(name + " " + age); - } + (string name, int age) [|t1|] = GetPerson(); + System.Console.WriteLine(t1.name + " " + t1.age); + } - (string name, int age) GetPerson() => default; + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() + { + (string name, int age) = GetPerson(); + System.Console.WriteLine(name + " " + age); } - """); - } - [Fact] - public async Task TestTupleType() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + (string name, int age) GetPerson() => default; + } + """); + } + + [Fact] + public async Task TestVarInForEach() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Collections.Generic; + + class C + { + void M() { - void M() - { - (string name, int age) [|t1|] = GetPerson(); + foreach (var [|t1|] in GetPeople()) System.Console.WriteLine(t1.name + " " + t1.age); - } - - (string name, int age) GetPerson() => default; } - """, """ - class C + + IEnumerable<(string name, int age)> GetPeople() => default; + } + """, """ + using System.Collections.Generic; + + class C + { + void M() { - void M() - { - (string name, int age) = GetPerson(); + foreach (var (name, age) in GetPeople()) System.Console.WriteLine(name + " " + age); - } - - (string name, int age) GetPerson() => default; } - """); - } - [Fact] - public async Task TestVarInForEach() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Collections.Generic; + IEnumerable<(string name, int age)> GetPeople() => default; + } + """); + } - class C - { - void M() - { - foreach (var [|t1|] in GetPeople()) - System.Console.WriteLine(t1.name + " " + t1.age); - } + [Fact] + public async Task TestTupleTypeInForEach() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Collections.Generic; - IEnumerable<(string name, int age)> GetPeople() => default; + class C + { + void M() + { + foreach ((string name, int age) [|t1|] in GetPeople()) + System.Console.WriteLine(t1.name + " " + t1.age); } - """, """ - using System.Collections.Generic; - class C - { - void M() - { - foreach (var (name, age) in GetPeople()) - System.Console.WriteLine(name + " " + age); - } + IEnumerable<(string name, int age)> GetPeople() => default; + } + """, """ + using System.Collections.Generic; - IEnumerable<(string name, int age)> GetPeople() => default; + class C + { + void M() + { + foreach ((string name, int age) in GetPeople()) + System.Console.WriteLine(name + " " + age); } - """); - } - [Fact] - public async Task TestTupleTypeInForEach() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Collections.Generic; + IEnumerable<(string name, int age)> GetPeople() => default; + } + """); + } - class C + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - foreach ((string name, int age) [|t1|] in GetPeople()) - System.Console.WriteLine(t1.name + " " + t1.age); - } - - IEnumerable<(string name, int age)> GetPeople() => default; + var [|t1|] = GetPerson(); + var [|t2|] = GetPerson(); } - """, """ - using System.Collections.Generic; - class C + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() { - void M() - { - foreach ((string name, int age) in GetPeople()) - System.Console.WriteLine(name + " " + age); - } - - IEnumerable<(string name, int age)> GetPeople() => default; + var (name, age) = GetPerson(); + var t2 = GetPerson(); } - """); - } - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C - { - void M() - { - var [|t1|] = GetPerson(); - var [|t2|] = GetPerson(); - } + (string name, int age) GetPerson() => default; + } + """); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestFixAll2() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() + { + var [|t1|] = GetPerson(); } - """, """ - class C + + void M2() { - void M() - { - var (name, age) = GetPerson(); - var t2 = GetPerson(); - } + var [|t2|] = GetPerson(); + } - (string name, int age) GetPerson() => default; + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() + { + var (name, age) = GetPerson(); } - """); - } - [Fact] - public async Task TestFixAll2() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + void M2() { - void M() - { - var [|t1|] = GetPerson(); - } + var (name, age) = GetPerson(); + } - void M2() - { - var [|t2|] = GetPerson(); - } + (string name, int age) GetPerson() => default; + } + """); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestFixAll3() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() + { + (string name1, int age1) [|t1|] = GetPerson(); + (string name2, int age2) [|t2|] = GetPerson(); } - """, """ - class C + + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() { - void M() - { - var (name, age) = GetPerson(); - } + (string name1, int age1) = GetPerson(); + (string name2, int age2) = GetPerson(); + } - void M2() - { - var (name, age) = GetPerson(); - } + (string name, int age) GetPerson() => default; + } + """); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestFixAll4() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() + { + (string name, int age) [|t1|] = GetPerson(); + (string name, int age) [|t2|] = GetPerson(); } - """); - } - [Fact] - public async Task TestFixAll3() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() { - void M() - { - (string name1, int age1) [|t1|] = GetPerson(); - (string name2, int age2) [|t2|] = GetPerson(); - } - - (string name, int age) GetPerson() => default; + (string name, int age) = GetPerson(); + (string name, int age) t2 = GetPerson(); } - """, """ - class C - { - void M() - { - (string name1, int age1) = GetPerson(); - (string name2, int age2) = GetPerson(); - } - (string name, int age) GetPerson() => default; - } - """); - } + (string name, int age) GetPerson() => default; + } + """); + } - [Fact] - public async Task TestFixAll4() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestNotIfDefaultTupleNameWithVar() + { + var code = """ + class C + { + void M() { - void M() - { - (string name, int age) [|t1|] = GetPerson(); - (string name, int age) [|t2|] = GetPerson(); - } - - (string name, int age) GetPerson() => default; + var t1 = GetPerson(); } - """, """ - class C - { - void M() - { - (string name, int age) = GetPerson(); - (string name, int age) t2 = GetPerson(); - } - (string name, int age) GetPerson() => default; - } - """); - } + (string, int) GetPerson() => default; + } + """; - [Fact] - public async Task TestNotIfDefaultTupleNameWithVar() - { - var code = """ - class C + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestWithUserNamesThatMatchDefaultTupleNameWithVar1() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - var t1 = GetPerson(); - } + var [|t1|] = GetPerson(); + } - (string, int) GetPerson() => default; + (string Item1, int Item2) GetPerson() => default; + } + """, """ + class C + { + void M() + { + var (Item1, Item2) = GetPerson(); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string Item1, int Item2) GetPerson() => default; + } + """); + } - [Fact] - public async Task TestWithUserNamesThatMatchDefaultTupleNameWithVar1() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestWithUserNamesThatMatchDefaultTupleNameWithVar2() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - var [|t1|] = GetPerson(); - } - - (string Item1, int Item2) GetPerson() => default; + var [|t1|] = GetPerson(); + System.Console.WriteLine(t1.Item1); } - """, """ - class C - { - void M() - { - var (Item1, Item2) = GetPerson(); - } - (string Item1, int Item2) GetPerson() => default; + (string Item1, int Item2) GetPerson() => default; + } + """, """ + class C + { + void M() + { + var (Item1, Item2) = GetPerson(); + System.Console.WriteLine(Item1); } - """); - } - [Fact] - public async Task TestWithUserNamesThatMatchDefaultTupleNameWithVar2() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C - { - void M() - { - var [|t1|] = GetPerson(); - System.Console.WriteLine(t1.Item1); - } + (string Item1, int Item2) GetPerson() => default; + } + """); + } - (string Item1, int Item2) GetPerson() => default; - } - """, """ - class C + [Fact] + public async Task TestNotIfDefaultTupleNameWithTupleType() + { + var code = """ + class C + { + void M() { - void M() - { - var (Item1, Item2) = GetPerson(); - System.Console.WriteLine(Item1); - } - - (string Item1, int Item2) GetPerson() => default; + (string, int) t1 = GetPerson(); } - """); - } - [Fact] - public async Task TestNotIfDefaultTupleNameWithTupleType() - { - var code = """ - class C - { - void M() - { - (string, int) t1 = GetPerson(); - } + (string, int) GetPerson() => default; + } + """; - (string, int) GetPerson() => default; + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestNotIfTupleIsUsed() + { + var code = """ + class C + { + void M() + { + var t1 = GetPerson(); + System.Console.WriteLine(t1); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """; - [Fact] - public async Task TestNotIfTupleIsUsed() - { - var code = """ - class C - { - void M() - { - var t1 = GetPerson(); - System.Console.WriteLine(t1); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestNotIfTupleMethodIsUsed() + { + var code = """ + class C + { + void M() + { + var t1 = GetPerson(); + System.Console.WriteLine(t1.ToString()); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """; - [Fact] - public async Task TestNotIfTupleMethodIsUsed() - { - var code = """ - class C - { - void M() - { - var t1 = GetPerson(); - System.Console.WriteLine(t1.ToString()); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestNotIfTupleDefaultElementNameUsed() + { + var code = """ + class C + { + void M() + { + var t1 = GetPerson(); + System.Console.WriteLine(t1.Item1); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """; - [Fact] - public async Task TestNotIfTupleDefaultElementNameUsed() - { - var code = """ - class C - { - void M() - { - var t1 = GetPerson(); - System.Console.WriteLine(t1.Item1); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestNotIfTupleRandomNameUsed() + { + var code = """ + class C + { + void M() + { + var t1 = GetPerson(); + System.Console.WriteLine(t1.{|CS1061:Unknown|}); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """; - [Fact] - public async Task TestNotIfTupleRandomNameUsed() - { - var code = """ - class C + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestTrivia1() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - var t1 = GetPerson(); - System.Console.WriteLine(t1.{|CS1061:Unknown|}); - } + /*1*/(/*2*/string/*3*/ name, /*4*/int/*5*/ age)/*6*/ [|t1|] = GetPerson(); + System.Console.WriteLine(/*7*/t1.name/*8*/ + " " + /*9*/t1.age/*10*/); + } - (string name, int age) GetPerson() => default; + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() + { + /*1*/(/*2*/string/*3*/ name, /*4*/int/*5*/ age)/*6*/ = GetPerson(); + System.Console.WriteLine(/*7*/name/*8*/ + " " + /*9*/age/*10*/); } - """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + (string name, int age) GetPerson() => default; + } + """); + } - [Fact] - public async Task TestTrivia1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25260")] + public async Task TestNotWithDefaultLiteralInitializer() + { + await new VerifyCS.Test() { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ class C { void M() { - /*1*/(/*2*/string/*3*/ name, /*4*/int/*5*/ age)/*6*/ [|t1|] = GetPerson(); - System.Console.WriteLine(/*7*/t1.name/*8*/ + " " + /*9*/t1.age/*10*/); + (string name, int age) person = default; + System.Console.WriteLine(person.name + " " + person.age); } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - (string name, int age) GetPerson() => default; + [Fact] + public async Task TestWithDefaultExpressionInitializer() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() + { + (string name, int age) [|person|] = default((string, int)); + System.Console.WriteLine(person.name + " " + person.age); } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() - { - /*1*/(/*2*/string/*3*/ name, /*4*/int/*5*/ age)/*6*/ = GetPerson(); - System.Console.WriteLine(/*7*/name/*8*/ + " " + /*9*/age/*10*/); - } + (string name, int age) = default((string, int)); + System.Console.WriteLine(name + " " + age); + } + } + """); + } + + [Fact] + public async Task TestNotWithImplicitConversionFromNonTuple() + { + var code = """ + class C + { + class Person + { + public static implicit operator (string, int)(Person person) => default; + } - (string name, int age) GetPerson() => default; + void M() + { + (string name, int age) person = new Person(); + System.Console.WriteLine(person.name + " " + person.age); } - """); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25260")] - public async Task TestNotWithDefaultLiteralInitializer() - { - await new VerifyCS.Test() + await VerifyCS.VerifyCodeFixAsync(code, code); + } + + [Fact] + public async Task TestWithExplicitImplicitConversionFromNonTuple() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C { - TestCode = """ - class C - { - void M() - { - (string name, int age) person = default; - System.Console.WriteLine(person.name + " " + person.age); - } - } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + class Person + { + public static implicit operator (string, int)(Person person) => default; + } - [Fact] - public async Task TestWithDefaultExpressionInitializer() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + void M() { - void M() - { - (string name, int age) [|person|] = default((string, int)); - System.Console.WriteLine(person.name + " " + person.age); - } + (string name, int age) [|person|] = ((string, int))new Person(); + System.Console.WriteLine(person.name + " " + person.age); } - """, """ - class C + } + """, """ + class C + { + class Person { - void M() - { - (string name, int age) = default((string, int)); - System.Console.WriteLine(name + " " + age); - } + public static implicit operator (string, int)(Person person) => default; } - """); - } - [Fact] - public async Task TestNotWithImplicitConversionFromNonTuple() - { - var code = """ - class C + void M() { - class Person - { - public static implicit operator (string, int)(Person person) => default; - } + (string name, int age) = ((string, int))new Person(); + System.Console.WriteLine(name + " " + age); + } + } + """); + } - void M() - { - (string name, int age) person = new Person(); + [Fact] + public async Task TestNotWithImplicitConversionFromNonTupleInForEach() + { + var code = """ + class C + { + class Person + { + public static implicit operator (string, int)(Person person) => default; + } + + void M() + { + foreach ((string name, int age) person in new Person[] { }) System.Console.WriteLine(person.name + " " + person.age); - } } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestWithExplicitImplicitConversionFromNonTuple() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestWithExplicitImplicitConversionFromNonTupleInForEach() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Linq; + class C + { + class Person { - class Person - { - public static implicit operator (string, int)(Person person) => default; - } + public static implicit operator (string, int)(Person person) => default; + } - void M() - { - (string name, int age) [|person|] = ((string, int))new Person(); + void M() + { + foreach ((string name, int age) [|person|] in new Person[] { }.Cast<(string, int)>()) System.Console.WriteLine(person.name + " " + person.age); - } } - """, """ - class C + } + """, """ + using System.Linq; + class C + { + class Person { - class Person - { - public static implicit operator (string, int)(Person person) => default; - } - - void M() - { - (string name, int age) = ((string, int))new Person(); - System.Console.WriteLine(name + " " + age); - } + public static implicit operator (string, int)(Person person) => default; } - """); - } - [Fact] - public async Task TestNotWithImplicitConversionFromNonTupleInForEach() - { - var code = """ - class C + void M() { - class Person - { - public static implicit operator (string, int)(Person person) => default; - } - - void M() - { - foreach ((string name, int age) person in new Person[] { }) - System.Console.WriteLine(person.name + " " + person.age); - } + foreach ((string name, int age) in new Person[] { }.Cast<(string, int)>()) + System.Console.WriteLine(name + " " + age); } - """; - - await VerifyCS.VerifyCodeFixAsync(code, code); - } + } + """); + } - [Fact] - public async Task TestWithExplicitImplicitConversionFromNonTupleInForEach() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Linq; - class C + [Fact] + public async Task TestWithTupleLiteralConversion() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - class Person - { - public static implicit operator (string, int)(Person person) => default; - } - - void M() - { - foreach ((string name, int age) [|person|] in new Person[] { }.Cast<(string, int)>()) - System.Console.WriteLine(person.name + " " + person.age); - } + (object name, double age) [|person|] = (null, 0); + System.Console.WriteLine(person.name + " " + person.age); } - """, """ - using System.Linq; - class C + } + """, """ + class C + { + void M() { - class Person - { - public static implicit operator (string, int)(Person person) => default; - } - - void M() - { - foreach ((string name, int age) in new Person[] { }.Cast<(string, int)>()) - System.Console.WriteLine(name + " " + age); - } + (object name, double age) = (null, 0); + System.Console.WriteLine(name + " " + age); } - """); - } + } + """); + } - [Fact] - public async Task TestWithTupleLiteralConversion() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestWithImplicitTupleConversion() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (object name, double age) [|person|] = (null, 0); - System.Console.WriteLine(person.name + " " + person.age); - } + (object name, double age) [|person|] = GetPerson(); + System.Console.WriteLine(person.name + " " + person.age); } - """, """ - class C + + (string name, int age) GetPerson() => default; + } + """, """ + class C + { + void M() { - void M() - { - (object name, double age) = (null, 0); - System.Console.WriteLine(name + " " + age); - } + (object name, double age) = GetPerson(); + System.Console.WriteLine(name + " " + age); } - """); - } - [Fact] - public async Task TestWithImplicitTupleConversion() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + (string name, int age) GetPerson() => default; + } + """); + } + + [Fact] + public async Task TestWithImplicitTupleConversionInForEach() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Collections.Generic; + class C + { + void M() { - void M() - { - (object name, double age) [|person|] = GetPerson(); + foreach ((object name, double age) [|person|] in GetPeople()) System.Console.WriteLine(person.name + " " + person.age); - } - - (string name, int age) GetPerson() => default; } - """, """ - class C + + IEnumerable<(string name, int age)> GetPeople() => default; + } + """, """ + using System.Collections.Generic; + class C + { + void M() { - void M() - { - (object name, double age) = GetPerson(); + foreach ((object name, double age) in GetPeople()) System.Console.WriteLine(name + " " + age); - } - - (string name, int age) GetPerson() => default; } - """); - } - [Fact] - public async Task TestWithImplicitTupleConversionInForEach() + IEnumerable<(string name, int age)> GetPeople() => default; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27251")] + public async Task TestEscapedContextualKeywordAsTupleName() + { + await new VerifyCS.Test() { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.Collections.Generic; class C { void M() { - foreach ((object name, double age) [|person|] in GetPeople()) - System.Console.WriteLine(person.name + " " + person.age); + var collection = new List<(int position, int @delegate)>(); + foreach (var [|item|] in collection) + { + // Do something + } } IEnumerable<(string name, int age)> GetPeople() => default; } - """, """ + """, + FixedCode = """ using System.Collections.Generic; class C { void M() { - foreach ((object name, double age) in GetPeople()) - System.Console.WriteLine(name + " " + age); + var collection = new List<(int position, int @delegate)>(); + foreach (var (position, @delegate) in collection) + { + // Do something + } } IEnumerable<(string name, int age)> GetPeople() => default; } - """); - } + """, + CodeActionValidationMode = Testing.CodeActionValidationMode.None + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27251")] - public async Task TestEscapedContextualKeywordAsTupleName() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42770")] + public async Task TestPreserveAwait() + { + await new VerifyCS.Test { - await new VerifyCS.Test() - { - TestCode = """ - using System.Collections.Generic; - class C - { - void M() - { - var collection = new List<(int position, int @delegate)>(); - foreach (var [|item|] in collection) - { - // Do something - } - } + TestCode = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; - IEnumerable<(string name, int age)> GetPeople() => default; - } - """, - FixedCode = """ - using System.Collections.Generic; - class C + class Program + { + static async Task Main(string[] args) { - void M() + {|CS7014:[Goo]|} + await foreach (var [|t|] in Sequence()) { - var collection = new List<(int position, int @delegate)>(); - foreach (var (position, @delegate) in collection) - { - // Do something - } + Console.WriteLine(t.x + t.y); } - - IEnumerable<(string name, int age)> GetPeople() => default; } - """, - CodeActionValidationMode = Testing.CodeActionValidationMode.None - }.RunAsync(); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42770")] - public async Task TestPreserveAwait() - { - await new VerifyCS.Test - { - TestCode = """ - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - - class Program + static async IAsyncEnumerable<(int x, int y)> Sequence() { - static async Task Main(string[] args) - { - {|CS7014:[Goo]|} - await foreach (var [|t|] in Sequence()) - { - Console.WriteLine(t.x + t.y); - } - } - - static async IAsyncEnumerable<(int x, int y)> Sequence() - { - yield return (0, 0); - await Task.Yield(); - } + yield return (0, 0); + await Task.Yield(); } - """, - FixedCode = """ - using System; - using System.Collections.Generic; - using System.Threading.Tasks; + } + """, + FixedCode = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; - class Program + class Program + { + static async Task Main(string[] args) { - static async Task Main(string[] args) + {|CS7014:[Goo]|} + await foreach (var (x, y) in Sequence()) { - {|CS7014:[Goo]|} - await foreach (var (x, y) in Sequence()) - { - Console.WriteLine(x + y); - } + Console.WriteLine(x + y); } + } - static async IAsyncEnumerable<(int x, int y)> Sequence() - { - yield return (0, 0); - await Task.Yield(); - } + static async IAsyncEnumerable<(int x, int y)> Sequence() + { + yield return (0, 0); + await Task.Yield(); } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60 + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66994")] - public async Task TestTopLevelDeconstruct1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66994")] + public async Task TestTopLevelDeconstruct1() + { + await new VerifyCS.Test() { - await new VerifyCS.Test() - { - TestCode = """ - (int A, int B) ints = (1, 1); - M(ints); + TestCode = """ + (int A, int B) ints = (1, 1); + M(ints); - void M((int, int) i) - { - - } - """, - TestState = + void M((int, int) i) { - OutputKind = OutputKind.ConsoleApplication - }, - LanguageVersion = LanguageVersion.CSharp9 - }.RunAsync(); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66994")] - public async Task TestTopLevelDeconstruct2() - { - await new VerifyCS.Test + } + """, + TestState = { - TestCode = """ - (int A, int B) [|ints|] = (1, 1); - M(ints.A, ints.B); + OutputKind = OutputKind.ConsoleApplication + }, + LanguageVersion = LanguageVersion.CSharp9 + }.RunAsync(); + } - void M(int x, int y) - { + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66994")] + public async Task TestTopLevelDeconstruct2() + { + await new VerifyCS.Test + { + TestCode = """ + (int A, int B) [|ints|] = (1, 1); + M(ints.A, ints.B); - } - """, - FixedCode = """ - (int A, int B) = (1, 1); - M(A, B); + void M(int x, int y) + { - void M(int x, int y) - { + } + """, + FixedCode = """ + (int A, int B) = (1, 1); + M(A, B); - } - """, - TestState = - { - OutputKind = OutputKind.ConsoleApplication - }, - FixedState = - { - OutputKind = OutputKind.ConsoleApplication - }, - LanguageVersion = LanguageVersion.CSharp9 - }.RunAsync(); - } + void M(int x, int y) + { + + } + """, + TestState = + { + OutputKind = OutputKind.ConsoleApplication + }, + FixedState = + { + OutputKind = OutputKind.ConsoleApplication + }, + LanguageVersion = LanguageVersion.CSharp9 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseDefaultLiteral/UseDefaultLiteralTests.cs b/src/Analyzers/CSharp/Tests/UseDefaultLiteral/UseDefaultLiteralTests.cs index 20cf342007e64..e7651ba47f906 100644 --- a/src/Analyzers/CSharp/Tests/UseDefaultLiteral/UseDefaultLiteralTests.cs +++ b/src/Analyzers/CSharp/Tests/UseDefaultLiteral/UseDefaultLiteralTests.cs @@ -10,805 +10,804 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseDefaultLiteral +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseDefaultLiteral; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseDefaultLiteralDiagnosticAnalyzer, + CSharpUseDefaultLiteralCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)] +public class UseDefaultLiteralTests { - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseDefaultLiteralDiagnosticAnalyzer, - CSharpUseDefaultLiteralCodeFixProvider>; + [Fact] + public async Task TestNotInCSharp7() + { + var code = """ + class C + { + void Goo(string s = default(string)) + { + } + } + """; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)] - public class UseDefaultLiteralTests + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7 + }.RunAsync(); + } + + [Fact] + public async Task TestInParameterList() { - [Fact] - public async Task TestNotInCSharp7() + await new VerifyCS.Test { - var code = """ + TestCode = """ class C { - void Goo(string s = default(string)) + void Goo(string s = [|default(string)|]) { } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7 - }.RunAsync(); - } - - [Fact] - public async Task TestInParameterList() - { - await new VerifyCS.Test - { - TestCode = """ - class C - { - void Goo(string s = [|default(string)|]) - { - } - } - """, - FixedCode = """ - class C + """, + FixedCode = """ + class C + { + void Goo(string s = default) { - void Goo(string s = default) - { - } } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestInIfCheck() + [Fact] + public async Task TestInIfCheck() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void Goo(string s) { - void Goo(string s) - { - if (s == [|default(string)|]) { } - } + if (s == [|default(string)|]) { } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void Goo(string s) { - void Goo(string s) - { - if (s == default) { } - } + if (s == default) { } } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestInReturnStatement() + [Fact] + public async Task TestInReturnStatement() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - string Goo() - { - return [|default(string)|]; - } - } - """, - FixedCode = """ - class C + TestCode = """ + class C + { + string Goo() { - string Goo() - { - return default; - } + return [|default(string)|]; } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInReturnStatement2() - { - var code = """ + } + """, + FixedCode = """ class C { string Goo() { - return {|CS0029:default(int)|}; + return default; } } - """; + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestInReturnStatement2() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInLambda1() + string Goo() + { + return {|CS0029:default(int)|}; + } + } + """; + + await new VerifyCS.Test() { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - class C - { - void Goo() - { - Func f = () => [|default(string)|]; - } - } - """, - FixedCode = """ - using System; + [Fact] + public async Task TestInLambda1() + { + await new VerifyCS.Test + { + TestCode = """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = () => default; - } + Func f = () => [|default(string)|]; } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInLambda2() - { - var code = """ + } + """, + FixedCode = """ using System; class C { void Goo() { - Func f = () => {|CS1662:{|CS0029:default(int)|}|}; + Func f = () => default; } } - """; + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestInLambda2() + { + var code = """ + using System; + + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInLocalInitializer() + void Goo() + { + Func f = () => {|CS1662:{|CS0029:default(int)|}|}; + } + } + """; + + await new VerifyCS.Test() { - await new VerifyCS.Test - { - TestCode = """ - class C - { - void Goo() - { - string s = [|default(string)|]; - } - } - """, - FixedCode = """ - class C - { - void Goo() - { - string s = default; - } - } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestInLocalInitializer2() + [Fact] + public async Task TestInLocalInitializer() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ class C { void Goo() { - string s = {|CS0029:default(int)|}; + string s = [|default(string)|]; } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestNotForVar() - { - var code = """ + """, + FixedCode = """ class C { void Goo() { - var s = default(string); + string s = default; } } - """; + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestInLocalInitializer2() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInInvocationExpression() + void Goo() + { + string s = {|CS0029:default(int)|}; + } + } + """; + + await new VerifyCS.Test() { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestNotForVar() + { + var code = """ + class C { - TestCode = """ - class C - { - void Goo() - { - Bar([|default(string)|]); - } + void Goo() + { + var s = default(string); + } + } + """; - void Bar(string s) { } - } - """, - FixedCode = """ - class C - { - void Goo() - { - Bar(default); - } + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - void Bar(string s) { } + [Fact] + public async Task TestInInvocationExpression() + { + await new VerifyCS.Test + { + TestCode = """ + class C + { + void Goo() + { + Bar([|default(string)|]); } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - [Fact] - public async Task TestNotWithMultipleOverloads() - { - var code = """ + void Bar(string s) { } + } + """, + FixedCode = """ class C { void Goo() { - Bar(default(string)); + Bar(default); } void Bar(string s) { } - void Bar(int i) { } } - """; + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestNotWithMultipleOverloads() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestLeftSideOfTernary() + void Goo() + { + Bar(default(string)); + } + + void Bar(string s) { } + void Bar(int i) { } + } + """; + + await new VerifyCS.Test() { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestLeftSideOfTernary() + { + await new VerifyCS.Test + { + TestCode = """ + class C + { + void Goo(bool b) { - void Goo(bool b) - { - var v = b ? [|default(string)|] : [|default(string)|]; - } + var v = b ? [|default(string)|] : [|default(string)|]; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void Goo(bool b) { - void Goo(bool b) - { - var v = b ? default : default(string); - } + var v = b ? default : default(string); } - """, - LanguageVersion = LanguageVersion.CSharp7_1, - DiagnosticSelector = d => d[0], - CodeFixTestBehaviors = Testing.CodeFixTestBehaviors.FixOne | Testing.CodeFixTestBehaviors.SkipFixAllCheck - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1, + DiagnosticSelector = d => d[0], + CodeFixTestBehaviors = Testing.CodeFixTestBehaviors.FixOne | Testing.CodeFixTestBehaviors.SkipFixAllCheck + }.RunAsync(); + } - [Fact] - public async Task TestRightSideOfTernary() + [Fact] + public async Task TestRightSideOfTernary() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void Goo(bool b) { - void Goo(bool b) - { - var v = b ? [|default(string)|] : [|default(string)|]; - } + var v = b ? [|default(string)|] : [|default(string)|]; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void Goo(bool b) { - void Goo(bool b) - { - var v = b ? default(string) : default; - } + var v = b ? default(string) : default; } - """, - LanguageVersion = LanguageVersion.CSharp7_1, - DiagnosticSelector = d => d[1], - CodeFixTestBehaviors = Testing.CodeFixTestBehaviors.FixOne | Testing.CodeFixTestBehaviors.SkipFixAllCheck - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1, + DiagnosticSelector = d => d[1], + CodeFixTestBehaviors = Testing.CodeFixTestBehaviors.FixOne | Testing.CodeFixTestBehaviors.SkipFixAllCheck + }.RunAsync(); + } - [Fact] - public async Task TestFixAll1() + [Fact] + public async Task TestFixAll1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void Goo() { - void Goo() - { - string s1 = [|default(string)|]; - string s2 = [|default(string)|]; - } + string s1 = [|default(string)|]; + string s2 = [|default(string)|]; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void Goo() { - void Goo() - { - string s1 = default; - string s2 = default; - } + string s1 = default; + string s2 = default; } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestFixAll2() + [Fact] + public async Task TestFixAll2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void Goo(bool b) { - void Goo(bool b) - { - string s1 = b ? [|default(string)|] : [|default(string)|]; - } + string s1 = b ? [|default(string)|] : [|default(string)|]; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void Goo(bool b) { - void Goo(bool b) - { - string s1 = b ? default : default(string); - } + string s1 = b ? default : default(string); } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestFixAll3() + [Fact] + public async Task TestFixAll3() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void Goo() { - void Goo() - { - string s1 = [|default(string)|]; - string s2 = {|CS0029:default(int)|}; - } + string s1 = [|default(string)|]; + string s2 = {|CS0029:default(int)|}; } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void Goo() { - void Goo() - { - string s1 = default; - string s2 = {|CS0029:default(int)|}; - } + string s1 = default; + string s2 = {|CS0029:default(int)|}; } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestDoNotOfferIfTypeWouldChange() + { + var code = """ + struct S + { + void M() + { + var s = new S(); + s.Equals(default(S)); + } - [Fact] - public async Task TestDoNotOfferIfTypeWouldChange() + public override bool Equals(object obj) + { + return base.Equals(obj); + } + } + """; + + await new VerifyCS.Test() { - var code = """ + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestDoNotOfferIfTypeWouldChange2() + { + var code = """ + struct S + { + void M() + { + var s = new S(); + s.Equals(default(S)); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + } + """; + + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestOnShadowedMethod() + { + await new VerifyCS.Test + { + TestCode = """ struct S { void M() { var s = new S(); - s.Equals(default(S)); + s.Equals([|default(S)|]); } - public override bool Equals(object obj) - { - return base.Equals(obj); - } + public new bool Equals(S s) => true; } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestDoNotOfferIfTypeWouldChange2() - { - var code = """ - struct S + """, + FixedCode = """ + struct S { void M() { - var s = new S(); - s.Equals(default(S)); + var s = new S(); + s.Equals(default); } - public override bool Equals(object obj) + public new bool Equals(S s) => true; + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25456")] + public async Task TestNotInSwitchCase() + { + var code = """ + class C + { + void M() + { + switch (true) { - return base.Equals(obj); + case default(bool): } } - """; + } + """; - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestOnShadowedMethod() + await new VerifyCS.Test() { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestNotInSwitchCase_InsideParentheses() + { + var code = """ + class C { - TestCode = """ - struct S + void M() + { + switch (true) { - void M() - { - var s = new S(); - s.Equals([|default(S)|]); - } - - public new bool Equals(S s) => true; + case (default(bool)): } - """, - FixedCode = """ - struct S - { - void M() - { - var s = new S(); - s.Equals(default); - } + } + } + """; - public new bool Equals(S s) => true; - } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25456")] - public async Task TestNotInSwitchCase() + [Fact] + public async Task TestInSwitchCase_InsideCast() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ class C { void M() { switch (true) { - case default(bool): + case (bool)[|default(bool)|]: } } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestNotInSwitchCase_InsideParentheses() - { - var code = """ + """, + FixedCode = """ class C { void M() { switch (true) { - case (default(bool)): + case (bool)default: } } } - """; + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestNotInPatternSwitchCase() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInSwitchCase_InsideCast() + void M() + { + switch (true) + { + case default(bool) when true: + } + } + } + """; + + await new VerifyCS.Test() { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestNotInPatternSwitchCase_InsideParentheses() + { + var code = """ + class C { - TestCode = """ - class C + void M() + { + switch (true) { - void M() - { - switch (true) - { - case (bool)[|default(bool)|]: - } - } + case (default(bool)) when true: } - """, - FixedCode = """ - class C - { - void M() - { - switch (true) - { - case (bool)default: - } - } - } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + } + """; + + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestNotInPatternSwitchCase() + [Fact] + public async Task TestInPatternSwitchCase_InsideCast() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ class C { void M() { switch (true) { - case default(bool) when true: + case (bool)[|default(bool)|] when true: } } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestNotInPatternSwitchCase_InsideParentheses() - { - var code = """ + """, + FixedCode = """ class C { void M() { switch (true) { - case (default(bool)) when true: + case (bool)default when true: } } } - """; + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInPatternSwitchCase_InsideCast() + [Fact] + public async Task TestInPatternSwitchCase_InsideWhenClause() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case (bool)[|default(bool)|] when true: - } + case default(bool) when [|default(bool)|]: } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M() { - void M() + switch (true) { - switch (true) - { - case (bool)default when true: - } + case default(bool) when default: } } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } - [Fact] - public async Task TestInPatternSwitchCase_InsideWhenClause() + [Fact] + public async Task TestNotInPatternIs() + { + var code = """ + class C + { + void M() + { + if (true is default(bool)); + } + } + """; + + await new VerifyCS.Test() { - await new VerifyCS.Test + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestNotInPatternIs_InsideParentheses() + { + var code = """ + class C { - TestCode = """ - class C - { - void M() - { - switch (true) - { - case default(bool) when [|default(bool)|]: - } - } - } - """, - FixedCode = """ - class C - { - void M() - { - switch (true) - { - case default(bool) when default: - } - } - } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + void M() + { + if (true is (default(bool))); + } + } + """; - [Fact] - public async Task TestNotInPatternIs() + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); + } + + [Fact] + public async Task TestInPatternIs_InsideCast() + { + await new VerifyCS.Test { - var code = """ + TestCode = """ class C { void M() { - if (true is default(bool)); + if (true is (bool)[|default(bool)|]); } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestNotInPatternIs_InsideParentheses() - { - var code = """ + """, + FixedCode = """ class C { void M() { - if (true is (default(bool))); + if (true is (bool)default); } } - """; - - await new VerifyCS.Test() - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } - - [Fact] - public async Task TestInPatternIs_InsideCast() - { - await new VerifyCS.Test - { - TestCode = """ - class C - { - void M() - { - if (true is (bool)[|default(bool)|]); - } - } - """, - FixedCode = """ - class C - { - void M() - { - if (true is (bool)default); - } - } - """, - LanguageVersion = LanguageVersion.CSharp7_1 - }.RunAsync(); - } + """, + LanguageVersion = LanguageVersion.CSharp7_1 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseExplicitTupleName/UseExplicitTupleNameTests.cs b/src/Analyzers/CSharp/Tests/UseExplicitTupleName/UseExplicitTupleNameTests.cs index f5270a4ed0ea3..7e24bf2ee9a9a 100644 --- a/src/Analyzers/CSharp/Tests/UseExplicitTupleName/UseExplicitTupleNameTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExplicitTupleName/UseExplicitTupleNameTests.cs @@ -10,297 +10,296 @@ using Microsoft.CodeAnalysis.UseExplicitTupleName; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExplicitTupleName -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExplicitTupleNameDiagnosticAnalyzer, - UseExplicitTupleNameCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExplicitTupleName; + +using VerifyCS = CSharpCodeFixVerifier< + UseExplicitTupleNameDiagnosticAnalyzer, + UseExplicitTupleNameCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)] - public class UseExplicitTupleNameTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)] +public class UseExplicitTupleNameTests +{ + [Fact] + public async Task TestNamedTuple1() { - [Fact] - public async Task TestNamedTuple1() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.[|Item1|]; - } + (int i, string s) v1 = default((int, string)); + var v2 = v1.[|Item1|]; } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.i; - } + (int i, string s) v1 = default((int, string)); + var v2 = v1.i; } - """); - } + } + """); + } - [Fact] - public async Task TestInArgument() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestInArgument() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - Goo(v1.[|Item1|]); - } - - void Goo(int i) { } + (int i, string s) v1 = default((int, string)); + Goo(v1.[|Item1|]); } - """, """ - class C - { - void M() - { - (int i, string s) v1 = default((int, string)); - Goo(v1.i); - } - void Goo(int i) { } + void Goo(int i) { } + } + """, """ + class C + { + void M() + { + (int i, string s) v1 = default((int, string)); + Goo(v1.i); } - """); - } - [Fact] - public async Task TestNamedTuple2() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + void Goo(int i) { } + } + """); + } + + [Fact] + public async Task TestNamedTuple2() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.[|Item2|]; - } + (int i, string s) v1 = default((int, string)); + var v2 = v1.[|Item2|]; } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.s; - } + (int i, string s) v1 = default((int, string)); + var v2 = v1.s; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnMatchingName1() - { - var code = """ - class C + [Fact] + public async Task TestMissingOnMatchingName1() + { + var code = """ + class C + { + void M() { - void M() - { - (int, string s) v1 = default((int, string)); - var v2 = v1.Item1; - } + (int, string s) v1 = default((int, string)); + var v2 = v1.Item1; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestMissingOnMatchingName2() - { - var code = """ - class C + [Fact] + public async Task TestMissingOnMatchingName2() + { + var code = """ + class C + { + void M() { - void M() - { - (int Item1, string s) v1 = default((int, string)); - var v2 = v1.Item1; - } + (int Item1, string s) v1 = default((int, string)); + var v2 = v1.Item1; } - """; + } + """; - await VerifyCS.VerifyCodeFixAsync(code, code); - } + await VerifyCS.VerifyCodeFixAsync(code, code); + } - [Fact] - public async Task TestWrongCasing() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestWrongCasing() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (int item1, string s) v1 = default((int, string)); - var v2 = v1.[|Item1|]; - } + (int item1, string s) v1 = default((int, string)); + var v2 = v1.[|Item1|]; } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() - { - (int item1, string s) v1 = default((int, string)); - var v2 = v1.item1; - } + (int item1, string s) v1 = default((int, string)); + var v2 = v1.item1; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.[|Item1|]; - var v3 = v1.[|Item2|]; - } + (int i, string s) v1 = default((int, string)); + var v2 = v1.[|Item1|]; + var v3 = v1.[|Item2|]; } - """, """ - class C + } + """, """ + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.i; - var v3 = v1.s; - } + (int i, string s) v1 = default((int, string)); + var v2 = v1.i; + var v3 = v1.s; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await VerifyCS.VerifyCodeFixAsync(""" - class C - { - void M() - { - (int i, int s) v1 = default((int, int)); - v1.[|Item1|] = v1.[|Item2|]; - } - } - """, """ - class C + [Fact] + public async Task TestFixAll2() + { + await VerifyCS.VerifyCodeFixAsync(""" + class C + { + void M() { - void M() - { - (int i, int s) v1 = default((int, int)); - v1.i = v1.s; - } + (int i, int s) v1 = default((int, int)); + v1.[|Item1|] = v1.[|Item2|]; } - """); - } - - [Fact] - public async Task TestFalseOptionImplicitTuple() - { - var code = """ - class C + } + """, """ + class C + { + void M() { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.Item1; - } + (int i, int s) v1 = default((int, int)); + v1.i = v1.s; } - """; + } + """); + } - await new VerifyCS.Test() + [Fact] + public async Task TestFalseOptionImplicitTuple() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - Options = + void M() { - { CodeStyleOptions2.PreferExplicitTupleNames, false, NotificationOption2.Warning } + (int i, string s) v1 = default((int, string)); + var v2 = v1.Item1; } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestFalseOptionExplicitTuple() + await new VerifyCS.Test() { - var code = """ - class C - { - void M() - { - (int i, string s) v1 = default((int, string)); - var v2 = v1.i; - } - } - """; + TestCode = code, + FixedCode = code, + Options = + { + { CodeStyleOptions2.PreferExplicitTupleNames, false, NotificationOption2.Warning } + } + }.RunAsync(); + } - await new VerifyCS.Test() + [Fact] + public async Task TestFalseOptionExplicitTuple() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - Options = + void M() { - { CodeStyleOptions2.PreferExplicitTupleNames, false, NotificationOption2.Warning } + (int i, string s) v1 = default((int, string)); + var v2 = v1.i; } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestOnRestField() + await new VerifyCS.Test() { - var valueTuple8 = """ - namespace System + TestCode = code, + FixedCode = code, + Options = + { + { CodeStyleOptions2.PreferExplicitTupleNames, false, NotificationOption2.Warning } + } + }.RunAsync(); + } + + [Fact] + public async Task TestOnRestField() + { + var valueTuple8 = """ + namespace System + { + public struct ValueTuple { - public struct ValueTuple - { - public T1 Item1; + public T1 Item1; - public ValueTuple(T1 item1) - { - } - } - public struct ValueTuple where TRest : struct + public ValueTuple(T1 item1) { - public T1 Item1; - public T2 Item2; - public T3 Item3; - public T4 Item4; - public T5 Item5; - public T6 Item6; - public T7 Item7; - public TRest Rest; - - public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) - { - } } } - """; - var code = """ - class C + public struct ValueTuple where TRest : struct { - void M() + public T1 Item1; + public T2 Item2; + public T3 Item3; + public T4 Item4; + public T5 Item5; + public T6 Item6; + public T7 Item7; + public TRest Rest; + + public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { - (int, int, int, int, int, int, int, int) x = default; - _ = x.Rest; } } - """ + valueTuple8; - - await new VerifyCS.Test() + } + """; + var code = """ + class C { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp11 - }.RunAsync(); - } + void M() + { + (int, int, int, int, int, int, int, int) x = default; + _ = x.Rest; + } + } + """ + valueTuple8; + + await new VerifyCS.Test() + { + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp11 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseExplicitTypeForConst/UseExplicitTypeForConstTests.cs b/src/Analyzers/CSharp/Tests/UseExplicitTypeForConst/UseExplicitTypeForConstTests.cs index 6eef6f0aa63b8..8444ac27faa7f 100644 --- a/src/Analyzers/CSharp/Tests/UseExplicitTypeForConst/UseExplicitTypeForConstTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExplicitTypeForConst/UseExplicitTypeForConstTests.cs @@ -11,281 +11,280 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExplicitTypeForConst +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExplicitTypeForConst; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTypeForConst)] +public sealed class UseExplicitTypeForConstTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTypeForConst)] - public sealed class UseExplicitTypeForConstTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseExplicitTypeForConstTests(ITestOutputHelper logger) + : base(logger) { - public UseExplicitTypeForConstTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new UseExplicitTypeForConstCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new UseExplicitTypeForConstCodeFixProvider()); - [Fact] - public async Task TestWithIntLiteral() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithIntLiteral() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = 0; - } + const [|var|] v = 0; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - const int v = 0; - } + const int v = 0; } - """); - } + } + """); + } - [Fact] - public async Task TestWithStringConstant() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithStringConstant() + { + await TestInRegularAndScriptAsync( + """ + class C + { + const string s = null; + void M() { - const string s = null; - void M() - { - const [|var|] v = s; - } + const [|var|] v = s; } - """, - """ - class C + } + """, + """ + class C + { + const string s = null; + void M() { - const string s = null; - void M() - { - const string v = s; - } + const string v = s; } - """); - } + } + """); + } - [Fact] - public async Task TestWithQualifiedType() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithQualifiedType() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = default(System.Action); - } + const [|var|] v = default(System.Action); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - const System.Action v = default(System.Action); - } + const System.Action v = default(System.Action); } - """); - } + } + """); + } - [Fact] - public async Task TestWithNonConstantInitializer() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithNonConstantInitializer() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = System.Console.ReadLine(); - } + const [|var|] v = System.Console.ReadLine(); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - const string v = System.Console.ReadLine(); - } + const string v = System.Console.ReadLine(); } - """); - } + } + """); + } - [Fact] - public async Task TestWithNonConstantTupleType() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithNonConstantTupleType() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = (0, true); - } + const [|var|] v = (0, true); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - const (int, bool) v = (0, true); - } + const (int, bool) v = (0, true); } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithNullLiteral() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotWithNullLiteral() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = null; - } + const [|var|] v = null; } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithDefaultLiteral() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotWithDefaultLiteral() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = default; - } + const [|var|] v = default; } - """); - } + } + """); + } - [Fact] - public async Task TestWithLambda() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWithLambda() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = () => { }; - } + const [|var|] v = () => { }; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - const System.Action v = () => { }; - } + const System.Action v = () => { }; } - """); - } - - [Fact] - public async Task TestNotWithAnonymousType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void M() - { - const [|var|] v = new { a = 0 }; - } - } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithArrayInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotWithAnonymousType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = { 0, 1 }; - } + const [|var|] v = new { a = 0 }; } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithMissingInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotWithArrayInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = - } + const [|var|] v = { 0, 1 }; } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithClassVar() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotWithMissingInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - class var { } - void M() - { - const [|var|] v = 0; - } + const [|var|] v = } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnField() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotWithClassVar() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + class var { } + void M() { const [|var|] v = 0; } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithMultipleDeclarators() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestNotOnField() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + const [|var|] v = 0; + } + """); + } + + [Fact] + public async Task TestNotWithMultipleDeclarators() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] a = 0, b = 0; - } + const [|var|] a = 0, b = 0; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForAccessorsAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForAccessorsAnalyzerTests.cs index 21a8b8c2819f8..c496185cb85d1 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForAccessorsAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForAccessorsAnalyzerTests.cs @@ -13,825 +13,824 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForAccessorsTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForAccessorsTests +{ + private static async Task TestWithUseExpressionBody( + string code, + string fixedCode, + LanguageVersion version = LanguageVersion.CSharp8) { - private static async Task TestWithUseExpressionBody( - string code, - string fixedCode, - LanguageVersion version = LanguageVersion.CSharp8) + var test = new VerifyCS.Test { - var test = new VerifyCS.Test + ReferenceAssemblies = version == LanguageVersion.CSharp9 ? ReferenceAssemblies.Net.Net50 : ReferenceAssemblies.Default, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = version, + Options = { - ReferenceAssemblies = version == LanguageVersion.CSharp9 ? ReferenceAssemblies.Net.Net50 : ReferenceAssemblies.Default, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = version, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, - }, - }; + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, + }, + }; - await test.RunAsync(); - } + await test.RunAsync(); + } - private static async Task TestWithUseExpressionBodyIncludingPropertiesAndIndexers(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + private static async Task TestWithUseExpressionBodyIncludingPropertiesAndIndexers(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + { + await new VerifyCS.Test { - await new VerifyCS.Test + ReferenceAssemblies = version == LanguageVersion.CSharp9 ? ReferenceAssemblies.Net.Net50 : ReferenceAssemblies.Default, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = version, + Options = { - ReferenceAssemblies = version == LanguageVersion.CSharp9 ? ReferenceAssemblies.Net.Net50 : ReferenceAssemblies.Default, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = version, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.WhenPossible }, - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.WhenPossible }, - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.WhenPossible }, + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.WhenPossible }, + } + }.RunAsync(); + } - private static async Task TestWithUseBlockBodyIncludingPropertiesAndIndexers(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + private static async Task TestWithUseBlockBodyIncludingPropertiesAndIndexers(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + { + await new VerifyCS.Test { - await new VerifyCS.Test + ReferenceAssemblies = version == LanguageVersion.CSharp9 ? ReferenceAssemblies.Net.Net50 : ReferenceAssemblies.Default, + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = version, + Options = { - ReferenceAssemblies = version == LanguageVersion.CSharp9 ? ReferenceAssemblies.Net.Net50 : ReferenceAssemblies.Default, - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = version, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, + } + }.RunAsync(); + } - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C + { + int Bar() { return 0; } - int Goo - { - {|IDE0027:get - { - return Bar(); - }|} - } - } - """; - var fixedCode = """ - class C + int Goo { - int Bar() { return 0; } - - int Goo + {|IDE0027:get { - get => Bar(); - } + return Bar(); + }|} } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - [Fact] - public async Task TestUpdatePropertyInsteadOfAccessor() - { - // TODO: Should this test move to properties tests? - var code = """ - class C + int Goo { - int Bar() { return 0; } - - {|IDE0025:int Goo - { - get - { - return Bar(); - } - }|} + get => Bar(); } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - int Goo => Bar(); - } - """; - await TestWithUseExpressionBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + [Fact] + public async Task TestUpdatePropertyInsteadOfAccessor() + { + // TODO: Should this test move to properties tests? + var code = """ + class C + { + int Bar() { return 0; } - [Fact] - public async Task TestOnIndexer1() - { - var code = """ - class C + {|IDE0025:int Goo { - int Bar() { return 0; } - - int this[int i] + get { - {|IDE0027:get - { - return Bar(); - }|} + return Bar(); } - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int this[int i] - { - get => Bar(); - } - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + int Goo => Bar(); + } + """; + await TestWithUseExpressionBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - [Fact] - public async Task TestUpdateIndexerIfIndexerAndAccessorCanBeUpdated() - { - // TODO: Should this test move to indexers tests? - var code = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestOnIndexer1() + { + var code = """ + class C + { + int Bar() { return 0; } - {|IDE0026:int this[int i] + int this[int i] + { + {|IDE0027:get { - get - { - return Bar(); - } + return Bar(); }|} } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } - - int this[int i] => Bar(); - } - """; - await TestWithUseExpressionBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - [Fact] - public async Task TestOnSetter1() - { - var code = """ - class C + int this[int i] { - void Bar() { } - - int Goo - { - {|IDE0027:set - { - Bar(); - }|} - } + get => Bar(); } - """; - var fixedCode = """ - class C - { - void Bar() { } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - int Goo - { - set => Bar(); - } - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestUpdateIndexerIfIndexerAndAccessorCanBeUpdated() + { + // TODO: Should this test move to indexers tests? + var code = """ + class C + { + int Bar() { return 0; } - [Fact] - public async Task TestOnInit1() - { - var code = - """ - class C + {|IDE0026:int this[int i] { - int Goo + get { - {|IDE0027:init - { - Bar(); - }|} + return Bar(); } + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int Bar() { return 0; } - } - """; - var fixedCode = - """ - class C + int this[int i] => Bar(); + } + """; + await TestWithUseExpressionBodyIncludingPropertiesAndIndexers(code, fixedCode); + } + + [Fact] + public async Task TestOnSetter1() + { + var code = """ + class C + { + void Bar() { } + + int Goo { - int Goo + {|IDE0027:set { - init => Bar(); - } - - int Bar() { return 0; } + Bar(); + }|} } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp9); - } + } + """; + var fixedCode = """ + class C + { + void Bar() { } - [Fact] - public async Task TestMissingWithOnlySetter() - { - await VerifyCS.VerifyAnalyzerAsync(""" - class C + int Goo { - void Bar() { } - - int Goo - { - set => Bar(); - } + set => Bar(); } - """); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestMissingWithOnlyInit() - { - var code = - """ - class C + [Fact] + public async Task TestOnInit1() + { + var code = + """ + class C + { + int Goo { - int Goo + {|IDE0027:init { - init => Bar(); - } - - int Bar() { return 0; } + Bar(); + }|} } - """; - await new VerifyCS.Test + int Bar() { return 0; } + } + """; + var fixedCode = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, - TestCode = code, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + int Goo + { + init => Bar(); + } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + int Bar() { return 0; } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp9); + } - class C + [Fact] + public async Task TestMissingWithOnlySetter() + { + await VerifyCS.VerifyAnalyzerAsync(""" + class C + { + void Bar() { } + + int Goo { - int Goo - { - {|IDE0027:get - { - throw new NotImplementedException(); - }|} - } + set => Bar(); } - """; - var fixedCode = """ - using System; + } + """); + } - class C + [Fact] + public async Task TestMissingWithOnlyInit() + { + var code = + """ + class C + { + int Goo { - int Goo - { - get => throw new NotImplementedException(); - } + init => Bar(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } - [Fact] - public async Task TestUseExpressionBody4() + int Bar() { return 0; } + } + """; + + await new VerifyCS.Test { - var code = """ - using System; + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + TestCode = code, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + int Goo { - int Goo + {|IDE0027:get { - {|IDE0027:get - { - throw new NotImplementedException(); // comment - }|} - } + throw new NotImplementedException(); + }|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + int Goo { - int Goo - { - get => throw new NotImplementedException(); // comment - } + get => throw new NotImplementedException(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59255")] - public async Task TestUseExpressionBody5() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - class C + class C + { + int Goo { - event EventHandler Goo + {|IDE0027:get { - {|IDE0027:add - { - throw new NotImplementedException(); - }|} - - {|IDE0027:remove - { - throw new NotImplementedException(); - }|} - } + throw new NotImplementedException(); // comment + }|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + int Goo { - event EventHandler Goo - { - add => throw new NotImplementedException(); - - remove => throw new NotImplementedException(); - } + get => throw new NotImplementedException(); // comment } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59255")] + public async Task TestUseExpressionBody5() + { + var code = """ + using System; + + class C + { + event EventHandler Goo { - int Bar() { return 0; } + {|IDE0027:add + { + throw new NotImplementedException(); + }|} - int Goo + {|IDE0027:remove { - {|IDE0027:get => Bar();|} - } + throw new NotImplementedException(); + }|} } - """; - var fixedCode = """ - class C + } + """; + var fixedCode = """ + using System; + + class C + { + event EventHandler Goo { - int Bar() { return 0; } + add => throw new NotImplementedException(); - int Goo - { - get - { - return Bar(); - } - } + remove => throw new NotImplementedException(); } - """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBodyForSetter1() - { - var code = """ - class C + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + int Bar() { return 0; } + + int Goo { - void Bar() { } + {|IDE0027:get => Bar();|} + } + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int Goo + int Goo + { + get { - {|IDE0027:set => Bar();|} - } + return Bar(); } - """; - var fixedCode = """ - class C - { - void Bar() { } + } + } + """; + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - int Goo - { - set - { - Bar(); - } + [Fact] + public async Task TestUseBlockBodyForSetter1() + { + var code = """ + class C + { + void Bar() { } + + int Goo + { + {|IDE0027:set => Bar();|} } } - """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + """; + var fixedCode = """ + class C + { + void Bar() { } - [Fact] - public async Task TestUseBlockBodyForInit1() - { - var code = - """ - class C + int Goo { - int Goo + set { - {|IDE0027:init => Bar();|} - } + Bar(); + } + } + } + """; + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - int Bar() { return 0; } + [Fact] + public async Task TestUseBlockBodyForInit1() + { + var code = + """ + class C + { + int Goo + { + {|IDE0027:init => Bar();|} } - """; - var fixedCode = - """ - class C + + int Bar() { return 0; } + } + """; + var fixedCode = + """ + class C + { + int Goo { - int Goo + init { - init - { - Bar(); - } + Bar(); } + } - int Bar() { return 0; } - } - """; + int Bar() { return 0; } + } + """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode, LanguageVersion.CSharp9); - } + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode, LanguageVersion.CSharp9); + } - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; - class C + class C + { + int Goo { - int Goo - { - {|IDE0027:get => throw new NotImplementedException();|} - } + {|IDE0027:get => throw new NotImplementedException();|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + } + """; + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - class C + class C + { + int Goo { - int Goo - { - {|IDE0027:get => throw new NotImplementedException();|} // comment - } + {|IDE0027:get => throw new NotImplementedException();|} // comment } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); // comment } } - """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + } + """; + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31308")] - public async Task TestUseBlockBody5() - { - var code = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31308")] + public async Task TestUseBlockBody5() + { + var code = """ + class C + { + C this[int index] { - C this[int index] - { - get => default; - } + get => default; } - """; - await new VerifyCS.Test + } + """; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenOnSingleLine, NotificationOption2.None }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.WhenOnSingleLine, NotificationOption2.None }, + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.WhenOnSingleLine, NotificationOption2.None }, + } + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59255")] + public async Task TestUseBlockBody6() + { + var code = """ + using System; + + class C { - TestCode = code, - FixedCode = code, - Options = + event EventHandler Goo { - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenOnSingleLine, NotificationOption2.None }, - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.WhenOnSingleLine, NotificationOption2.None }, - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.WhenOnSingleLine, NotificationOption2.None }, + {|IDE0027:add => throw new NotImplementedException();|} + {|IDE0027:remove => throw new NotImplementedException();|} + } } - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/59255")] - public async Task TestUseBlockBody6() - { - var code = """ - using System; + """; + var fixedCode = """ + using System; - class C + class C + { + event EventHandler Goo { - event EventHandler Goo + add { - {|IDE0027:add => throw new NotImplementedException();|} - {|IDE0027:remove => throw new NotImplementedException();|} - } + throw new NotImplementedException(); } - """; - var fixedCode = """ - using System; - class C - { - event EventHandler Goo + remove { - add - { - throw new NotImplementedException(); - } - - remove - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + } + """; + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20350")] - public async Task TestAccessorListFormatting() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20350")] + public async Task TestAccessorListFormatting() + { + var code = """ + class C + { + int Bar() { return 0; } - int Goo { {|IDE0027:get => Bar();|} } - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + int Goo { {|IDE0027:get => Bar();|} } + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int Goo + int Goo + { + get { - get - { - return Bar(); - } + return Bar(); } } - """; - await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); - } + } + """; + await TestWithUseBlockBodyIncludingPropertiesAndIndexers(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20350")] - public async Task TestAccessorListFormatting_FixAll() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20350")] + public async Task TestAccessorListFormatting_FixAll() + { + var code = """ + class C + { + int Bar() { return 0; } - int Goo { {|IDE0027:get => Bar();|} {|IDE0027:set => Bar();|} } - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + int Goo { {|IDE0027:get => Bar();|} {|IDE0027:set => Bar();|} } + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int Goo + int Goo + { + get { return Bar(); } + set { - get { return Bar(); } - set - { - Bar(); - } + Bar(); } } - """; - var batchFixedCode = """ - class C + } + """; + var batchFixedCode = """ + class C + { + int Bar() { return 0; } + + int Goo { - int Bar() { return 0; } + get + { + return Bar(); + } - int Goo + set { - get - { - return Bar(); - } - - set - { - Bar(); - } + Bar(); } } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - BatchFixedCode = batchFixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, - }, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20350")] - public async Task TestAccessorListFormatting_FixAll2() + } + """; + await new VerifyCS.Test { - var code = - """ - class C - { - int Goo { {|IDE0027:get => Bar();|} {|IDE0027:init => Bar();|} } + TestCode = code, + FixedCode = fixedCode, + BatchFixedCode = batchFixedCode, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, + }, + }.RunAsync(); + } - int Bar() { return 0; } - } - """; - var fixedCode = - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20350")] + public async Task TestAccessorListFormatting_FixAll2() + { + var code = + """ + class C + { + int Goo { {|IDE0027:get => Bar();|} {|IDE0027:init => Bar();|} } + + int Bar() { return 0; } + } + """; + var fixedCode = + """ + class C + { + int Goo { - int Goo + get { return Bar(); } + init { - get { return Bar(); } - init - { - Bar(); - } + Bar(); } - - int Bar() { return 0; } } - """; - var batchFixedCode = - """ - class C + + int Bar() { return 0; } + } + """; + var batchFixedCode = + """ + class C + { + int Goo { - int Goo + get { - get - { - return Bar(); - } - - init - { - Bar(); - } + return Bar(); } - int Bar() { return 0; } + init + { + Bar(); + } } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, - TestCode = code, - FixedCode = fixedCode, - BatchFixedCode = batchFixedCode, - LanguageVersion = LanguageVersion.CSharp9, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, - } - }.RunAsync(); - } + int Bar() { return 0; } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7() + await new VerifyCS.Test { - var code = """ - using System; - class C - { - int Goo { {|IDE0027:get {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} } - } - """; - var fixedCode = """ - using System; - class C + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + TestCode = code, + FixedCode = fixedCode, + BatchFixedCode = batchFixedCode, + LanguageVersion = LanguageVersion.CSharp9, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, + } + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7() + { + var code = """ + using System; + class C + { + int Goo { {|IDE0027:get {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} } + } + """; + var fixedCode = """ + using System; + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7_FixAll() - { - var code = """ - using System; - class C - { - int Goo { {|IDE0027:get {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} } - int Bar { {|IDE0027:get {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} } - } - """; - var fixedCode = """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7_FixAll() + { + var code = """ + using System; + class C + { + int Goo { {|IDE0027:get {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} } + int Bar { {|IDE0027:get {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} } + } + """; + var fixedCode = """ + using System; + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - int Bar + } + int Bar + { + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConstructorsAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConstructorsAnalyzerTests.cs index a395184e792c7..c9c5d77ef6644 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConstructorsAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConstructorsAnalyzerTests.cs @@ -12,294 +12,293 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForConstructorsAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForConstructorsAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = version, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, ExpressionBodyPreference.WhenPossible } } - }.RunAsync(); - } - - private static async Task TestWithUseBlockBody(string code, string fixedCode) + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = version, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, ExpressionBodyPreference.WhenPossible } } + }.RunAsync(); + } + + private static async Task TestWithUseBlockBody(string code, string fixedCode) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, ExpressionBodyPreference.Never } } + }.RunAsync(); + } + + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, ExpressionBodyPreference.Never } } - }.RunAsync(); - } - - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - void Bar() { } + void Bar() { } - {|IDE0021:public C() - { - Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0021:public C() { - void Bar() { } - - public C() => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + void Bar() { } - [Fact] - public async Task TestUseExpressionBody2() - { - var code = """ - class C - { - int a; + public C() => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - {|IDE0021:public C() - { - a = Bar(); - }|} + [Fact] + public async Task TestUseExpressionBody2() + { + var code = """ + class C + { + int a; - int Bar() { return 0; } - } - """; - var fixedCode = """ - class C + {|IDE0021:public C() { - int a; + a = Bar(); + }|} + + int Bar() { return 0; } + } + """; + var fixedCode = """ + class C + { + int a; - public C() => a = Bar(); + public C() => a = Bar(); - int Bar() { return 0; } - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + int Bar() { return 0; } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + {|IDE0021:public C() { - {|IDE0021:public C() - { - throw new NotImplementedException(); - }|} - } - """; - var fixedCode = """ - using System; + throw new NotImplementedException(); + }|} + } + """; + var fixedCode = """ + using System; + + class C + { + public C() => throw new NotImplementedException(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; + + class C + { + {|IDE0021:public C() { - public C() => throw new NotImplementedException(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + throw new NotImplementedException(); // comment + }|} + } + """; + var fixedCode = """ + using System; + + class C + { + public C() => throw new NotImplementedException(); // comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + {|IDE0021:public C() => Bar();|} - class C + void Bar() { } + } + """; + var fixedCode = """ + class C + { + public C() { - {|IDE0021:public C() - { - throw new NotImplementedException(); // comment - }|} + Bar(); } - """; - var fixedCode = """ - using System; - class C - { - public C() => throw new NotImplementedException(); // comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + void Bar() { } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C - { - {|IDE0021:public C() => Bar();|} + [Fact] + public async Task TestUseBlockBody2() + { + var code = """ + class C + { + int a; - void Bar() { } - } - """; - var fixedCode = """ - class C - { - public C() - { - Bar(); - } + {|IDE0021:public C() => a = Bar();|} - void Bar() { } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + int Bar() { return 0; } + } + """; + var fixedCode = """ + class C + { + int a; - [Fact] - public async Task TestUseBlockBody2() - { - var code = """ - class C + public C() { - int a; - - {|IDE0021:public C() => a = Bar();|} - - int Bar() { return 0; } + a = Bar(); } - """; - var fixedCode = """ - class C - { - int a; - public C() - { - a = Bar(); - } + int Bar() { return 0; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - int Bar() { return 0; } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + class C + { + {|IDE0021:public C() => throw new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; - class C + class C + { + public C() { - {|IDE0021:public C() => throw new NotImplementedException();|} + throw new NotImplementedException(); } - """; - var fixedCode = """ - using System; + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - public C() - { - throw new NotImplementedException(); - } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + class C + { + {|IDE0021:public C() => throw new NotImplementedException();|} // comment + } + """; + var fixedCode = """ + using System; - class C + class C + { + public C() { - {|IDE0021:public C() => throw new NotImplementedException();|} // comment + throw new NotImplementedException(); // comment } - """; - var fixedCode = """ - using System; + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7() + { + var code = """ + using System; + class C + { + {|IDE0021:public C() {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; + class C + { + public C() { - public C() - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7() - { - var code = """ - using System; - class C - { - {|IDE0021:public C() {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7_FixAll() + { + var code = """ + using System; + class C + { + {|IDE0021:public C() {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} + {|IDE0021:public C(int i) {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; + class C + { + public C() { - public C() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp7_FixAll() - { - var code = """ - using System; - class C - { - {|IDE0021:public C() {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} - {|IDE0021:public C(int i) {|CS8059:=>|} {|CS8059:throw|} new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; - class C + public C(int i) { - public C() - { - throw new NotImplementedException(); - } - - public C(int i) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConversionOperatorsAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConversionOperatorsAnalyzerTests.cs index d4de340a28ef4..87024cd4f51f2 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConversionOperatorsAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForConversionOperatorsAnalyzerTests.cs @@ -10,208 +10,207 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForConversionOperatorsAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForConversionOperatorsAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.WhenPossible } } - }.RunAsync(); - } + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.WhenPossible } } + }.RunAsync(); + } - private static async Task TestWithUseBlockBody(string code, string fixedCode) + private static async Task TestWithUseBlockBody(string code, string fixedCode) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.Never } } + }.RunAsync(); + } + + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.Never } } - }.RunAsync(); - } - - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - static int Bar() { return 0; } + static int Bar() { return 0; } - {|IDE0023:public static implicit operator {|CS0161:C|}(int i) - { - Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0023:public static implicit operator {|CS0161:C|}(int i) { - static int Bar() { return 0; } + Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + static int Bar() { return 0; } - public static implicit operator C(int i) => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + public static implicit operator C(int i) => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody2() - { - var code = """ - class C - { - static int Bar() { return 0; } + [Fact] + public async Task TestUseExpressionBody2() + { + var code = """ + class C + { + static int Bar() { return 0; } - {|IDE0023:public static implicit operator C(int i) - { - return Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0023:public static implicit operator C(int i) { - static int Bar() { return 0; } - - public static implicit operator C(int i) => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + return Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + static int Bar() { return 0; } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + public static implicit operator C(int i) => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C - { - {|IDE0023:public static implicit operator C(int i) - { - throw new NotImplementedException(); - }|} - } - """; - var fixedCode = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + {|IDE0023:public static implicit operator C(int i) { - public static implicit operator C(int i) => throw new NotImplementedException(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + throw new NotImplementedException(); + }|} + } + """; + var fixedCode = """ + using System; + + class C + { + public static implicit operator C(int i) => throw new NotImplementedException(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - class C + class C + { + {|IDE0023:public static implicit operator C(int i) { - {|IDE0023:public static implicit operator C(int i) - { - throw new NotImplementedException(); // comment - }|} - } - """; - var fixedCode = """ - using System; + throw new NotImplementedException(); // comment + }|} + } + """; + var fixedCode = """ + using System; + + class C + { + public static implicit operator C(int i) => throw new NotImplementedException(); // comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C - { - public static implicit operator C(int i) => throw new NotImplementedException(); // comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + static int Bar() { return 0; } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C - { - static int Bar() { return 0; } + {|IDE0023:public static implicit operator C(int i) => Bar();|} + } + """; + var fixedCode = """ + class C + { + static int Bar() { return 0; } - {|IDE0023:public static implicit operator C(int i) => Bar();|} - } - """; - var fixedCode = """ - class C + public static implicit operator C(int i) { - static int Bar() { return 0; } - - public static implicit operator C(int i) - { - return Bar(); - } + return Bar(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; - class C - { - {|IDE0023:public static implicit operator C(int i) => throw new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; + class C + { + {|IDE0023:public static implicit operator C(int i) => throw new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; - class C + class C + { + public static implicit operator C(int i) { - public static implicit operator C(int i) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - class C - { - {|IDE0023:public static implicit operator C(int i) => throw new NotImplementedException();|} // comment - } - """; - var fixedCode = """ - using System; + class C + { + {|IDE0023:public static implicit operator C(int i) => throw new NotImplementedException();|} // comment + } + """; + var fixedCode = """ + using System; - class C + class C + { + public static implicit operator C(int i) { - public static implicit operator C(int i) - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); // comment } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForIndexersAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForIndexersAnalyzerTests.cs index 57785d67bee26..8e7c480cfad9c 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForIndexersAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForIndexersAnalyzerTests.cs @@ -11,289 +11,288 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForIndexersAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForIndexersAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode) + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { - TestCode = code, - FixedCode = fixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.WhenPossible }, - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.WhenPossible }, + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + } + }.RunAsync(); + } - private static async Task TestWithUseBlockBody(string code, string fixedCode) + private static async Task TestWithUseBlockBody(string code, string fixedCode) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { - TestCode = code, - FixedCode = fixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - } - }.RunAsync(); - } + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + } + }.RunAsync(); + } - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C + { + int Bar() { return 0; } - {|IDE0026:int this[int i] - { - get - { - return Bar(); - } - }|} - } - """; - var fixedCode = """ - class C + {|IDE0026:int this[int i] { - int Bar() { return 0; } + get + { + return Bar(); + } + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int this[int i] => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + int this[int i] => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestMissingWithSetter() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestMissingWithSetter() + { + var code = """ + class C + { + int Bar() { return 0; } - int this[int i] + int this[int i] + { + get { - get - { - return Bar(); - } - - set - { - } + return Bar(); } - } - """; - await TestWithUseExpressionBody(code, code); - } - [Fact] - public async Task TestMissingOnSetter1() - { - var code = """ - class C - { - void Bar() { } - - int this[int i] + set { - set - { - Bar(); - } } } - """; - await TestWithUseExpressionBody(code, code); - } + } + """; + await TestWithUseExpressionBody(code, code); + } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + [Fact] + public async Task TestMissingOnSetter1() + { + var code = """ + class C + { + void Bar() { } - class C + int this[int i] { - {|IDE0026:int this[int i] + set { - get - { - throw new NotImplementedException(); - } - }|} - } - """; - var fixedCode = """ - using System; - - class C - { - int this[int i] => throw new NotImplementedException(); + Bar(); + } } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, code); + } - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + {|IDE0026:int this[int i] { - {|IDE0026:int this[int i] + get { - get - { - throw new NotImplementedException(); // comment - } - }|} - } - """; - var fixedCode = """ - using System; + throw new NotImplementedException(); + } + }|} + } + """; + var fixedCode = """ + using System; - class C - { - int this[int i] => throw new NotImplementedException(); // comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + class C + { + int this[int i] => throw new NotImplementedException(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - {|IDE0026:int this[int i] => Bar();|} - } - """; - var fixedCode = """ - class C + class C + { + {|IDE0026:int this[int i] { - int Bar() { return 0; } - - int this[int i] + get { - get - { - return Bar(); - } + throw new NotImplementedException(); // comment } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + }|} + } + """; + var fixedCode = """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20363")] - public async Task TestUseBlockBodyForAccessorEventWhenAccessorWantExpression1() - { - var code = """ - class C - { - int Bar() { return 0; } + class C + { + int this[int i] => throw new NotImplementedException(); // comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - {|IDE0026:int this[int i] => Bar();|} - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + int Bar() { return 0; } + + {|IDE0026:int this[int i] => Bar();|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - int this[int i] + int this[int i] + { + get { - get => Bar(); + return Bar(); } } - """; - await new VerifyCS.Test + } + """; + await TestWithUseBlockBody(code, fixedCode); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20363")] + public async Task TestUseBlockBodyForAccessorEventWhenAccessorWantExpression1() + { + var code = """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, - }, - NumberOfFixAllIterations = 2, - NumberOfIncrementalIterations = 2, - }.RunAsync(); - } + int Bar() { return 0; } - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + {|IDE0026:int this[int i] => Bar();|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - class C + int this[int i] { - {|IDE0026:int this[int i] => throw new NotImplementedException();|} + get => Bar(); } - """; - var fixedCode = """ - using System; + } + """; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, + }, + NumberOfFixAllIterations = 2, + NumberOfIncrementalIterations = 2, + }.RunAsync(); + } + + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; + + class C + { + {|IDE0026:int this[int i] => throw new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; - class C + class C + { + int this[int i] { - int this[int i] + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - class C - { - {|IDE0026:int this[int i] => throw new NotImplementedException();|} // comment - } - """; - var fixedCode = """ - using System; + class C + { + {|IDE0026:int this[int i] => throw new NotImplementedException();|} // comment + } + """; + var fixedCode = """ + using System; - class C + class C + { + int this[int i] { - int this[int i] + get { - get - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); // comment } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForLocalFunctionsAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForLocalFunctionsAnalyzerTests.cs index 3f32c500ac41d..3e7dc3d812008 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForLocalFunctionsAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForLocalFunctionsAnalyzerTests.cs @@ -13,934 +13,933 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForLocalFunctionsAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForLocalFunctionsAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.WhenPossible } } - }.RunAsync(); - } + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.WhenPossible } } + }.RunAsync(); + } - private static async Task TestWithUseExpressionBodyWhenOnSingleLine(string code, string fixedCode) + private static async Task TestWithUseExpressionBodyWhenOnSingleLine(string code, string fixedCode) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.WhenOnSingleLine } } - }.RunAsync(); - } + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.WhenOnSingleLine } } + }.RunAsync(); + } - private static async Task TestWithUseBlockBody(string code, string fixedCode, ReferenceAssemblies? referenceAssemblies = null) + private static async Task TestWithUseBlockBody(string code, string fixedCode, ReferenceAssemblies? referenceAssemblies = null) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.Never } }, + ReferenceAssemblies = referenceAssemblies ?? ReferenceAssemblies.Default, + }.RunAsync(); + } + + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.Never } }, - ReferenceAssemblies = referenceAssemblies ?? ReferenceAssemblies.Default, - }.RunAsync(); - } + void Test() { } - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C + void Goo() { - void Test() { } - - void Goo() + {|IDE0061:void Bar() { - {|IDE0061:void Bar() - { - Test(); - }|} - } + Test(); + }|} } - """; - var fixedCode = """ - class C - { - void Test() { } + } + """; + var fixedCode = """ + class C + { + void Test() { } - void Goo() - { - void Bar() => Test(); - } + void Goo() + { + void Bar() => Test(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody2() - { - var code = """ - class C - { - int Test() { return 0; } + [Fact] + public async Task TestUseExpressionBody2() + { + var code = """ + class C + { + int Test() { return 0; } - void Goo() + void Goo() + { + {|IDE0061:int Bar() { - {|IDE0061:int Bar() - { - return Test(); - }|} - } + return Test(); + }|} } - """; - var fixedCode = """ - class C - { - int Test() { return 0; } + } + """; + var fixedCode = """ + class C + { + int Test() { return 0; } - void Goo() - { - int Bar() => Test(); - } + void Goo() + { + int Bar() => Test(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + void Goo() { - void Goo() + {|IDE0061:int Bar() { - {|IDE0061:int Bar() - { - throw new NotImplementedException(); - }|} - } + throw new NotImplementedException(); + }|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - int Bar() => throw new NotImplementedException(); - } + int Bar() => throw new NotImplementedException(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - class C + class C + { + void Goo() { - void Goo() + {|IDE0061:int Bar() { - {|IDE0061:int Bar() - { - throw new NotImplementedException(); // comment - }|} - } + throw new NotImplementedException(); // comment + }|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - int Bar() => throw new NotImplementedException(); // comment - } + int Bar() => throw new NotImplementedException(); // comment } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBodyWhenOnSingleLineMissing() - { - var code = """ - class C + [Fact] + public async Task TestUseExpressionBodyWhenOnSingleLineMissing() + { + var code = """ + class C + { + void Goo() { - void Goo() + int Bar() { - int Bar() - { - return 1 + - 2 + - 3; - } + return 1 + + 2 + + 3; } } - """; - await TestWithUseExpressionBodyWhenOnSingleLine(code, code); - } + } + """; + await TestWithUseExpressionBodyWhenOnSingleLine(code, code); + } - [Fact] - public async Task TestUseExpressionBodyWhenOnSingleLine() - { - var code = """ - class C + [Fact] + public async Task TestUseExpressionBodyWhenOnSingleLine() + { + var code = """ + class C + { + void Goo() { - void Goo() + {|IDE0061:int Bar() { - {|IDE0061:int Bar() - { - return 1 + 2 + 3; - }|} - } + return 1 + 2 + 3; + }|} } - """; - var fixedCode = """ - class C + } + """; + var fixedCode = """ + class C + { + void Goo() { - void Goo() - { - int Bar() => 1 + 2 + 3; - } + int Bar() => 1 + 2 + 3; } - """; - await TestWithUseExpressionBodyWhenOnSingleLine(code, fixedCode); - } + } + """; + await TestWithUseExpressionBodyWhenOnSingleLine(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C - { - void Test() { } + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + void Test() { } - void Goo() - { - {|IDE0061:void Bar() => Test();|} - } - } - """; - var fixedCode = """ - class C + void Goo() { - void Test() { } - - void Goo() - { - void Bar() - { - Test(); - } - } + {|IDE0061:void Bar() => Test();|} } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + var fixedCode = """ + class C + { + void Test() { } - [Fact] - public async Task TestUseBlockBody2() - { - var code = """ - class C + void Goo() { - int Test() { return 0; } - - void Goo() + void Bar() { - {|IDE0061:int Bar() => Test();|} + Test(); } } - """; - var fixedCode = """ - class C + } + """; + await TestWithUseBlockBody(code, fixedCode); + } + + [Fact] + public async Task TestUseBlockBody2() + { + var code = """ + class C + { + int Test() { return 0; } + + void Goo() { - int Test() { return 0; } + {|IDE0061:int Bar() => Test();|} + } + } + """; + var fixedCode = """ + class C + { + int Test() { return 0; } - void Goo() + void Goo() + { + int Bar() { - int Bar() - { - return Test(); - } + return Test(); } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - {|IDE0061:int Bar() => throw new NotImplementedException();|} - } + {|IDE0061:int Bar() => throw new NotImplementedException();|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + void Goo() { - void Goo() + int Bar() { - int Bar() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - {|IDE0061:int Bar() => throw new NotImplementedException();|} // comment - } + {|IDE0061:int Bar() => throw new NotImplementedException();|} // comment } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C + class C + { + void Goo() { - void Goo() + int Bar() { - int Bar() - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); // comment } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestComments1() - { - var code = """ - class C - { - void Test() { } + [Fact] + public async Task TestComments1() + { + var code = """ + class C + { + void Test() { } - void Goo() - { - {|IDE0061:void Bar() - { - // Comment - Test(); - }|} - } - } - """; - var fixedCode = """ - class C + void Goo() { - void Test() { } - - void Goo() + {|IDE0061:void Bar() { - void Bar() => - // Comment - Test(); - } + // Comment + Test(); + }|} } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + var fixedCode = """ + class C + { + void Test() { } - [Fact] - public async Task TestComments2() - { - var code = """ - class C + void Goo() { - int Test() { return 0; } + void Bar() => + // Comment + Test(); + } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } + + [Fact] + public async Task TestComments2() + { + var code = """ + class C + { + int Test() { return 0; } - void Goo() + void Goo() + { + {|IDE0061:int Bar() { - {|IDE0061:int Bar() - { - // Comment - return Test(); - }|} - } + // Comment + return Test(); + }|} } - """; - var fixedCode = """ - class C - { - int Test() { return 0; } + } + """; + var fixedCode = """ + class C + { + int Test() { return 0; } - void Goo() - { - int Bar() => - // Comment - Test(); - } + void Goo() + { + int Bar() => + // Comment + Test(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestComments3() - { - var code = """ - using System; + [Fact] + public async Task TestComments3() + { + var code = """ + using System; - class C - { - Exception Test() { return new Exception(); } + class C + { + Exception Test() { return new Exception(); } - void Goo() + void Goo() + { + {|IDE0061:void Bar() { - {|IDE0061:void Bar() - { - // Comment - throw Test(); - }|} - } + // Comment + throw Test(); + }|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C - { - Exception Test() { return new Exception(); } + class C + { + Exception Test() { return new Exception(); } - void Goo() - { - void Bar() => - // Comment - throw Test(); - } + void Goo() + { + void Bar() => + // Comment + throw Test(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestComments4() - { - var code = """ - class C - { - void Test() { } + [Fact] + public async Task TestComments4() + { + var code = """ + class C + { + void Test() { } - void Goo() - { - {|IDE0061:void Bar() - { - Test(); // Comment - }|} - } - } - """; - var fixedCode = """ - class C + void Goo() { - void Test() { } - - void Goo() + {|IDE0061:void Bar() { - void Bar() => Test(); // Comment - } + Test(); // Comment + }|} } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + var fixedCode = """ + class C + { + void Test() { } - [Fact] - public async Task TestComments5() - { - var code = """ - class C + void Goo() { - int Test() { return 0; } + void Bar() => Test(); // Comment + } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } + + [Fact] + public async Task TestComments5() + { + var code = """ + class C + { + int Test() { return 0; } - void Goo() + void Goo() + { + {|IDE0061:int Bar() { - {|IDE0061:int Bar() - { - return Test(); // Comment - }|} - } + return Test(); // Comment + }|} } - """; - var fixedCode = """ - class C - { - int Test() { return 0; } + } + """; + var fixedCode = """ + class C + { + int Test() { return 0; } - void Goo() - { - int Bar() => Test(); // Comment - } + void Goo() + { + int Bar() => Test(); // Comment } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestComments6() - { - var code = """ - using System; + [Fact] + public async Task TestComments6() + { + var code = """ + using System; - class C - { - Exception Test() { return new Exception(); } + class C + { + Exception Test() { return new Exception(); } - void Goo() + void Goo() + { + {|IDE0061:void Bar() { - {|IDE0061:void Bar() - { - throw Test(); // Comment - }|} - } + throw Test(); // Comment + }|} } - """; - var fixedCode = """ - using System; + } + """; + var fixedCode = """ + using System; - class C - { - Exception Test() { return new Exception(); } + class C + { + Exception Test() { return new Exception(); } - void Goo() - { - void Bar() => throw Test(); // Comment - } + void Goo() + { + void Bar() => throw Test(); // Comment } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestDirectives1() - { - var code = """ - #define DEBUG - using System; + [Fact] + public async Task TestDirectives1() + { + var code = """ + #define DEBUG + using System; - class Program + class Program + { + void Method() { - void Method() + {|IDE0061:void Bar() { - {|IDE0061:void Bar() - { - #if DEBUG - Console.WriteLine(); - #endif - }|} - } + #if DEBUG + Console.WriteLine(); + #endif + }|} } - """; - var fixedCode = """ - #define DEBUG - using System; + } + """; + var fixedCode = """ + #define DEBUG + using System; - class Program + class Program + { + void Method() { - void Method() - { - void Bar() => - #if DEBUG - Console.WriteLine(); - #endif + void Bar() => + #if DEBUG + Console.WriteLine(); + #endif - } } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestDirectives2() - { - var code = """ - #define DEBUG - using System; + [Fact] + public async Task TestDirectives2() + { + var code = """ + #define DEBUG + using System; - class Program + class Program + { + void Method() { - void Method() + {|IDE0061:void Bar() { - {|IDE0061:void Bar() - { - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif - }|} - } + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif + }|} } - """; - var fixedCode = """ - #define DEBUG - using System; + } + """; + var fixedCode = """ + #define DEBUG + using System; - class Program + class Program + { + void Method() { - void Method() - { - void Bar() => - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif + void Bar() => + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif - } } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBodyAsync1() - { - var code = """ - using System.Threading.Tasks; + [Fact] + public async Task TestUseBlockBodyAsync1() + { + var code = """ + using System.Threading.Tasks; - class C + class C + { + async Task Goo() { - async Task Goo() - { - {|IDE0061:async Task Bar() => await Test();|} - } - - Task Test() { return Task.CompletedTask; } + {|IDE0061:async Task Bar() => await Test();|} } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C + Task Test() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; + + class C + { + async Task Goo() { - async Task Goo() + async Task Bar() { - async Task Bar() - { - await Test(); - } + await Test(); } - - Task Test() { return Task.CompletedTask; } } - """; - await TestWithUseBlockBody(code, fixedCode); - } - [Fact] - public async Task TestUseBlockBodyAsync2() - { - var code = """ - using System.Threading.Tasks; + Task Test() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - async void Goo() - { - {|IDE0061:async void Bar() => await Test();|} - } + [Fact] + public async Task TestUseBlockBodyAsync2() + { + var code = """ + using System.Threading.Tasks; - Task Test() { return Task.CompletedTask; } + class C + { + async void Goo() + { + {|IDE0061:async void Bar() => await Test();|} } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C + Task Test() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; + + class C + { + async void Goo() { - async void Goo() + async void Bar() { - async void Bar() - { - await Test(); - } + await Test(); } - - Task Test() { return Task.CompletedTask; } } - """; - await TestWithUseBlockBody(code, fixedCode); - } - [Fact] - public async Task TestUseBlockBodyAsync3() - { - var code = """ - using System.Threading.Tasks; + Task Test() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - void Goo() - { - {|IDE0061:async ValueTask Test() => await Bar();|} - } + [Fact] + public async Task TestUseBlockBodyAsync3() + { + var code = """ + using System.Threading.Tasks; - Task Bar() { return Task.CompletedTask; } + class C + { + void Goo() + { + {|IDE0061:async ValueTask Test() => await Bar();|} } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() + async ValueTask Test() { - async ValueTask Test() - { - await Bar(); - } + await Bar(); } - - Task Bar() { return Task.CompletedTask; } } - """; - await TestWithUseBlockBody(code, fixedCode, ReferenceAssemblies.NetStandard.NetStandard21); - } - [Fact] - public async Task TestUseBlockBodyAsync4() - { - var code = """ - using System.Threading.Tasks; + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode, ReferenceAssemblies.NetStandard.NetStandard21); + } - class C - { - void Goo() - { - {|IDE0061:Task Test() => Bar();|} - } + [Fact] + public async Task TestUseBlockBodyAsync4() + { + var code = """ + using System.Threading.Tasks; - Task Bar() { return Task.FromResult(0); } + class C + { + void Goo() + { + {|IDE0061:Task Test() => Bar();|} } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C + Task Bar() { return Task.FromResult(0); } + } + """; + var fixedCode = """ + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() + Task Test() { - Task Test() - { - return Bar(); - } + return Bar(); } - - Task Bar() { return Task.FromResult(0); } } - """; - await TestWithUseBlockBody(code, fixedCode); - } - [Fact] - public async Task TestUseBlockBodyAsync5() - { - var code = """ - using System.Threading.Tasks; + Task Bar() { return Task.FromResult(0); } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - void Goo() - { - {|IDE0061:Task Test() => Bar();|} - } + [Fact] + public async Task TestUseBlockBodyAsync5() + { + var code = """ + using System.Threading.Tasks; - Task Bar() { return Task.CompletedTask; } + class C + { + void Goo() + { + {|IDE0061:Task Test() => Bar();|} } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; + + class C + { + void Goo() { - void Goo() + Task Test() { - Task Test() - { - return Bar(); - } + return Bar(); } - - Task Bar() { return Task.CompletedTask; } } - """; - await TestWithUseBlockBody(code, fixedCode); - } - [Fact] - public async Task TestUseBlockBodyNestedLocalFunction() - { - var code = """ - class C - { - void NestedTest() { } + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } + + [Fact] + public async Task TestUseBlockBodyNestedLocalFunction() + { + var code = """ + class C + { + void NestedTest() { } - void Goo() + void Goo() + { + void Bar() { - void Bar() - { - {|IDE0061:void Test() => NestedTest();|} - } + {|IDE0061:void Test() => NestedTest();|} } } - """; - var fixedCode = """ - class C - { - void NestedTest() { } + } + """; + var fixedCode = """ + class C + { + void NestedTest() { } - void Goo() + void Goo() + { + void Bar() { - void Bar() + void Test() { - void Test() - { - NestedTest(); - } + NestedTest(); } } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBodyNestedLocalFunction() - { - var code = """ - class C - { - void NestedTest() { } + [Fact] + public async Task TestUseExpressionBodyNestedLocalFunction() + { + var code = """ + class C + { + void NestedTest() { } - void Goo() + void Goo() + { + void Bar() { - void Bar() + {|IDE0061:void Test() { - {|IDE0061:void Test() - { - NestedTest(); - }|} - } + NestedTest(); + }|} } } - """; - var fixedCode = """ - class C - { - void NestedTest() { } + } + """; + var fixedCode = """ + class C + { + void NestedTest() { } - void Goo() + void Goo() + { + void Bar() { - void Bar() - { - void Test() => NestedTest(); - } + void Test() => NestedTest(); } } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57570")] - public async Task TestUseExpressionBodyTopLevelStatment() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57570")] + public async Task TestUseExpressionBodyTopLevelStatment() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestState = { - TestState = + OutputKind = OutputKind.ConsoleApplication, + Sources = { - OutputKind = OutputKind.ConsoleApplication, - Sources = + """ + {|IDE0061:int Bar(int x) { - """ - {|IDE0061:int Bar(int x) - { - return x; - }|} - """ - }, + return x; + }|} + """ }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = - { - """ - int Bar(int x) => x; - """ - }, + """ + int Bar(int x) => x; + """ }, - LanguageVersion = LanguageVersion.CSharp9, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.WhenPossible } }, - }.RunAsync(); - } + }, + LanguageVersion = LanguageVersion.CSharp9, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.WhenPossible } }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57570")] - public async Task TestUseBlockBodyTopLevelStatment() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/57570")] + public async Task TestUseBlockBodyTopLevelStatment() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestState = { - TestState = + OutputKind = OutputKind.ConsoleApplication, + Sources = { - OutputKind = OutputKind.ConsoleApplication, - Sources = - { - """ - {|IDE0061:int Bar(int x) => x;|} - """ - }, + """ + {|IDE0061:int Bar(int x) => x;|} + """ }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = - { - """ - int Bar(int x) { return x; } - """ - }, + """ + int Bar(int x) { return x; } + """ }, - LanguageVersion = LanguageVersion.CSharp9, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.Never } }, - }.RunAsync(); - } + }, + LanguageVersion = LanguageVersion.CSharp9, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedLocalFunctions, ExpressionBodyPreference.Never } }, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForMethodsAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForMethodsAnalyzerTests.cs index 766b995597761..713d1647f1997 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForMethodsAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForMethodsAnalyzerTests.cs @@ -13,1132 +13,1131 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForMethodsAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForMethodsAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = version, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, ExpressionBodyPreference.WhenPossible } } - }.RunAsync(); - } + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = version, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, ExpressionBodyPreference.WhenPossible } } + }.RunAsync(); + } - private static async Task TestWithUseBlockBody(string code, string fixedCode, ReferenceAssemblies? referenceAssemblies = null) + private static async Task TestWithUseBlockBody(string code, string fixedCode, ReferenceAssemblies? referenceAssemblies = null) + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, ExpressionBodyPreference.Never } }, - ReferenceAssemblies = referenceAssemblies ?? ReferenceAssemblies.Default, - }.RunAsync(); - } + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, ExpressionBodyPreference.Never } }, + ReferenceAssemblies = referenceAssemblies ?? ReferenceAssemblies.Default, + }.RunAsync(); + } - [Fact] - public void TestOptionEditorConfig1() - { - var option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("true", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.WhenPossible, option.Value); - Assert.Equal(NotificationOption2.Silent, option.Notification); + [Fact] + public void TestOptionEditorConfig1() + { + var option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("true", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.WhenPossible, option.Value); + Assert.Equal(NotificationOption2.Silent, option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("false", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.Never, option.Value); - Assert.Equal(NotificationOption2.Silent, option.Notification); + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("false", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.Never, option.Value); + Assert.Equal(NotificationOption2.Silent, option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("when_on_single_line", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.WhenOnSingleLine, option.Value); - Assert.Equal(NotificationOption2.Silent, option.Notification); + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("when_on_single_line", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.WhenOnSingleLine, option.Value); + Assert.Equal(NotificationOption2.Silent, option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("true:blah", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.Never, option.Value); - Assert.Equal(NotificationOption2.Silent, option.Notification); + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("true:blah", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.Never, option.Value); + Assert.Equal(NotificationOption2.Silent, option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("when_blah:error", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.Never, option.Value); - Assert.Equal(NotificationOption2.Silent, option.Notification); + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("when_blah:error", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.Never, option.Value); + Assert.Equal(NotificationOption2.Silent, option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("false:error", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.Never, option.Value); - Assert.Equal(NotificationOption2.Error.WithIsExplicitlySpecified(true), option.Notification); + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("false:error", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.Never, option.Value); + Assert.Equal(NotificationOption2.Error.WithIsExplicitlySpecified(true), option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("true:warning", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.WhenPossible, option.Value); - Assert.Equal(NotificationOption2.Warning.WithIsExplicitlySpecified(true), option.Notification); + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("true:warning", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.WhenPossible, option.Value); + Assert.Equal(NotificationOption2.Warning.WithIsExplicitlySpecified(true), option.Notification); - option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("when_on_single_line:suggestion", CSharpCodeStyleOptions.NeverWithSilentEnforcement); - Assert.Equal(ExpressionBodyPreference.WhenOnSingleLine, option.Value); - Assert.Equal(NotificationOption2.Suggestion.WithIsExplicitlySpecified(true), option.Notification); - } + option = CSharpCodeStyleOptions.ParseExpressionBodyPreference("when_on_single_line:suggestion", CSharpCodeStyleOptions.NeverWithSilentEnforcement); + Assert.Equal(ExpressionBodyPreference.WhenOnSingleLine, option.Value); + Assert.Equal(NotificationOption2.Suggestion.WithIsExplicitlySpecified(true), option.Notification); + } - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - void Bar() => Bar(); + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C + { + void Bar() => Bar(); - {|IDE0022:void Goo() - { - Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0022:void Goo() { - void Bar() => Bar(); + Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + void Bar() => Bar(); - void Goo() => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + void Goo() => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody2() - { - var code = """ - class C - { - int Bar() => 0; + [Fact] + public async Task TestUseExpressionBody2() + { + var code = """ + class C + { + int Bar() => 0; - {|IDE0022:int Goo() - { - return Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0022:int Goo() { - int Bar() => 0; - - int Goo() => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + return Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() => 0; - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + int Goo() => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C - { - {|IDE0022:int Goo() - { - throw new NotImplementedException(); - }|} - } - """; - var fixedCode = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + {|IDE0022:int Goo() { - int Goo() => throw new NotImplementedException(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } - - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + throw new NotImplementedException(); + }|} + } + """; + var fixedCode = """ + using System; - class C - { - {|IDE0022:int Goo() - { - throw new NotImplementedException(); // comment - }|} - } - """; - var fixedCode = """ - using System; + class C + { + int Goo() => throw new NotImplementedException(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C - { - int Goo() => throw new NotImplementedException(); // comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C + class C + { + {|IDE0022:int Goo() { - void Bar() { } + throw new NotImplementedException(); // comment + }|} + } + """; + var fixedCode = """ + using System; - {|IDE0022:void Goo() => Bar();|} - } - """; - var fixedCode = """ - class C - { - void Bar() { } + class C + { + int Goo() => throw new NotImplementedException(); // comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - void Goo() - { - Bar(); - } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + void Bar() { } - [Fact] - public async Task TestUseBlockBody2() - { - var code = """ - class C - { - int Bar() { return 0; } + {|IDE0022:void Goo() => Bar();|} + } + """; + var fixedCode = """ + class C + { + void Bar() { } - {|IDE0022:int Goo() => Bar();|} - } - """; - var fixedCode = """ - class C + void Goo() { - int Bar() { return 0; } - - int Goo() - { - return Bar(); - } + Bar(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody2() + { + var code = """ + class C + { + int Bar() { return 0; } - class C - { - {|IDE0022:int Goo() => throw new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; + {|IDE0022:int Goo() => Bar();|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - class C + int Goo() { - int Goo() - { - throw new NotImplementedException(); - } + return Bar(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } - - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - {|IDE0022:int Goo() => throw new NotImplementedException();|} // comment - } - """; - var fixedCode = """ - using System; + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; - class C - { - int Goo() - { - throw new NotImplementedException(); // comment - } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + class C + { + {|IDE0022:int Goo() => throw new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; - [Fact] - public async Task TestComments1() - { - var code = """ - class C + class C + { + int Goo() { - void Bar() => Bar(); - - {|IDE0022:void Goo() - { - // Comment - Bar(); - }|} + throw new NotImplementedException(); } - """; - var fixedCode = """ - class C - { - void Bar() => Bar(); + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - void Goo() => - // Comment - Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - [Fact] - public async Task TestComments2() - { - var code = """ - class C - { - int Bar() => 0; + class C + { + {|IDE0022:int Goo() => throw new NotImplementedException();|} // comment + } + """; + var fixedCode = """ + using System; - {|IDE0022:int Goo() - { - // Comment - return Bar(); - }|} - } - """; - var fixedCode = """ - class C + class C + { + int Goo() { - int Bar() => 0; - - int Goo() => - // Comment - Bar(); + throw new NotImplementedException(); // comment } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestComments3() - { - var code = """ - using System; + [Fact] + public async Task TestComments1() + { + var code = """ + class C + { + void Bar() => Bar(); - class C + {|IDE0022:void Goo() { - Exception Bar() => new Exception(); + // Comment + Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + void Bar() => Bar(); + + void Goo() => + // Comment + Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - {|IDE0022:void Goo() - { - // Comment - throw Bar(); - }|} - } - """; - var fixedCode = """ - using System; + [Fact] + public async Task TestComments2() + { + var code = """ + class C + { + int Bar() => 0; - class C + {|IDE0022:int Goo() { - Exception Bar() => new Exception(); + // Comment + return Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() => 0; + + int Goo() => + // Comment + Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - void Goo() => - // Comment - throw Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestComments3() + { + var code = """ + using System; - [Fact] - public async Task TestComments4() - { - var code = """ - class C - { - void Bar() => Bar(); + class C + { + Exception Bar() => new Exception(); - {|IDE0022:void Goo() - { - Bar(); // Comment - }|} - } - """; - var fixedCode = """ - class C + {|IDE0022:void Goo() { - void Bar() => Bar(); + // Comment + throw Bar(); + }|} + } + """; + var fixedCode = """ + using System; - void Goo() => Bar(); // Comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + class C + { + Exception Bar() => new Exception(); + + void Goo() => + // Comment + throw Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestComments5() - { - var code = """ - class C - { - int Bar() => 0; + [Fact] + public async Task TestComments4() + { + var code = """ + class C + { + void Bar() => Bar(); - {|IDE0022:int Goo() - { - return Bar(); // Comment - }|} - } - """; - var fixedCode = """ - class C + {|IDE0022:void Goo() { - int Bar() => 0; + Bar(); // Comment + }|} + } + """; + var fixedCode = """ + class C + { + void Bar() => Bar(); - int Goo() => Bar(); // Comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + void Goo() => Bar(); // Comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestComments6() - { - var code = """ - using System; + [Fact] + public async Task TestComments5() + { + var code = """ + class C + { + int Bar() => 0; - class C + {|IDE0022:int Goo() { - Exception Bar() => new Exception(); - - {|IDE0022:void Goo() - { - throw Bar(); // Comment - }|} - } - """; - var fixedCode = """ - using System; + return Bar(); // Comment + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() => 0; - class C - { - Exception Bar() => new Exception(); + int Goo() => Bar(); // Comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - void Goo() => throw Bar(); // Comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestComments6() + { + var code = """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives1() - { - var code = """ - #define DEBUG - using System; + class C + { + Exception Bar() => new Exception(); - class Program + {|IDE0022:void Goo() { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(); - #endif - }|} - } - """; - var fixedCode = """ - #define DEBUG - using System; + throw Bar(); // Comment + }|} + } + """; + var fixedCode = """ + using System; - class Program - { - void Method() => - #if DEBUG - Console.WriteLine(); - #endif + class C + { + Exception Bar() => new Exception(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + void Goo() => throw Bar(); // Comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives2() - { - var code = """ - #define DEBUG - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives1() + { + var code = """ + #define DEBUG + using System; - class Program - { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif - }|} - } - """; - var fixedCode = """ - #define DEBUG - using System; + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(); + #endif + }|} + } + """; + var fixedCode = """ + #define DEBUG + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class Program - { - void Method() => - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives2() + { + var code = """ + #define DEBUG + using System; - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif + }|} + } + """; + var fixedCode = """ + #define DEBUG + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] - public async Task TestDirectives3() - { - var code = """ - #define DEBUG - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] + public async Task TestDirectives3() + { + var code = """ + #define DEBUG + using System; - class Program - { - void Method() - { - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - Console.WriteLine(2); - #endif - } - } - """; - await TestWithUseExpressionBody(code, code); - } + class Program + { + void Method() + { + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + Console.WriteLine(2); + #endif + } + } + """; + await TestWithUseExpressionBody(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives4() - { - var code = """ - #define RELEASE - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives4() + { + var code = """ + #define RELEASE + using System; - class Program - { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif - }|} - } - """; - var fixedCode = """ - #define RELEASE - using System; + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif + }|} + } + """; + var fixedCode = """ + #define RELEASE + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class Program - { - void Method() => - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives5() + { + var code = """ + #define DEBUG + using System; - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #else + throw new System.NotImplementedException(); + #endif + }|} + } + """; + var fixedCode = """ + #define DEBUG + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #else + throw new System.NotImplementedException(); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives5() - { - var code = """ - #define DEBUG - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives6() + { + var code = """ + #define RELEASE + using System; - class Program - { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #else - throw new System.NotImplementedException(); - #endif - }|} - } - """; - var fixedCode = """ - #define DEBUG - using System; + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #else + throw new System.NotImplementedException(); + #endif + }|} + } + """; + var fixedCode = """ + #define RELEASE + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #else + throw new System.NotImplementedException(); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class Program - { - void Method() => - #if DEBUG - Console.WriteLine(0); - #else - throw new System.NotImplementedException(); - #endif + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] + public async Task TestDirectives7() + { + var code = """ + #define DEBUG + using System; + class Program + { + void Method() + { + #if DEBUG + #endif + Console.WriteLine(0); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives6() - { - var code = """ - #define RELEASE - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] + public async Task TestDirectives8() + { + var code = """ + #define DEBUG + using System; - class Program + class Program + { + void Method() { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #else - throw new System.NotImplementedException(); - #endif - }|} + Console.WriteLine(0); + #if DEBUG + #endif } - """; - var fixedCode = """ - #define RELEASE - using System; + } + """; + await TestWithUseExpressionBody(code, code); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] + public async Task TestDirectives9() + { + var code = """ + #define DEBUG + using System; + + class Program + { + void Method() { - void Method() => - #if DEBUG - Console.WriteLine(0); - #else - throw new System.NotImplementedException(); - #endif + #if DEBUG + Console.WriteLine(0); + #else + Console.WriteLine(1); + #endif + #if DEBUG + #endif } - """; - await TestWithUseExpressionBody(code, fixedCode); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] - public async Task TestDirectives7() - { - var code = """ - #define DEBUG - using System; + } + """; + await TestWithUseExpressionBody(code, code); + } - class Program - { - void Method() - { - #if DEBUG - #endif - Console.WriteLine(0); - } - } - """; - await TestWithUseExpressionBody(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives10() + { + var code = """ + #define DEBUG + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] - public async Task TestDirectives8() - { - var code = """ - #define DEBUG - using System; + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #elif RELEASE + Console.WriteLine(1); + #else + Console.WriteLine(2); + #endif + }|} + } + """; + var fixedCode = """ + #define DEBUG + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #elif RELEASE + Console.WriteLine(1); + #else + Console.WriteLine(2); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class Program - { - void Method() - { - Console.WriteLine(0); - #if DEBUG - #endif - } - } - """; - await TestWithUseExpressionBody(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives11() + { + var code = """ + #define RELEASE + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/69783")] - public async Task TestDirectives9() - { - var code = """ - #define DEBUG - using System; + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #elif RELEASE + Console.WriteLine(1); + #else + Console.WriteLine(2); + #endif + }|} + } + """; + var fixedCode = """ + #define RELEASE + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #elif RELEASE + Console.WriteLine(1); + #else + Console.WriteLine(2); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class Program - { - void Method() - { - #if DEBUG - Console.WriteLine(0); - #else - Console.WriteLine(1); - #endif - - #if DEBUG - #endif - } - } - """; - await TestWithUseExpressionBody(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] + public async Task TestDirectives12() + { + var code = """ + #define OTHER + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives10() - { - var code = """ - #define DEBUG - using System; + class Program + { + {|IDE0022:void Method() + { + #if DEBUG + Console.WriteLine(0); + #elif RELEASE + Console.WriteLine(1); + #else + Console.WriteLine(2); + #endif + }|} + } + """; + var fixedCode = """ + #define OTHER + using System; + + class Program + { + void Method() => + #if DEBUG + Console.WriteLine(0); + #elif RELEASE + Console.WriteLine(1); + #else + Console.WriteLine(2); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp6() + { + var code = """ + using System; + class C + { + {|IDE0022:void M() {|CS8026:=>|} {|CS8026:throw|} new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; + class C + { + void M() { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #elif RELEASE - Console.WriteLine(1); - #else - Console.WriteLine(2); - #endif - }|} + throw new NotImplementedException(); } - """; - var fixedCode = """ - #define DEBUG - using System; + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp5); + } - class Program - { - void Method() => - #if DEBUG - Console.WriteLine(0); - #elif RELEASE - Console.WriteLine(1); - #else - Console.WriteLine(2); - #endif + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20352")] + public async Task TestDoNotOfferToConvertToBlockIfExpressionBodyPreferredIfCSharp6() + { + var code = """ + using System; + class C + { + int M() => 0; + } + """; + await TestWithUseExpressionBody(code, code, LanguageVersion.CSharp6); + } - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20352")] + public async Task TestOfferToConvertToExpressionIfCSharp6() + { + var code = """ + using System; + class C + { + {|IDE0022:int M() { return 0; }|} + } + """; + var fixedCode = """ + using System; + class C + { + int M() => 0; + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives11() - { - var code = """ - #define RELEASE - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20352")] + public async Task TestDoNotOfferToConvertToExpressionInCSharp6IfThrowExpression() + { + var code = """ + using System; + class C + { + // throw expressions not supported in C# 6. + void M() { throw new Exception(); } + } + """; + await TestWithUseExpressionBody(code, code, LanguageVersion.CSharp6); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp6_FixAll() + { + var code = """ + using System; + class C + { + {|IDE0022:void M() => {|CS8059:throw|} new NotImplementedException();|} + {|IDE0022:void M(int i) => {|CS8059:throw|} new NotImplementedException();|} + int M(bool b) => 0; + } + """; + var fixedCode = """ + using System; + class C + { + void M() { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #elif RELEASE - Console.WriteLine(1); - #else - Console.WriteLine(2); - #endif - }|} + throw new NotImplementedException(); } - """; - var fixedCode = """ - #define RELEASE - using System; - class Program + void M(int i) { - void Method() => - #if DEBUG - Console.WriteLine(0); - #elif RELEASE - Console.WriteLine(1); - #else - Console.WriteLine(2); - #endif - + throw new NotImplementedException(); } - """; - await TestWithUseExpressionBody(code, fixedCode); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17120")] - public async Task TestDirectives12() - { - var code = """ - #define OTHER - using System; + int M(bool b) => 0; + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); + } - class Program - { - {|IDE0022:void Method() - { - #if DEBUG - Console.WriteLine(0); - #elif RELEASE - Console.WriteLine(1); - #else - Console.WriteLine(2); - #endif - }|} - } - """; - var fixedCode = """ - #define OTHER - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] + public async Task TestUseBlockBodyAsync1() + { + var code = """ + using System.Threading.Tasks; - class Program - { - void Method() => - #if DEBUG - Console.WriteLine(0); - #elif RELEASE - Console.WriteLine(1); - #else - Console.WriteLine(2); - #endif + class C + { + {|IDE0022:async Task Goo() => await Bar();|} - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp6() - { - var code = """ - using System; - class C - { - {|IDE0022:void M() {|CS8026:=>|} {|CS8026:throw|} new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; - class C + class C + { + async Task Goo() { - void M() - { - throw new NotImplementedException(); - } + await Bar(); } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp5); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20352")] - public async Task TestDoNotOfferToConvertToBlockIfExpressionBodyPreferredIfCSharp6() - { - var code = """ - using System; - class C - { - int M() => 0; - } - """; - await TestWithUseExpressionBody(code, code, LanguageVersion.CSharp6); - } + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20352")] - public async Task TestOfferToConvertToExpressionIfCSharp6() - { - var code = """ - using System; - class C - { - {|IDE0022:int M() { return 0; }|} - } - """; - var fixedCode = """ - using System; - class C - { - int M() => 0; - } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] + public async Task TestUseBlockBodyAsync2() + { + var code = """ + using System.Threading.Tasks; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20352")] - public async Task TestDoNotOfferToConvertToExpressionInCSharp6IfThrowExpression() - { - var code = """ - using System; - class C - { - // throw expressions not supported in C# 6. - void M() { throw new Exception(); } - } - """; - await TestWithUseExpressionBody(code, code, LanguageVersion.CSharp6); - } + class C + { + {|IDE0022:async void Goo() => await Bar();|} - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfPriorToCSharp6_FixAll() - { - var code = """ - using System; - class C + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; + + class C + { + async void Goo() { - {|IDE0022:void M() => {|CS8059:throw|} new NotImplementedException();|} - {|IDE0022:void M(int i) => {|CS8059:throw|} new NotImplementedException();|} - int M(bool b) => 0; + await Bar(); } - """; - var fixedCode = """ - using System; - class C - { - void M() - { - throw new NotImplementedException(); - } - - void M(int i) - { - throw new NotImplementedException(); - } - int M(bool b) => 0; - } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] - public async Task TestUseBlockBodyAsync1() - { - var code = """ - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] + public async Task TestUseBlockBodyAsync3() + { + var code = """ + using System.Threading.Tasks; - class C - { - {|IDE0022:async Task Goo() => await Bar();|} + class C + { + {|IDE0022:async void Goo() => await Bar();|} - Task Bar() { return Task.CompletedTask; } - } - """; - var fixedCode = """ - using System.Threading.Tasks; + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; - class C + class C + { + async void Goo() { - async Task Goo() - { - await Bar(); - } - - Task Bar() { return Task.CompletedTask; } + await Bar(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] - public async Task TestUseBlockBodyAsync2() - { - var code = """ - using System.Threading.Tasks; - - class C - { - {|IDE0022:async void Goo() => await Bar();|} - Task Bar() { return Task.CompletedTask; } - } - """; - var fixedCode = """ - using System.Threading.Tasks; + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - async void Goo() - { - await Bar(); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] + public async Task TestUseBlockBodyAsync4() + { + var code = """ + using System.Threading.Tasks; - Task Bar() { return Task.CompletedTask; } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + class C + { + {|IDE0022:async ValueTask Goo() => await Bar();|} - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] - public async Task TestUseBlockBodyAsync3() - { - var code = """ - using System.Threading.Tasks; + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; - class C + class C + { + async ValueTask Goo() { - {|IDE0022:async void Goo() => await Bar();|} - - Task Bar() { return Task.CompletedTask; } + await Bar(); } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C - { - async void Goo() - { - await Bar(); - } - - Task Bar() { return Task.CompletedTask; } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode, ReferenceAssemblies.NetStandard.NetStandard21); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] - public async Task TestUseBlockBodyAsync4() - { - var code = """ - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] + public async Task TestUseBlockBodyAsync5() + { + var code = """ + using System.Threading.Tasks; - class C - { - {|IDE0022:async ValueTask Goo() => await Bar();|} + class C + { + {|IDE0022:async Task Goo() => await Bar();|} - Task Bar() { return Task.CompletedTask; } - } - """; - var fixedCode = """ - using System.Threading.Tasks; + Task Bar() { return Task.FromResult(0); } + } + """; + var fixedCode = """ + using System.Threading.Tasks; - class C + class C + { + async Task Goo() { - async ValueTask Goo() - { - await Bar(); - } - - Task Bar() { return Task.CompletedTask; } + return await Bar(); } - """; - await TestWithUseBlockBody(code, fixedCode, ReferenceAssemblies.NetStandard.NetStandard21); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] - public async Task TestUseBlockBodyAsync5() - { - var code = """ - using System.Threading.Tasks; - - class C - { - {|IDE0022:async Task Goo() => await Bar();|} - Task Bar() { return Task.FromResult(0); } - } - """; - var fixedCode = """ - using System.Threading.Tasks; + Task Bar() { return Task.FromResult(0); } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - class C - { - async Task Goo() - { - return await Bar(); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] + public async Task TestUseBlockBodyAsync6() + { + var code = """ + using System.Threading.Tasks; - Task Bar() { return Task.FromResult(0); } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + class C + { + {|IDE0022:Task Goo() => Bar();|} - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25202")] - public async Task TestUseBlockBodyAsync6() - { - var code = """ - using System.Threading.Tasks; + Task Bar() { return Task.CompletedTask; } + } + """; + var fixedCode = """ + using System.Threading.Tasks; - class C + class C + { + Task Goo() { - {|IDE0022:Task Goo() => Bar();|} - - Task Bar() { return Task.CompletedTask; } + return Bar(); } - """; - var fixedCode = """ - using System.Threading.Tasks; - class C - { - Task Goo() - { - return Bar(); - } - - Task Bar() { return Task.CompletedTask; } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + Task Bar() { return Task.CompletedTask; } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53532")] - public async Task TestUseBlockBodyTrivia1() - { - var code = """ - using System; - class C - { - {|IDE0022:void M() - // Test - => Console.WriteLine();|} - } - """; - var fixedCode = """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53532")] + public async Task TestUseBlockBodyTrivia1() + { + var code = """ + using System; + class C + { + {|IDE0022:void M() + // Test + => Console.WriteLine();|} + } + """; + var fixedCode = """ + using System; + class C + { + void M() { - void M() - { - // Test - Console.WriteLine(); - } + // Test + Console.WriteLine(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForOperatorsAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForOperatorsAnalyzerTests.cs index d588271e22479..accb7f6869a59 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForOperatorsAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForOperatorsAnalyzerTests.cs @@ -10,208 +10,207 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForOperatorsAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForOperatorsAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.WhenPossible } } - }.RunAsync(); - } + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.WhenPossible } } + }.RunAsync(); + } - private static async Task TestWithUseBlockBody(string code, string fixedCode) + private static async Task TestWithUseBlockBody(string code, string fixedCode) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.Never } } + }.RunAsync(); + } + + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = { { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, ExpressionBodyPreference.Never } } - }.RunAsync(); - } - - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - private static C Bar() { return new C(); } + private static C Bar() { return new C(); } - {|IDE0024:public static C operator {|CS0161:+|}(C c1, C c2) - { - Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0024:public static C operator {|CS0161:+|}(C c1, C c2) { - private static C Bar() { return new C(); } + Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + private static C Bar() { return new C(); } - public static C operator +(C c1, C c2) => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + public static C operator +(C c1, C c2) => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody2() - { - var code = """ - class C - { - private static C Bar() { return new C(); } + [Fact] + public async Task TestUseExpressionBody2() + { + var code = """ + class C + { + private static C Bar() { return new C(); } - {|IDE0024:public static C operator +(C c1, C c2) - { - return Bar(); - }|} - } - """; - var fixedCode = """ - class C + {|IDE0024:public static C operator +(C c1, C c2) { - private static C Bar() { return new C(); } - - public static C operator +(C c1, C c2) => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + return Bar(); + }|} + } + """; + var fixedCode = """ + class C + { + private static C Bar() { return new C(); } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + public static C operator +(C c1, C c2) => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C - { - {|IDE0024:public static C operator +(C c1, C c2) - { - throw new NotImplementedException(); - }|} - } - """; - var fixedCode = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + {|IDE0024:public static C operator +(C c1, C c2) { - public static C operator +(C c1, C c2) => throw new NotImplementedException(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + throw new NotImplementedException(); + }|} + } + """; + var fixedCode = """ + using System; + + class C + { + public static C operator +(C c1, C c2) => throw new NotImplementedException(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - class C + class C + { + {|IDE0024:public static C operator +(C c1, C c2) { - {|IDE0024:public static C operator +(C c1, C c2) - { - throw new NotImplementedException(); // comment - }|} - } - """; - var fixedCode = """ - using System; + throw new NotImplementedException(); // comment + }|} + } + """; + var fixedCode = """ + using System; + + class C + { + public static C operator +(C c1, C c2) => throw new NotImplementedException(); // comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class C - { - public static C operator +(C c1, C c2) => throw new NotImplementedException(); // comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + private static C Bar() { return new C(); } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C - { - private static C Bar() { return new C(); } + {|IDE0024:public static C operator +(C c1, C c2) => Bar();|} + } + """; + var fixedCode = """ + class C + { + private static C Bar() { return new C(); } - {|IDE0024:public static C operator +(C c1, C c2) => Bar();|} - } - """; - var fixedCode = """ - class C + public static C operator +(C c1, C c2) { - private static C Bar() { return new C(); } - - public static C operator +(C c1, C c2) - { - return Bar(); - } + return Bar(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; - class C - { - {|IDE0024:public static C operator +(C c1, C c2) => throw new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; + class C + { + {|IDE0024:public static C operator +(C c1, C c2) => throw new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; - class C + class C + { + public static C operator +(C c1, C c2) { - public static C operator +(C c1, C c2) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - class C - { - {|IDE0024:public static C operator +(C c1, C c2) => throw new NotImplementedException();|} // comment - } - """; - var fixedCode = """ - using System; + class C + { + {|IDE0024:public static C operator +(C c1, C c2) => throw new NotImplementedException();|} // comment + } + """; + var fixedCode = """ + using System; - class C + class C + { + public static C operator +(C c1, C c2) { - public static C operator +(C c1, C c2) - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); // comment } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForPropertiesAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForPropertiesAnalyzerTests.cs index 8c5b841f24a2c..9751be7a65ffa 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForPropertiesAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBody/UseExpressionBodyForPropertiesAnalyzerTests.cs @@ -13,572 +13,571 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody -{ - using VerifyCS = CSharpCodeFixVerifier< - UseExpressionBodyDiagnosticAnalyzer, - UseExpressionBodyCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +using VerifyCS = CSharpCodeFixVerifier< + UseExpressionBodyDiagnosticAnalyzer, + UseExpressionBodyCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForPropertiesAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForPropertiesAnalyzerTests +{ + private static async Task TestWithUseExpressionBody(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) { - private static async Task TestWithUseExpressionBody(string code, string fixedCode, LanguageVersion version = LanguageVersion.CSharp8) + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = version, + Options = { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = version, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.WhenPossible }, - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - }, - MarkupOptions = MarkupOptions.None, - }.RunAsync(); - } - - private static async Task TestWithUseBlockBody(string code, string fixedCode) + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.WhenPossible }, + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + }, + MarkupOptions = MarkupOptions.None, + }.RunAsync(); + } + + private static async Task TestWithUseBlockBody(string code, string fixedCode) + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = code, + FixedCode = fixedCode, + Options = { - TestCode = code, - FixedCode = fixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, - }, - MarkupOptions = MarkupOptions.None, - }.RunAsync(); - } - - [Fact] - public async Task TestUseExpressionBody1() - { - var code = """ - class C - { - int Bar() { return 0; } - - {|IDE0025:int Goo - { - get - { - return Bar(); - } - }|} - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.Never }, + }, + MarkupOptions = MarkupOptions.None, + }.RunAsync(); + } - int Goo => Bar(); - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact] + public async Task TestUseExpressionBody1() + { + var code = """ + class C + { + int Bar() { return 0; } - [Fact] - public async Task TestMissingWithSetter() - { - var code = """ - class C + {|IDE0025:int Goo { - int Bar() { return 0; } - - int Goo + get { - get - { - return Bar(); - } - - set - { - } + return Bar(); } - } - """; - await TestWithUseExpressionBody(code, code); - } + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } - [Fact] - public async Task TestMissingWithAttribute() - { - var code = """ - using System; + int Goo => Bar(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - class AAttribute : Attribute {} + [Fact] + public async Task TestMissingWithSetter() + { + var code = """ + class C + { + int Bar() { return 0; } - class C + int Goo { - int Bar() { return 0; } - - int Goo + get { - [A] - get - { - return Bar(); - } + return Bar(); } - } - """; - await TestWithUseExpressionBody(code, code); - } - [Fact] - public async Task TestMissingOnSetter1() - { - var code = """ - class C - { - void Bar() { } - - int Goo + set { - set - { - Bar(); - } } } - """; - await TestWithUseExpressionBody(code, code); - } + } + """; + await TestWithUseExpressionBody(code, code); + } - [Fact] - public async Task TestUseExpressionBody3() - { - var code = """ - using System; + [Fact] + public async Task TestMissingWithAttribute() + { + var code = """ + using System; + + class AAttribute : Attribute {} - class C + class C + { + int Bar() { return 0; } + + int Goo { - {|IDE0025:int Goo + [A] + get { - get - { - throw new NotImplementedException(); - } - }|} + return Bar(); + } } - """; - var fixedCode = """ - using System; + } + """; + await TestWithUseExpressionBody(code, code); + } - class C + [Fact] + public async Task TestMissingOnSetter1() + { + var code = """ + class C + { + void Bar() { } + + int Goo { - int Goo => throw new NotImplementedException(); + set + { + Bar(); + } } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, code); + } - [Fact] - public async Task TestUseExpressionBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseExpressionBody3() + { + var code = """ + using System; - class C + class C + { + {|IDE0025:int Goo { - {|IDE0025:int Goo + get { - get - { - throw new NotImplementedException(); // comment - } - }|} - } - """; - var fixedCode = """ - using System; + throw new NotImplementedException(); + } + }|} + } + """; + var fixedCode = """ + using System; - class C - { - int Goo => throw new NotImplementedException(); // comment - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + class C + { + int Goo => throw new NotImplementedException(); + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody1() - { - var code = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestUseExpressionBody4() + { + var code = """ + using System; - {|IDE0025:int Goo => Bar();|} - } - """; - var fixedCode = """ - class C + class C + { + {|IDE0025:int Goo { - int Bar() { return 0; } - - int Goo + get { - get - { - return Bar(); - } + throw new NotImplementedException(); // comment } - } - """; - await TestWithUseBlockBody(code, fixedCode); - } + }|} + } + """; + var fixedCode = """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20363")] - public async Task TestUseBlockBodyForAccessorEventWhenAccessorWantExpression1() - { - var code = """ - class C - { - int Bar() { return 0; } + class C + { + int Goo => throw new NotImplementedException(); // comment + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - {|IDE0025:int Goo => Bar();|} - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } + [Fact] + public async Task TestUseBlockBody1() + { + var code = """ + class C + { + int Bar() { return 0; } - int Goo + {|IDE0025:int Goo => Bar();|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } + + int Goo + { + get { - get => Bar(); + return Bar(); } } - """; - await new VerifyCS.Test + } + """; + await TestWithUseBlockBody(code, fixedCode); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20363")] + public async Task TestUseBlockBodyForAccessorEventWhenAccessorWantExpression1() + { + var code = """ + class C { - TestCode = code, - FixedCode = fixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, - { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, - }, - MarkupOptions = MarkupOptions.None, - NumberOfFixAllIterations = 2, - NumberOfIncrementalIterations = 2, - }.RunAsync(); - } - - [Fact] - public async Task TestUseBlockBody3() - { - var code = """ - using System; + int Bar() { return 0; } - class C + {|IDE0025:int Goo => Bar();|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } + + int Goo { - {|IDE0025:int Goo => throw new NotImplementedException();|} + get => Bar(); } - """; - var fixedCode = """ - using System; + } + """; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedProperties, ExpressionBodyPreference.Never }, + { CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, ExpressionBodyPreference.WhenPossible }, + }, + MarkupOptions = MarkupOptions.None, + NumberOfFixAllIterations = 2, + NumberOfIncrementalIterations = 2, + }.RunAsync(); + } - class C + [Fact] + public async Task TestUseBlockBody3() + { + var code = """ + using System; + + class C + { + {|IDE0025:int Goo => throw new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; + + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact] - public async Task TestUseBlockBody4() - { - var code = """ - using System; + [Fact] + public async Task TestUseBlockBody4() + { + var code = """ + using System; - class C - { - {|IDE0025:int Goo => throw new NotImplementedException();|} // comment - } - """; - var fixedCode = """ - using System; + class C + { + {|IDE0025:int Goo => throw new NotImplementedException();|} // comment + } + """; + var fixedCode = """ + using System; - class C + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); // comment - } + throw new NotImplementedException(); // comment } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16386")] - public async Task TestUseExpressionBodyKeepTrailingTrivia() - { - var code = """ - class C - { - private string _prop = "HELLO THERE!"; - {|IDE0025:public string Prop { get { return _prop; } }|} + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16386")] + public async Task TestUseExpressionBodyKeepTrailingTrivia() + { + var code = """ + class C + { + private string _prop = "HELLO THERE!"; + {|IDE0025:public string Prop { get { return _prop; } }|} + + public string OtherThing => "Pickles"; + } + """; + var fixedCode = """ + class C + { + private string _prop = "HELLO THERE!"; + public string Prop => _prop; - public string OtherThing => "Pickles"; - } - """; - var fixedCode = """ - class C - { - private string _prop = "HELLO THERE!"; - public string Prop => _prop; + public string OtherThing => "Pickles"; + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - public string OtherThing => "Pickles"; - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] + public async Task TestDirectivesInBlockBody1() + { + var code = """ + class C + { + int Bar() { return 0; } + int Baz() { return 0; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] - public async Task TestDirectivesInBlockBody1() - { - var code = """ - class C + {|IDE0025:int Goo { - int Bar() { return 0; } - int Baz() { return 0; } - - {|IDE0025:int Goo + get { - get - { - #if true - return Bar(); - #else - return Baz(); - #endif - } - }|} - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } - int Baz() { return 0; } - - int Goo => - #if true - Bar(); - #else - return Baz(); - #endif + #if true + return Bar(); + #else + return Baz(); + #endif + } + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } + int Baz() { return 0; } + + int Goo => + #if true + Bar(); + #else + return Baz(); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] + public async Task TestDirectivesInBlockBody2() + { + var code = """ + class C + { + int Bar() { return 0; } + int Baz() { return 0; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] - public async Task TestDirectivesInBlockBody2() - { - var code = """ - class C + {|IDE0025:int Goo { - int Bar() { return 0; } - int Baz() { return 0; } - - {|IDE0025:int Goo + get { - get - { - #if false - return Bar(); - #else - return Baz(); - #endif - } - }|} - } - """; - var fixedCode = """ - class C - { - int Bar() { return 0; } - int Baz() { return 0; } - - int Goo => - #if false - return Bar(); - #else - Baz(); - #endif + #if false + return Bar(); + #else + return Baz(); + #endif + } + }|} + } + """; + var fixedCode = """ + class C + { + int Bar() { return 0; } + int Baz() { return 0; } + + int Goo => + #if false + return Bar(); + #else + Baz(); + #endif + + } + """; + await TestWithUseExpressionBody(code, fixedCode); + } - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] + public async Task TestMissingWithDirectivesInExpressionBody1() + { + var code = """ + class C + { + int Bar() { return 0; } + int Baz() { return 0; } + + int Goo => + #if true + Bar(); + #else + Baz(); + #endif + } + """; + await TestWithUseBlockBody(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] - public async Task TestMissingWithDirectivesInExpressionBody1() - { - var code = """ - class C - { - int Bar() { return 0; } - int Baz() { return 0; } - - int Goo => - #if true - Bar(); - #else - Baz(); - #endif - } - """; - await TestWithUseBlockBody(code, code); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] + public async Task TestMissingWithDirectivesInExpressionBody2() + { + var code = """ + class C + { + int Bar() { return 0; } + int Baz() { return 0; } + + int Goo => + #if false + Bar(); + #else + Baz(); + #endif + } + """; + await TestWithUseBlockBody(code, code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19235")] - public async Task TestMissingWithDirectivesInExpressionBody2() - { - var code = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19193")] + public async Task TestMoveTriviaFromExpressionToReturnStatement() + { + // TODO: This test is unrelated to properties. It should be moved to UseExpressionBodyForMethodsAnalyzerTests. + var code = """ + class C + { + {|IDE0022:int Goo(int i) => + //comment + i * i;|} + } + """; + var fixedCode = """ + class C + { + int Goo(int i) { - int Bar() { return 0; } - int Baz() { return 0; } - - int Goo => - #if false - Bar(); - #else - Baz(); - #endif + //comment + return i * i; } - """; - await TestWithUseBlockBody(code, code); - } + } + """; + await TestWithUseBlockBody(code, fixedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19193")] - public async Task TestMoveTriviaFromExpressionToReturnStatement() - { - // TODO: This test is unrelated to properties. It should be moved to UseExpressionBodyForMethodsAnalyzerTests. - var code = """ - class C - { - {|IDE0022:int Goo(int i) => - //comment - i * i;|} - } - """; - var fixedCode = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfHasThrowExpressionPriorToCSharp7() + { + var code = """ + using System; + class C + { + {|IDE0025:int Goo => {|CS8059:throw|} new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; + class C + { + int Goo { - int Goo(int i) + get { - //comment - return i * i; + throw new NotImplementedException(); } } - """; - await TestWithUseBlockBody(code, fixedCode); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfHasThrowExpressionPriorToCSharp7() - { - var code = """ - using System; - class C - { - {|IDE0025:int Goo => {|CS8059:throw|} new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] + public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfHasThrowExpressionPriorToCSharp7_FixAll() + { + var code = """ + using System; + class C + { + {|IDE0025:int Goo => {|CS8059:throw|} new NotImplementedException();|} + {|IDE0025:int Bar => {|CS8059:throw|} new NotImplementedException();|} + } + """; + var fixedCode = """ + using System; + class C + { + int Goo { - int Goo + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20362")] - public async Task TestOfferToConvertToBlockEvenIfExpressionBodyPreferredIfHasThrowExpressionPriorToCSharp7_FixAll() - { - var code = """ - using System; - class C + int Bar { - {|IDE0025:int Goo => {|CS8059:throw|} new NotImplementedException();|} - {|IDE0025:int Bar => {|CS8059:throw|} new NotImplementedException();|} - } - """; - var fixedCode = """ - using System; - class C - { - int Goo - { - get - { - throw new NotImplementedException(); - } - } - - int Bar + get { - get - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """; - await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); - } + } + """; + await TestWithUseExpressionBody(code, fixedCode, LanguageVersion.CSharp6); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50181")] - public async Task TestUseExpressionBodyPreserveComments() - { - var code = """ - public class C - { - {|IDE0025:public long Length //N - { - // N = N1 + N2 - get { return 1 + 2; } - }|} - } - """; - var fixedCode = """ - public class C - { - public long Length //N - // N = N1 + N2 - => 1 + 2; - } - """; - await TestWithUseExpressionBody(code, fixedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50181")] + public async Task TestUseExpressionBodyPreserveComments() + { + var code = """ + public class C + { + {|IDE0025:public long Length //N + { + // N = N1 + N2 + get { return 1 + 2; } + }|} + } + """; + var fixedCode = """ + public class C + { + public long Length //N + // N = N1 + N2 + => 1 + 2; + } + """; + await TestWithUseExpressionBody(code, fixedCode); } } diff --git a/src/Analyzers/CSharp/Tests/UseExpressionBodyForLambda/UseExpressionBodyForLambdasAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseExpressionBodyForLambda/UseExpressionBodyForLambdasAnalyzerTests.cs index 2c452cb5458e7..b531650b83f71 100644 --- a/src/Analyzers/CSharp/Tests/UseExpressionBodyForLambda/UseExpressionBodyForLambdasAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseExpressionBodyForLambda/UseExpressionBodyForLambdasAnalyzerTests.cs @@ -13,1461 +13,1460 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExpressionBody; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] +public class UseExpressionBodyForLambdasAnalyzerTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] - public class UseExpressionBodyForLambdasAnalyzerTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseExpressionBodyForLambdasAnalyzerTests(ITestOutputHelper logger) + : base(logger) { - public UseExpressionBodyForLambdasAnalyzerTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new UseExpressionBodyForLambdaDiagnosticAnalyzer(), new UseExpressionBodyForLambdaCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new UseExpressionBodyForLambdaDiagnosticAnalyzer(), new UseExpressionBodyForLambdaCodeFixProvider()); - private OptionsCollection UseExpressionBody - => this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, CSharpCodeStyleOptions.WhenPossibleWithSuggestionEnforcement); + private OptionsCollection UseExpressionBody + => this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, CSharpCodeStyleOptions.WhenPossibleWithSuggestionEnforcement); - private OptionsCollection UseBlockBody - => this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, CSharpCodeStyleOptions.NeverWithSuggestionEnforcement); + private OptionsCollection UseBlockBody + => this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedLambdas, CSharpCodeStyleOptions.NeverWithSuggestionEnforcement); - [Fact] - public async Task UseExpressionBodyInMethod() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyInMethod() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func f = x [|=>|] { - Func f = x [|=>|] - { - return x.ToString(); - }; - } + return x.ToString(); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x => x.ToString(); - } + Func f = x => x.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task TestMissingWhenAlreadyAndExpressionBody() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingWhenAlreadyAndExpressionBody() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x [|=>|] x.ToString(); - } + Func f = x [|=>|] x.ToString(); } - """, new TestParameters(options: UseExpressionBody)); - } + } + """, new TestParameters(options: UseExpressionBody)); + } - [Fact] - public async Task UseBlockBodyInMethod() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyInMethod() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x [|=>|] x.ToString(); - } + Func f = x [|=>|] x.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func f = x => { - Func f = x => - { - return x.ToString(); - }; - } + return x.ToString(); + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task MissingWhenAlreadyHasBlockBody() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task MissingWhenAlreadyHasBlockBody() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x [|=>|] { return x.ToString(); }; - } + Func f = x [|=>|] { return x.ToString(); }; } - """, new TestParameters(options: UseBlockBody)); - } + } + """, new TestParameters(options: UseBlockBody)); + } - [Fact] - public async Task UseExpressionBodyInArgument() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyInArgument() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + TargetMethod(x [|=>|] { - TargetMethod(x [|=>|] - { - return x.ToString(); - }); - } - - void TargetMethod(Func targetParam) { } + return x.ToString(); + }); } - """, - """ - using System; - class C - { - void Goo() - { - TargetMethod(x => x.ToString()); - } + void TargetMethod(Func targetParam) { } + } + """, + """ + using System; - void TargetMethod(Func targetParam) { } + class C + { + void Goo() + { + TargetMethod(x => x.ToString()); } - """, options: UseExpressionBody); - } - [Fact] - public async Task UseBlockBodyInArgument() - { - await TestInRegularAndScriptAsync( - """ - using System; + void TargetMethod(Func targetParam) { } + } + """, options: UseExpressionBody); + } - class C - { - void Goo() - { - TargetMethod(x [|=>|] x.ToString()); - } + [Fact] + public async Task UseBlockBodyInArgument() + { + await TestInRegularAndScriptAsync( + """ + using System; - void TargetMethod(Func targetParam) { } + class C + { + void Goo() + { + TargetMethod(x [|=>|] x.ToString()); } - """, - """ - using System; - class C + void TargetMethod(Func targetParam) { } + } + """, + """ + using System; + + class C + { + void Goo() { - void Goo() + TargetMethod(x => { - TargetMethod(x => - { - return x.ToString(); - }); - } - - void TargetMethod(Func targetParam) { } + return x.ToString(); + }); } - """, options: UseBlockBody); - } - [Fact] - public async Task UseExpressionBodyFromReturnKeyword() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + void TargetMethod(Func targetParam) { } + } + """, options: UseBlockBody); + } - class C + [Fact] + public async Task UseExpressionBodyFromReturnKeyword() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void Goo() { - void Goo() + Func f = x => { - Func f = x => - { - [|return|] x.ToString(); - }; - } + [|return|] x.ToString(); + }; } - """, new TestParameters(options: UseExpressionBody)); - } + } + """, new TestParameters(options: UseExpressionBody)); + } - [Fact] - public async Task UseExpressionBodyFromLambdaOpeningBrace() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyFromLambdaOpeningBrace() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x => - [|{|] - return x.ToString(); - }; - } + Func f = x => + [|{|] + return x.ToString(); + }; } - """, new TestParameters(options: UseExpressionBody)); - } + } + """, new TestParameters(options: UseExpressionBody)); + } - [Fact] - public async Task UseExpressionBodyFromLambdaClosingBrace() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyFromLambdaClosingBrace() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func f = x => { - Func f = x => - { - return x.ToString(); - [|}|]; - } + return x.ToString(); + [|}|]; } - """, new TestParameters(options: UseExpressionBody)); - } + } + """, new TestParameters(options: UseExpressionBody)); + } - [Fact] - public async Task UseExpressionBodyThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func f = x [|=>|] { - Func f = x [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x => throw null; - } + Func f = x => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x [|=>|] throw null; - } + Func f = x [|=>|] throw null; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func f = x => { - Func f = x => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithVoidReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyWithVoidReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = x [|=>|] { - Action f = x [|=>|] - { - x.ToString(); - }; - } + x.ToString(); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = x => x.ToString(); - } + Action f = x => x.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithVoidReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyWithVoidReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = x [|=>|] { - Action f = x [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = x => throw null; - } + Action f = x => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithVoidReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyWithVoidReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = x [|=>|] x.ToString(); - } + Action f = x [|=>|] x.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = x => { - Action f = x => - { - x.ToString(); - }; - } + x.ToString(); + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyWithVoidReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyWithVoidReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = x [|=>|] throw null; - } + Action f = x [|=>|] throw null; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = x => { - Action f = x => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithAsyncVoidReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyWithAsyncVoidReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = async x [|=>|] { - Action f = async x [|=>|] - { - x.ToString(); - }; - } + x.ToString(); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = async x => x.ToString(); - } + Action f = async x => x.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithAsyncVoidReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyWithAsyncVoidReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = async x [|=>|] { - Action f = async x [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = async x => throw null; - } + Action f = async x => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithAsyncVoidReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyWithAsyncVoidReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = async x [|=>|] x.ToString(); - } + Action f = async x [|=>|] x.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = async x => { - Action f = async x => - { - x.ToString(); - }; - } + x.ToString(); + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyWithAsyncVoidReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyWithAsyncVoidReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Action f = async x [|=>|] throw null; - } + Action f = async x [|=>|] throw null; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Action f = async x => { - Action f = async x => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithTaskReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithTaskReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = () [|=>|] { - Func f = () [|=>|] - { - return Task.CompletedTask; - }; - } + return Task.CompletedTask; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = () => Task.CompletedTask; - } + Func f = () => Task.CompletedTask; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithTaskReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithTaskReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = () [|=>|] { - Func f = () [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = () => throw null; - } + Func f = () => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithTaskReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithTaskReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = () [|=>|] Task.CompletedTask; - } + Func f = () [|=>|] Task.CompletedTask; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = () => { - Func f = () => - { - return Task.CompletedTask; - }; - } + return Task.CompletedTask; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyWithTaskReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithTaskReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = () [|=>|] throw null; - } + Func f = () [|=>|] throw null; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = () => { - Func f = () => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithAsyncTaskReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithAsyncTaskReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = async () [|=>|] { - Func f = async () [|=>|] - { - await Task.CompletedTask; - }; - } + await Task.CompletedTask; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = async () => await Task.CompletedTask; - } + Func f = async () => await Task.CompletedTask; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithAsyncTaskReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithAsyncTaskReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = async () [|=>|] { - Func f = async () [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = async () => throw null; - } + Func f = async () => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithAsyncTaskReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithAsyncTaskReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = async () [|=>|] await Task.CompletedTask; - } + Func f = async () [|=>|] await Task.CompletedTask; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = async () => { - Func f = async () => - { - await Task.CompletedTask; - }; - } + await Task.CompletedTask; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyWithAsyncTaskReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithAsyncTaskReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = async () [|=>|] throw null; - } + Func f = async () [|=>|] throw null; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = async () => { - Func f = async () => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithTaskTReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithTaskTReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = x [|=>|] { - Func> f = x [|=>|] - { - return Task.FromResult(x.ToString()); - }; - } + return Task.FromResult(x.ToString()); + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x => Task.FromResult(x.ToString()); - } + Func> f = x => Task.FromResult(x.ToString()); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithTaskTReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithTaskTReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = x [|=>|] { - Func> f = x [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x => throw null; - } + Func> f = x => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithTaskTReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithTaskTReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x [|=>|] Task.FromResult(x.ToString()); - } + Func> f = x [|=>|] Task.FromResult(x.ToString()); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = x => { - Func> f = x => - { - return Task.FromResult(x.ToString()); - }; - } + return Task.FromResult(x.ToString()); + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyWithTaskTReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithTaskTReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x [|=>|] throw null; - } + Func> f = x [|=>|] throw null; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = x => { - Func> f = x => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithAsyncTaskTReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithAsyncTaskTReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = async x [|=>|] { - Func> f = async x [|=>|] - { - return await Task.FromResult(x.ToString()); - }; - } + return await Task.FromResult(x.ToString()); + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = async x => await Task.FromResult(x.ToString()); - } + Func> f = async x => await Task.FromResult(x.ToString()); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithAsyncTaskTReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithAsyncTaskTReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = async x [|=>|] { - Func> f = async x [|=>|] - { - throw null; - }; - } + throw null; + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = async x => throw null; - } + Func> f = async x => throw null; } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithAsyncTaskTReturn() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithAsyncTaskTReturn() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = async x [|=>|] await Task.FromResult(x.ToString()); - } + Func> f = async x [|=>|] await Task.FromResult(x.ToString()); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = async x => { - Func> f = async x => - { - return await Task.FromResult(x.ToString()); - }; - } + return await Task.FromResult(x.ToString()); + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyWithAsyncTaskTReturnThrowing() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithAsyncTaskTReturnThrowing() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = async x [|=>|] throw null; - } + Func> f = async x [|=>|] throw null; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func> f = async x => { - Func> f = async x => - { - throw null; - }; - } + throw null; + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyWithPrecedingComment() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithPrecedingComment() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = x [|=>|] { - Func f = x [|=>|] - { - // Comment - return x.ToString(); - }; - } + // Comment + return x.ToString(); + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x => - // Comment - x.ToString(); - } + Func f = x => + // Comment + x.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyWithEndingComment() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseExpressionBodyWithEndingComment() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = x [|=>|] { - Func f = x [|=>|] - { - return x.ToString(); // Comment - }; - } + return x.ToString(); // Comment + }; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x => x.ToString(); - } + Func f = x => x.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyWithEndingComment() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task UseBlockBodyWithEndingComment() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() - { - Func f = x [|=>|] x.ToString(); // Comment - } + Func f = x [|=>|] x.ToString(); // Comment } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void Goo() { - void Goo() + Func f = x => { - Func f = x => - { - return x.ToString(); - }; // Comment - } + return x.ToString(); + }; // Comment } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseExpressionBodyInMethod_FixAll1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyInMethod_FixAll1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = x {|FixAllInDocument:=>|} { - Func> f = x {|FixAllInDocument:=>|} + return y => { - return y => - { - return (x + y).ToString(); - }; + return (x + y).ToString(); }; - } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x => y => (x + y).ToString(); - } + Func> f = x => y => (x + y).ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseExpressionBodyInMethod_FixAll2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseExpressionBodyInMethod_FixAll2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = x => { - Func> f = x => + return y {|FixAllInDocument:=>|} { - return y {|FixAllInDocument:=>|} - { - return (x + y).ToString(); - }; + return (x + y).ToString(); }; - } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x => y => (x + y).ToString(); - } + Func> f = x => y => (x + y).ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task UseBlockBodyInMethod_FixAll1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyInMethod_FixAll1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x {|FixAllInDocument:=>|} y => (x + y).ToString(); - } + Func> f = x {|FixAllInDocument:=>|} y => (x + y).ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = x => { - Func> f = x => + return y => { - return y => - { - return (x + y).ToString(); - }; + return (x + y).ToString(); }; - } + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task UseBlockBodyInMethod_FixAll2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task UseBlockBodyInMethod_FixAll2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = x => y {|FixAllInDocument:=>|} (x + y).ToString(); - } + Func> f = x => y {|FixAllInDocument:=>|} (x + y).ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = x => { - Func> f = x => + return y => { - return y => - { - return (x + y).ToString(); - }; + return (x + y).ToString(); }; - } + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task FixAllNested1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllNested1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = a {|FixAllInDocument:=>|} { - Func> f = a {|FixAllInDocument:=>|} + return b => { - return b => - { - return b.ToString(); - }; + return b.ToString(); }; - } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = a => b => b.ToString(); - } + Func> f = a => b => b.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task FixAllNested2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllNested2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = a => { - Func> f = a => + return b {|FixAllInDocument:=>|} { - return b {|FixAllInDocument:=>|} - { - return b.ToString(); - }; + return b.ToString(); }; - } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = a => b => b.ToString(); - } + Func> f = a => b => b.ToString(); } - """, options: UseExpressionBody); - } + } + """, options: UseExpressionBody); + } - [Fact] - public async Task FixAllNested3() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllNested3() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = a {|FixAllInDocument:=>|} b => b.ToString(); - } + Func> f = a {|FixAllInDocument:=>|} b => b.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = a => { - Func> f = a => + return b => { - return b => - { - return b.ToString(); - }; + return b.ToString(); }; - } + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); + } - [Fact] - public async Task FixAllNested4() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllNested4() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void Goo() { - void Goo() - { - Func> f = a => b {|FixAllInDocument:=>|} b.ToString(); - } + Func> f = a => b {|FixAllInDocument:=>|} b.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void Goo() { - void Goo() + Func> f = a => { - Func> f = a => + return b => { - return b => - { - return b.ToString(); - }; + return b.ToString(); }; - } + }; } - """, options: UseBlockBody); - } + } + """, options: UseBlockBody); } } diff --git a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests.cs b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests.cs index 42e382a57ad32..5aa5e3acfcf70 100644 --- a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests.cs +++ b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests.cs @@ -15,2807 +15,2806 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseExplicitType +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseExplicitType; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitType)] +public partial class UseExplicitTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitType)] - public partial class UseExplicitTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseExplicitTypeTests(ITestOutputHelper logger) + : base(logger) { - public UseExplicitTypeTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseExplicitTypeDiagnosticAnalyzer(), new UseExplicitTypeCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseExplicitTypeDiagnosticAnalyzer(), new UseExplicitTypeCodeFixProvider()); - private readonly CodeStyleOption2 offWithSilent = new(false, NotificationOption2.Silent); - private readonly CodeStyleOption2 onWithInfo = new(true, NotificationOption2.Suggestion); - private readonly CodeStyleOption2 offWithInfo = new(false, NotificationOption2.Suggestion); - private readonly CodeStyleOption2 offWithWarning = new(false, NotificationOption2.Warning); - private readonly CodeStyleOption2 offWithError = new(false, NotificationOption2.Error); + private readonly CodeStyleOption2 offWithSilent = new(false, NotificationOption2.Silent); + private readonly CodeStyleOption2 onWithInfo = new(true, NotificationOption2.Suggestion); + private readonly CodeStyleOption2 offWithInfo = new(false, NotificationOption2.Suggestion); + private readonly CodeStyleOption2 offWithWarning = new(false, NotificationOption2.Warning); + private readonly CodeStyleOption2 offWithError = new(false, NotificationOption2.Error); - // specify all options explicitly to override defaults. - private OptionsCollection ExplicitTypeEverywhere() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; + // specify all options explicitly to override defaults. + private OptionsCollection ExplicitTypeEverywhere() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; - private OptionsCollection ExplicitTypeExceptWhereApparent() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; + private OptionsCollection ExplicitTypeExceptWhereApparent() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; - private OptionsCollection ExplicitTypeForBuiltInTypesOnly() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; + private OptionsCollection ExplicitTypeForBuiltInTypesOnly() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; - private OptionsCollection ExplicitTypeEnforcements() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithWarning }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithError }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; + private OptionsCollection ExplicitTypeEnforcements() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithWarning }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithError }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; - private OptionsCollection ExplicitTypeSilentEnforcement() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithSilent }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithSilent }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithSilent }, - }; + private OptionsCollection ExplicitTypeSilentEnforcement() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithSilent }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithSilent }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithSilent }, + }; - #region Error Cases + #region Error Cases - [Fact] - public async Task NotOnFieldDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnFieldDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program - { - [|var|] _myfield = 5; - } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + class Program + { + [|var|] _myfield = 5; + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnFieldLikeEvents() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnFieldLikeEvents() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program - { - public event [|var|] _myevent; - } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + class Program + { + public event [|var|] _myevent; + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task OnAnonymousMethodExpression() - { - var before = - """ - using System; + [Fact] + public async Task OnAnonymousMethodExpression() + { + var before = + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] comparer = delegate (string value) { - return value != "0"; - }; - } + [|var|] comparer = delegate (string value) { + return value != "0"; + }; } - """; - var after = - """ - using System; + } + """; + var after = + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - Func comparer = delegate (string value) { - return value != "0"; - }; - } + Func comparer = delegate (string value) { + return value != "0"; + }; } - """; - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact] - public async Task OnLambdaExpression() - { - var before = - """ - using System; + [Fact] + public async Task OnLambdaExpression() + { + var before = + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] x = (int y) => y * y; - } + [|var|] x = (int y) => y * y; } - """; - var after = - """ - using System; + } + """; + var after = + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - Func x = (int y) => y * y; - } + Func x = (int y) => y * y; } - """; - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact] - public async Task NotOnDeclarationWithMultipleDeclarators() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnDeclarationWithMultipleDeclarators() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] x = 5, y = x; - } + [|var|] x = 5, y = x; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnDeclarationWithoutInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnDeclarationWithoutInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] x; - } + [|var|] x; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotDuringConflicts() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotDuringConflicts() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] p = new var(); - } - - class var - { - } + [|var|] p = new var(); } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } - [Fact] - public async Task NotIfAlreadyExplicitlyTyped() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class Program + class var { - void Method() - { - [|Program|] p = new Program(); - } } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] - public async Task NotIfRefTypeAlreadyExplicitlyTyped() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotIfAlreadyExplicitlyTyped() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - struct Program + class Program + { + void Method() { - void Method() - { - ref [|Program|] p = Ref(); - } - ref Program Ref() => throw null; + [|Program|] p = new Program(); } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnRHS() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] + public async Task NotIfRefTypeAlreadyExplicitlyTyped() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + struct Program + { + void Method() { - void M() - { - var c = new [|var|](); - } + ref [|Program|] p = Ref(); } + ref Program Ref() => throw null; + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - class var + [Fact] + public async Task NotOnRHS() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + void M() { + var c = new [|var|](); } - """); - } + } - [Fact] - public async Task NotOnErrorSymbol() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + class var + { + } + """); + } + + [Fact] + public async Task NotOnErrorSymbol() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] x = new Goo(); - } + [|var|] x = new Goo(); } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29718")] - public async Task NotOnErrorConvertedType_ForEachVariableStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29718")] + public async Task NotOnErrorConvertedType_ForEachVariableStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + void M() { - void M() + // Error CS1061: 'KeyValuePair' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'KeyValuePair' could be found (are you missing a using directive or an assembly reference?) + // Error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'KeyValuePair', with 2 out parameters and a void return type. + foreach ([|var|] (key, value) in new Dictionary()) { - // Error CS1061: 'KeyValuePair' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'KeyValuePair' could be found (are you missing a using directive or an assembly reference?) - // Error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'KeyValuePair', with 2 out parameters and a void return type. - foreach ([|var|] (key, value) in new Dictionary()) - { - } } } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29718")] - public async Task NotOnErrorConvertedType_AssignmentExpressionStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29718")] + public async Task NotOnErrorConvertedType_AssignmentExpressionStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + void M(C c) { - void M(C c) - { - // Error CS1061: 'C' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?) - // Error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'C', with 2 out parameters and a void return type. - [|var|] (key, value) = c; - } + // Error CS1061: 'C' does not contain a definition for 'Deconstruct' and no accessible extension method 'Deconstruct' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?) + // Error CS8129: No suitable 'Deconstruct' instance or extension method was found for type 'C', with 2 out parameters and a void return type. + [|var|] (key, value) = c; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - #endregion + #endregion - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InArrayType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InArrayType() + { + var before = """ + class Program + { + void Method() { - void Method() - { - [|var|] x = new Program[0]; - } + [|var|] x = new Program[0]; } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method() { - void Method() - { - Program[] x = new Program[0]; - } + Program[] x = new Program[0]; } - """; - // The type is apparent and not intrinsic - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeExceptWhereApparent())); - } + } + """; + // The type is apparent and not intrinsic + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeExceptWhereApparent())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InArrayTypeWithIntrinsicType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InArrayTypeWithIntrinsicType() + { + var before = """ + class Program + { + void Method() { - void Method() - { - [|var|] x = new int[0]; - } + [|var|] x = new int[0]; } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method() { - void Method() - { - int[] x = new int[0]; - } + int[] x = new int[0]; } - """; - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); // preference for builtin types dominates - } + } + """; + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); // preference for builtin types dominates + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InNullableIntrinsicType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InNullableIntrinsicType() + { + var before = """ + class Program + { + void Method(int? x) { - void Method(int? x) - { - [|var|] y = x; - } + [|var|] y = x; } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(int? x) { - void Method(int? x) - { - int? y = x; - } + int? y = x; } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42986")] - public async Task InNativeIntIntrinsicType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42986")] + public async Task InNativeIntIntrinsicType() + { + var before = """ + class Program + { + void Method(nint x) { - void Method(nint x) - { - [|var|] y = x; - } + [|var|] y = x; } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(nint x) { - void Method(nint x) - { - nint y = x; - } + nint y = x; } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42986")] - public async Task InNativeUnsignedIntIntrinsicType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42986")] + public async Task InNativeUnsignedIntIntrinsicType() + { + var before = """ + class Program + { + void Method(nuint x) { - void Method(nuint x) - { - [|var|] y = x; - } + [|var|] y = x; } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(nuint x) { - void Method(nuint x) - { - nuint y = x; - } + nuint y = x; } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] - public async Task WithRefIntrinsicType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] + public async Task WithRefIntrinsicType() + { + var before = """ + class Program + { + void Method() { - void Method() - { - ref [|var|] y = Ref(); - } - ref int Ref() => throw null; + ref [|var|] y = Ref(); } - """; - var after = """ - class Program + ref int Ref() => throw null; + } + """; + var after = """ + class Program + { + void Method() { - void Method() - { - ref int y = Ref(); - } - ref int Ref() => throw null; + ref int y = Ref(); } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + ref int Ref() => throw null; + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] - public async Task WithRefIntrinsicTypeInForeach() - { - var before = """ - class E - { - public ref int Current => throw null; - public bool MoveNext() => throw null; - public E GetEnumerator() => throw null; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] + public async Task WithRefIntrinsicTypeInForeach() + { + var before = """ + class E + { + public ref int Current => throw null; + public bool MoveNext() => throw null; + public E GetEnumerator() => throw null; - void M() - { - foreach (ref [|var|] x in this) { } - } - } - """; - var after = """ - class E + void M() { - public ref int Current => throw null; - public bool MoveNext() => throw null; - public E GetEnumerator() => throw null; - - void M() - { - foreach (ref int x in this) { } - } + foreach (ref [|var|] x in this) { } } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + var after = """ + class E + { + public ref int Current => throw null; + public bool MoveNext() => throw null; + public E GetEnumerator() => throw null; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InArrayOfNullableIntrinsicType() - { - var before = """ - class Program - { - void Method(int?[] x) - { - [|var|] y = x; - } - } - """; - var after = """ - class Program + void M() { - void Method(int?[] x) - { - int?[] y = x; - } + foreach (ref int x in this) { } } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InNullableCustomType() - { - var before = """ - struct Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InArrayOfNullableIntrinsicType() + { + var before = """ + class Program + { + void Method(int?[] x) { - void Method(Program? x) - { - [|var|] y = x; - } + [|var|] y = x; } - """; - var after = """ - struct Program + } + """; + var after = """ + class Program + { + void Method(int?[] x) { - void Method(Program? x) - { - Program? y = x; - } + int?[] y = x; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NullableType() - { - var before = """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InNullableCustomType() + { + var before = """ + struct Program + { + void Method(Program? x) { - void Method(Program x) - { - [|var|] y = x; - y = null; - } + [|var|] y = x; } - """; - var after = """ - #nullable enable - class Program + } + """; + var after = """ + struct Program + { + void Method(Program? x) { - void Method(Program x) - { - Program? y = x; - y = null; - } + Program? y = x; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task ObliviousType() - { - var before = """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NullableType() + { + var before = """ + #nullable enable + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable disable - [|var|] y = x; - y = null; - } + [|var|] y = x; + y = null; } - """; - var after = """ - #nullable enable - class Program + } + """; + var after = """ + #nullable enable + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable disable - Program y = x; - y = null; - } + Program? y = x; + y = null; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NotNullableType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task ObliviousType() + { + var before = """ + #nullable enable + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable enable - [|var|] y = x; - y = null; - } + #nullable disable + [|var|] y = x; + y = null; } - """; - var after = """ - class Program + } + """; + var after = """ + #nullable enable + class Program + { + void Method(Program x) + { + #nullable disable + Program y = x; + y = null; + } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NotNullableType() + { + var before = """ + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable enable - Program? y = x; - y = null; - } + #nullable enable + [|var|] y = x; + y = null; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + var after = """ + class Program + { + void Method(Program x) + { + #nullable enable + Program? y = x; + y = null; + } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NullableType_OutVar() - { - var before = """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NullableType_OutVar() + { + var before = """ + #nullable enable + class Program + { + void Method(out Program? x) { - void Method(out Program? x) - { - Method(out [|var|] y1); - throw null!; - } + Method(out [|var|] y1); + throw null!; } - """; - var after = """ - #nullable enable - class Program + } + """; + var after = """ + #nullable enable + class Program + { + void Method(out Program? x) { - void Method(out Program? x) - { - Method(out Program? y1); - throw null!; - } + Method(out Program? y1); + throw null!; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NotNullableType_OutVar() - { - var before = """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NotNullableType_OutVar() + { + var before = """ + #nullable enable + class Program + { + void Method(out Program x) { - void Method(out Program x) - { - Method(out [|var|] y1); - throw null!; - } + Method(out [|var|] y1); + throw null!; } - """; - var after = """ - #nullable enable - class Program + } + """; + var after = """ + #nullable enable + class Program + { + void Method(out Program x) { - void Method(out Program x) - { - Method(out Program? y1); - throw null!; - } + Method(out Program? y1); + throw null!; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task ObliviousType_OutVar() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task ObliviousType_OutVar() + { + var before = """ + class Program + { + void Method(out Program x) { - void Method(out Program x) - { - Method(out [|var|] y1); - throw null; - } + Method(out [|var|] y1); + throw null; } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(out Program x) { - void Method(out Program x) - { - Method(out Program y1); - throw null; - } + Method(out Program y1); + throw null; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } - - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/40925")] - [WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - [WorkItem("https://github.com/dotnet/roslyn/issues/40925")] - public async Task NullableTypeAndNotNullableType_VarDeconstruction() - { - var before = """ - #nullable enable - class Program2 { } - class Program + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/40925")] + [WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + [WorkItem("https://github.com/dotnet/roslyn/issues/40925")] + public async Task NullableTypeAndNotNullableType_VarDeconstruction() + { + var before = """ + #nullable enable + class Program2 { } + class Program + { + void Method(Program? x, Program2 x2) { - void Method(Program? x, Program2 x2) - { - [|var|] (y1, y2) = (x, x2); - } + [|var|] (y1, y2) = (x, x2); } - """; - var after = """ - #nullable enable - class Program2 { } - class Program + } + """; + var after = """ + #nullable enable + class Program2 { } + class Program + { + void Method(Program? x, Program2 x2) { - void Method(Program? x, Program2 x2) - { - (Program? y1, Program2? y2) = (x, x2); - } + (Program? y1, Program2? y2) = (x, x2); } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task ObliviousType_VarDeconstruction() - { - var before = """ - #nullable enable - class Program2 { } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task ObliviousType_VarDeconstruction() + { + var before = """ + #nullable enable + class Program2 { } + class Program + { + void Method(Program x, Program2 x2) { - void Method(Program x, Program2 x2) - { - #nullable disable - [|var|] (y1, y2) = (x, x2); - } + #nullable disable + [|var|] (y1, y2) = (x, x2); } - """; - var after = """ - #nullable enable - class Program2 { } - class Program + } + """; + var after = """ + #nullable enable + class Program2 { } + class Program + { + void Method(Program x, Program2 x2) { - void Method(Program x, Program2 x2) - { - #nullable disable - (Program y1, Program2 y2) = (x, x2); - } + #nullable disable + (Program y1, Program2 y2) = (x, x2); } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task ObliviousType_Deconstruction() - { - var before = """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task ObliviousType_Deconstruction() + { + var before = """ + #nullable enable + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable disable - ([|var|] y1, Program y2) = (x, x); - } + #nullable disable + ([|var|] y1, Program y2) = (x, x); } - """; - var after = """ - #nullable enable - class Program + } + """; + var after = """ + #nullable enable + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable disable - (Program y1, Program y2) = (x, x); - } + #nullable disable + (Program y1, Program y2) = (x, x); } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NotNullableType_Deconstruction() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NotNullableType_Deconstruction() + { + var before = """ + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable enable - ([|var|] y1, Program y2) = (x, x); - } + #nullable enable + ([|var|] y1, Program y2) = (x, x); } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(Program x) { - void Method(Program x) - { - #nullable enable - (Program? y1, Program y2) = (x, x); - } + #nullable enable + (Program? y1, Program y2) = (x, x); } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NullableType_Deconstruction() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NullableType_Deconstruction() + { + var before = """ + class Program + { + void Method(Program? x) { - void Method(Program? x) - { - #nullable enable - ([|var|] y1, Program y2) = (x, x); - } + #nullable enable + ([|var|] y1, Program y2) = (x, x); } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(Program? x) { - void Method(Program? x) - { - #nullable enable - (Program? y1, Program y2) = (x, x); - } + #nullable enable + (Program? y1, Program y2) = (x, x); } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task ObliviousType_Foreach() - { - var before = """ - #nullable enable - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task ObliviousType_Foreach() + { + var before = """ + #nullable enable + class Program + { + void Method(System.Collections.Generic.IEnumerable x) { - void Method(System.Collections.Generic.IEnumerable x) + #nullable disable + foreach ([|var|] y in x) { - #nullable disable - foreach ([|var|] y in x) - { - } } } - """; - var after = """ - #nullable enable - class Program + } + """; + var after = """ + #nullable enable + class Program + { + void Method(System.Collections.Generic.IEnumerable x) { - void Method(System.Collections.Generic.IEnumerable x) + #nullable disable + foreach ([|Program|] y in x) { - #nullable disable - foreach ([|Program|] y in x) - { - } } } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NotNullableType_Foreach() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NotNullableType_Foreach() + { + var before = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable x) { - void Method(System.Collections.Generic.IEnumerable x) + #nullable enable + foreach ([|var|] y in x) { - #nullable enable - foreach ([|var|] y in x) - { - } } } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable x) { - void Method(System.Collections.Generic.IEnumerable x) + #nullable enable + foreach (Program? y in x) { - #nullable enable - foreach (Program? y in x) - { - } } } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NullableType_Foreach() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NullableType_Foreach() + { + var before = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable x) { - void Method(System.Collections.Generic.IEnumerable x) + #nullable enable + foreach ([|var|] y in x) { - #nullable enable - foreach ([|var|] y in x) - { - } } } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable x) { - void Method(System.Collections.Generic.IEnumerable x) + #nullable enable + foreach (Program? y in x) { - #nullable enable - foreach (Program? y in x) - { - } } } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/37491")] - [WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NotNullableType_ForeachVarDeconstruction() - { - // Semantic model doesn't yet handle var deconstruction foreach - // https://github.com/dotnet/roslyn/issues/37491 - // https://github.com/dotnet/roslyn/issues/35010 - var before = """ - class Program + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/37491")] + [WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NotNullableType_ForeachVarDeconstruction() + { + // Semantic model doesn't yet handle var deconstruction foreach + // https://github.com/dotnet/roslyn/issues/37491 + // https://github.com/dotnet/roslyn/issues/35010 + var before = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) { - void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) + #nullable enable + foreach ([|var|] (y1, y2) in x) { - #nullable enable - foreach ([|var|] (y1, y2) in x) - { - } } } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) { - void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) + #nullable enable + foreach ((Program? y1, Program? y2) in x) { - #nullable enable - foreach ((Program? y1, Program? y2) in x) - { - } } } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] - public async Task NotNullableType_ForeachDeconstruction() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40477")] + public async Task NotNullableType_ForeachDeconstruction() + { + var before = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) { - void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) + #nullable enable + foreach (([|var|] y1, var y2) in x) { - #nullable enable - foreach (([|var|] y1, var y2) in x) - { - } } } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) { - void Method(System.Collections.Generic.IEnumerable<(Program, Program)> x) + #nullable enable + foreach ((Program? y1, var y2) in x) { - #nullable enable - foreach ((Program? y1, var y2) in x) - { - } } } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InPointerTypeWithIntrinsicType() - { - var before = """ - unsafe class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InPointerTypeWithIntrinsicType() + { + var before = """ + unsafe class Program + { + void Method(int* y) { - void Method(int* y) - { - [|var|] x = y; - } + [|var|] x = y; } - """; - var after = """ - unsafe class Program + } + """; + var after = """ + unsafe class Program + { + void Method(int* y) { - void Method(int* y) - { - int* x = y; - } + int* x = y; } - """; - // The type is intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); // preference for builtin types dominates - } + } + """; + // The type is intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); // preference for builtin types dominates + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task InPointerTypeWithCustomType() - { - var before = """ - unsafe class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task InPointerTypeWithCustomType() + { + var before = """ + unsafe class Program + { + void Method(Program* y) { - void Method(Program* y) - { - [|var|] x = y; - } + [|var|] x = y; } - """; - var after = """ - unsafe class Program + } + """; + var after = """ + unsafe class Program + { + void Method(Program* y) { - void Method(Program* y) - { - Program* x = y; - } + Program* x = y; } - """; - // The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] - public async Task InOutParameter() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] + public async Task InOutParameter() + { + var before = """ + class Program + { + void Method(out int x) { - void Method(out int x) - { - Method(out [|var|] x); - } + Method(out [|var|] x); } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method(out int x) { - void Method(out int x) - { - Method(out int x); - } + Method(out int x); } - """; - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeForBuiltInTypesOnly()); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact] - public async Task NotOnDynamic() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnDynamic() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|dynamic|] x = 1; - } + [|dynamic|] x = 1; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnForEachVarWithAnonymousType() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq; + [Fact] + public async Task NotOnForEachVarWithAnonymousType() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq; - class Program + class Program + { + void Method() { - void Method() - { - var values = Enumerable.Range(1, 5).Select(i => new { Value = i }); + var values = Enumerable.Range(1, 5).Select(i => new { Value = i }); - foreach ([|var|] value in values) - { - Console.WriteLine(value.Value); - } + foreach ([|var|] value in values) + { + Console.WriteLine(value.Value); } } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnDeconstructionVarParens() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnDeconstructionVarParens() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - [|var|] (x, y) = new Program(); - } - void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + [|var|] (x, y) = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - (int x, string y) = new Program(); - } - void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + (int x, string y) = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task OnDeconstructionVar() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact] + public async Task OnDeconstructionVar() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - ([|var|] x, var y) = new Program(); - } - void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + ([|var|] x, var y) = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - (int x, var y) = new Program(); - } - void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + (int x, var y) = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnNestedDeconstructionVar() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnNestedDeconstructionVar() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - [|var|] (x, (y, z)) = new Program(); - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + [|var|] (x, (y, z)) = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - (int x, (int y, Program z)) = new Program(); - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + (int x, (int y, Program z)) = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnBadlyFormattedNestedDeconstructionVar() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnBadlyFormattedNestedDeconstructionVar() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - [|var|](x,(y,z)) = new Program(); - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + [|var|](x,(y,z)) = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - (int x, (int y, Program z)) = new Program(); - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + (int x, (int y, Program z)) = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnForeachNestedDeconstructionVar() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnForeachNestedDeconstructionVar() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - foreach ([|var|] (x, (y, z)) in new[] { new Program() } { } - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + foreach ([|var|] (x, (y, z)) in new[] { new Program() } { } } - """, """ - using System; - class Program + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - foreach ((int x, (int y, Program z)) in new[] { new Program() } { } - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + foreach ((int x, (int y, Program z)) in new[] { new Program() } { } } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnNestedDeconstructionVarWithTrivia() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnNestedDeconstructionVarWithTrivia() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - /*before*/[|var|]/*after*/ (/*x1*/x/*x2*/, /*yz1*/(/*y1*/y/*y2*/, /*z1*/z/*z2*/)/*yz2*/) /*end*/ = new Program(); - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + /*before*/[|var|]/*after*/ (/*x1*/x/*x2*/, /*yz1*/(/*y1*/y/*y2*/, /*z1*/z/*z2*/)/*yz2*/) /*end*/ = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - /*before*//*after*/(/*x1*/int x/*x2*/, /*yz1*/(/*y1*/int y/*y2*/, /*z1*/Program z/*z2*/)/*yz2*/) /*end*/ = new Program(); - } - void Deconstruct(out int i, out Program s) { i = 1; s = null; } + /*before*//*after*/(/*x1*/int x/*x2*/, /*yz1*/(/*y1*/int y/*y2*/, /*z1*/Program z/*z2*/)/*yz2*/) /*end*/ = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out Program s) { i = 1; s = null; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnDeconstructionVarWithDiscard() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnDeconstructionVarWithDiscard() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - [|var|] (x, _) = new Program(); - } - void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + [|var|] (x, _) = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - (int x, string _) = new Program(); - } - void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + (int x, string _) = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out string s) { i = 1; s = "hello"; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] - public async Task OnDeconstructionVarWithErrorType() - { - await TestInRegularAndScriptAsync( - """ - using System; - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23752")] + public async Task OnDeconstructionVarWithErrorType() + { + await TestInRegularAndScriptAsync( + """ + using System; + class Program + { + void M() { - void M() - { - [|var|] (x, y) = new Program(); - } - void Deconstruct(out int i, out Error s) { i = 1; s = null; } + [|var|] (x, y) = new Program(); } - """, """ - using System; - class Program + void Deconstruct(out int i, out Error s) { i = 1; s = null; } + } + """, """ + using System; + class Program + { + void M() { - void M() - { - (int x, Error y) = new Program(); - } - void Deconstruct(out int i, out Error s) { i = 1; s = null; } + (int x, Error y) = new Program(); } - """, options: ExplicitTypeEverywhere()); - } + void Deconstruct(out int i, out Error s) { i = 1; s = null; } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task OnForEachVarWithExplicitType() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Linq; + [Fact] + public async Task OnForEachVarWithExplicitType() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Linq; - class Program + class Program + { + void Method() { - void Method() - { - var values = Enumerable.Range(1, 5); + var values = Enumerable.Range(1, 5); - foreach ([|var|] value in values) - { - Console.WriteLine(value.Value); - } + foreach ([|var|] value in values) + { + Console.WriteLine(value.Value); } } - """, - """ - using System; - using System.Linq; + } + """, + """ + using System; + using System.Linq; - class Program + class Program + { + void Method() { - void Method() - { - var values = Enumerable.Range(1, 5); + var values = Enumerable.Range(1, 5); - foreach (int value in values) - { - Console.WriteLine(value.Value); - } + foreach (int value in values) + { + Console.WriteLine(value.Value); } } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task NotOnAnonymousType() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnAnonymousType() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] x = new { Amount = 108, Message = "Hello" }; - } + [|var|] x = new { Amount = 108, Message = "Hello" }; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnArrayOfAnonymousType() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnArrayOfAnonymousType() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] x = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 } }; - } + [|var|] x = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 } }; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnEnumerableOfAnonymousTypeFromAQueryExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; - using System.Linq; + [Fact] + public async Task NotOnEnumerableOfAnonymousTypeFromAQueryExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + using System.Linq; - class Program + class Program + { + void Method() { - void Method() - { - var products = new List(); - [|var|] productQuery = from prod in products - select new { prod.Color, prod.Price }; - } + var products = new List(); + [|var|] productQuery = from prod in products + select new { prod.Color, prod.Price }; } + } - class Product - { - public ConsoleColor Color { get; set; } - public int Price { get; set; } - } - """); - } + class Product + { + public ConsoleColor Color { get; set; } + public int Price { get; set; } + } + """); + } - [Fact] - public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeString() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeString() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] s = "hello"; - } + [|var|] s = "hello"; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - string s = "hello"; - } + string s = "hello"; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnIntrinsicType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnIntrinsicType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] s = 5; - } + [|var|] s = 5; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - int s = 5; - } + int s = 5; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnFrameworkType() - { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; + [Fact] + public async Task SuggestExplicitTypeOnFrameworkType() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - [|var|] c = new List(); - } + [|var|] c = new List(); } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - List c = new List(); - } + List c = new List(); } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnUserDefinedType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnUserDefinedType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - [|var|] c = new C(); - } + [|var|] c = new C(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - C c = new C(); - } + C c = new C(); } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnGenericType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnGenericType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] c = new C(); - } + [|var|] c = new C(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - C c = new C(); - } + C c = new C(); } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnSingleDimensionalArrayTypeWithNewOperator() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnSingleDimensionalArrayTypeWithNewOperator() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] n1 = new int[4] { 2, 4, 6, 8 }; - } + [|var|] n1 = new int[4] { 2, 4, 6, 8 }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - int[] n1 = new int[4] { 2, 4, 6, 8 }; - } + int[] n1 = new int[4] { 2, 4, 6, 8 }; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnSingleDimensionalArrayTypeWithNewOperator2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnSingleDimensionalArrayTypeWithNewOperator2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] n1 = new[] { 2, 4, 6, 8 }; - } + [|var|] n1 = new[] { 2, 4, 6, 8 }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - int[] n1 = new[] { 2, 4, 6, 8 }; - } + int[] n1 = new[] { 2, 4, 6, 8 }; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnSingleDimensionalJaggedArrayType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnSingleDimensionalJaggedArrayType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] cs = new[] { - new[] { 1, 2, 3, 4 }, - new[] { 5, 6, 7, 8 } - }; - } + [|var|] cs = new[] { + new[] { 1, 2, 3, 4 }, + new[] { 5, 6, 7, 8 } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - int[][] cs = new[] { - new[] { 1, 2, 3, 4 }, - new[] { 5, 6, 7, 8 } - }; - } + int[][] cs = new[] { + new[] { 1, 2, 3, 4 }, + new[] { 5, 6, 7, 8 } + }; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnDeclarationWithObjectInitializer() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnDeclarationWithObjectInitializer() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|var|] cc = new Customer { City = "Chennai" }; - } + [|var|] cc = new Customer { City = "Chennai" }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - Customer cc = new Customer { City = "Chennai" }; - } + Customer cc = new Customer { City = "Chennai" }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnDeclarationWithCollectionInitializer() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task SuggestExplicitTypeOnDeclarationWithCollectionInitializer() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - [|var|] digits = new List { 1, 2, 3 }; - } + [|var|] digits = new List { 1, 2, 3 }; } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - List digits = new List { 1, 2, 3 }; - } + List digits = new List { 1, 2, 3 }; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnDeclarationWithCollectionAndObjectInitializers() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task SuggestExplicitTypeOnDeclarationWithCollectionAndObjectInitializers() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + [|var|] cs = new List { - [|var|] cs = new List - { - new Customer { City = "Chennai" } - }; - } + new Customer { City = "Chennai" } + }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + List cs = new List { - List cs = new List - { - new Customer { City = "Chennai" } - }; - } + new Customer { City = "Chennai" } + }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnForStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnForStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() + for ([|var|] i = 0; i < 5; i++) { - for ([|var|] i = 0; i < 5; i++) - { - } } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() + for (int i = 0; i < 5; i++) { - for (int i = 0; i < 5; i++) - { - } } } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnForeachStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task SuggestExplicitTypeOnForeachStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + var l = new List { 1, 3, 5 }; + foreach ([|var|] item in l) { - var l = new List { 1, 3, 5 }; - foreach ([|var|] item in l) - { - } } } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + var l = new List { 1, 3, 5 }; + foreach (int item in l) { - var l = new List { 1, 3, 5 }; - foreach (int item in l) - { - } } } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnQueryExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; - using System.Linq; + [Fact] + public async Task SuggestExplicitTypeOnQueryExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + using System.Linq; - class C + class C + { + static void M() { - static void M() - { - var customers = new List(); - [|var|] expr = from c in customers - where c.City == "London" - select c; - } - - private class Customer - { - public string City { get; set; } - } + var customers = new List(); + [|var|] expr = from c in customers + where c.City == "London" + select c; } - } - """, - """ - using System; - using System.Collections.Generic; - using System.Linq; - class C + private class Customer { - static void M() - { - var customers = new List(); - IEnumerable expr = from c in customers - where c.City == "London" - select c; - } + public string City { get; set; } + } + } + } + """, + """ + using System; + using System.Collections.Generic; + using System.Linq; - private class Customer - { - public string City { get; set; } - } + class C + { + static void M() + { + var customers = new List(); + IEnumerable expr = from c in customers + where c.City == "London" + select c; } + + private class Customer + { + public string City { get; set; } } - """, options: ExplicitTypeEverywhere()); - } + } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeInUsingStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeInUsingStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() + using ([|var|] r = new Res()) { - using ([|var|] r = new Res()) - { - } } + } - private class Res : IDisposable + private class Res : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() + using (Res r = new Res()) { - using (Res r = new Res()) - { - } } + } - private class Res : IDisposable + private class Res : IDisposable + { + public void Dispose() { - public void Dispose() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnInterpolatedString() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnInterpolatedString() + { + await TestInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] s = $"Hello, {name}" - } + [|var|] s = $"Hello, {name}" } - """, - """ - using System; + } + """, + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - string s = $"Hello, {name}" - } + string s = $"Hello, {name}" } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnExplicitConversion() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnExplicitConversion() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - double x = 1234.7; - [|var|] a = (int)x; - } + double x = 1234.7; + [|var|] a = (int)x; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - double x = 1234.7; - int a = (int)x; - } + double x = 1234.7; + int a = (int)x; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeOnConditionalAccessExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeOnConditionalAccessExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - C obj = new C(); - [|var|] anotherObj = obj?.Test(); - } + C obj = new C(); + [|var|] anotherObj = obj?.Test(); + } - C Test() - { - return this; - } + C Test() + { + return this; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - C obj = new C(); - C anotherObj = obj?.Test(); - } + C obj = new C(); + C anotherObj = obj?.Test(); + } - C Test() - { - return this; - } + C Test() + { + return this; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeInCheckedExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeInCheckedExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - long number1 = int.MaxValue + 20L; - [|var|] intNumber = checked((int)number1); - } + long number1 = int.MaxValue + 20L; + [|var|] intNumber = checked((int)number1); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - long number1 = int.MaxValue + 20L; - int intNumber = checked((int)number1); - } + long number1 = int.MaxValue + 20L; + int intNumber = checked((int)number1); } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeInAwaitExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task SuggestExplicitTypeInAwaitExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public async void ProcessRead() { - public async void ProcessRead() - { - [|var|] text = await ReadTextAsync(null); - } + [|var|] text = await ReadTextAsync(null); + } - private async Task ReadTextAsync(string filePath) - { - return string.Empty; - } + private async Task ReadTextAsync(string filePath) + { + return string.Empty; } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public async void ProcessRead() { - public async void ProcessRead() - { - string text = await ReadTextAsync(null); - } + string text = await ReadTextAsync(null); + } - private async Task ReadTextAsync(string filePath) - { - return string.Empty; - } + private async Task ReadTextAsync(string filePath) + { + return string.Empty; } - """, options: ExplicitTypeEverywhere()); - } + } + """, options: ExplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestExplicitTypeInBuiltInNumericType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeInBuiltInNumericType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - [|var|] text = 1; - } + [|var|] text = 1; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - int text = 1; - } + int text = 1; } - """, options: ExplicitTypeForBuiltInTypesOnly()); - } + } + """, options: ExplicitTypeForBuiltInTypesOnly()); + } - [Fact] - public async Task SuggestExplicitTypeInBuiltInCharType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeInBuiltInCharType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - [|var|] text = GetChar(); - } - - public char GetChar() => 'c'; + [|var|] text = GetChar(); } - """, - """ - using System; - class C - { - public void ProcessRead() - { - char text = GetChar(); - } + public char GetChar() => 'c'; + } + """, + """ + using System; - public char GetChar() => 'c'; + class C + { + public void ProcessRead() + { + char text = GetChar(); } - """, options: ExplicitTypeForBuiltInTypesOnly()); - } - [Fact] - public async Task SuggestExplicitTypeInBuiltInType_string() - { - // though string isn't an intrinsic type per the compiler - // we in the IDE treat it as an intrinsic type for this feature. - await TestInRegularAndScriptAsync( - """ - using System; + public char GetChar() => 'c'; + } + """, options: ExplicitTypeForBuiltInTypesOnly()); + } + + [Fact] + public async Task SuggestExplicitTypeInBuiltInType_string() + { + // though string isn't an intrinsic type per the compiler + // we in the IDE treat it as an intrinsic type for this feature. + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - [|var|] text = string.Empty; - } + [|var|] text = string.Empty; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - string text = string.Empty; - } + string text = string.Empty; } - """, options: ExplicitTypeForBuiltInTypesOnly()); - } + } + """, options: ExplicitTypeForBuiltInTypesOnly()); + } - [Fact] - public async Task SuggestExplicitTypeInBuiltInType_object() - { - // object isn't an intrinsic type per the compiler - // we in the IDE treat it as an intrinsic type for this feature. - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestExplicitTypeInBuiltInType_object() + { + // object isn't an intrinsic type per the compiler + // we in the IDE treat it as an intrinsic type for this feature. + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - object j = new C(); - [|var|] text = j; - } + object j = new C(); + [|var|] text = j; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - object j = new C(); - object text = j; - } + object j = new C(); + object text = j; } - """, options: ExplicitTypeForBuiltInTypesOnly()); - } + } + """, options: ExplicitTypeForBuiltInTypesOnly()); + } - [Fact] - public async Task SuggestExplicitTypeNotificationLevelSilent() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestExplicitTypeNotificationLevelSilent() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|var|] n1 = new C(); - } + [|var|] n1 = new C(); } - """; - await TestDiagnosticInfoAsync(source, - options: ExplicitTypeSilentEnforcement(), - diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Hidden); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ExplicitTypeSilentEnforcement(), + diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Hidden); + } - [Fact] - public async Task SuggestExplicitTypeNotificationLevelInfo() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestExplicitTypeNotificationLevelInfo() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|var|] s = 5; - } + [|var|] s = 5; } - """; - await TestDiagnosticInfoAsync(source, - options: ExplicitTypeEnforcements(), - diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Info); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ExplicitTypeEnforcements(), + diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Info); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task SuggestExplicitTypeNotificationLevelWarning() - { - var source = - """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task SuggestExplicitTypeNotificationLevelWarning() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|var|] n1 = new[] { new C() }; // type not apparent and not intrinsic - } + [|var|] n1 = new[] { new C() }; // type not apparent and not intrinsic } - """; - await TestDiagnosticInfoAsync(source, - options: ExplicitTypeEnforcements(), - diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Warning); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ExplicitTypeEnforcements(), + diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Warning); + } - [Fact] - public async Task SuggestExplicitTypeNotificationLevelError() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestExplicitTypeNotificationLevelError() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|var|] n1 = new C(); - } + [|var|] n1 = new C(); } - """; - await TestDiagnosticInfoAsync(source, - options: ExplicitTypeEnforcements(), - diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Error); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ExplicitTypeEnforcements(), + diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Error); + } - [Fact] - public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeTuple() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeTuple() + { + await TestInRegularAndScriptAsync( + """ + class C + { + static void M() { - static void M() - { - [|var|] s = (1, "hello"); - } + [|var|] s = (1, "hello"); } - """, - """ - class C + } + """, + """ + class C + { + static void M() { - static void M() - { - (int, string) s = (1, "hello"); - } + (int, string) s = (1, "hello"); } - """, + } + """, options: ExplicitTypeEverywhere()); - } + } - [Fact] - public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeTupleWithNames() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeTupleWithNames() + { + await TestInRegularAndScriptAsync( + """ + class C + { + static void M() { - static void M() - { - [|var|] s = (a: 1, b: "hello"); - } + [|var|] s = (a: 1, b: "hello"); } - """, - """ - class C + } + """, + """ + class C + { + static void M() { - static void M() - { - (int a, string b) s = (a: 1, b: "hello"); - } + (int a, string b) s = (a: 1, b: "hello"); } - """, + } + """, options: ExplicitTypeEverywhere()); - } + } - [Fact] - public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeTupleWithOneName() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task SuggestExplicitTypeOnLocalWithIntrinsicTypeTupleWithOneName() + { + await TestInRegularAndScriptAsync( + """ + class C + { + static void M() { - static void M() - { - [|var|] s = (a: 1, "hello"); - } + [|var|] s = (a: 1, "hello"); } - """, - """ - class C + } + """, + """ + class C + { + static void M() { - static void M() - { - (int a, string) s = (a: 1, "hello"); - } + (int a, string) s = (a: 1, "hello"); } - """, + } + """, options: ExplicitTypeEverywhere()); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20437")] - public async Task SuggestExplicitTypeOnDeclarationExpressionSyntax() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20437")] + public async Task SuggestExplicitTypeOnDeclarationExpressionSyntax() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - DateTime.TryParse(string.Empty, [|out var|] date); - } + DateTime.TryParse(string.Empty, [|out var|] date); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - DateTime.TryParse(string.Empty, out DateTime date); - } + DateTime.TryParse(string.Empty, out DateTime date); } - """, + } + """, options: ExplicitTypeEverywhere()); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|String|] test = new String(' ', 4); - } + [|String|] test = new String(' ', 4); } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() + foreach ([|String|] test in new String[] { "test1", "test2" }) { - foreach ([|String|] test in new String[] { "test1", "test2" }) - { - } } } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames3() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames3() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() - { - [|Int32[]|] array = new[] { 1, 2, 3 }; - } + [|Int32[]|] array = new[] { 1, 2, 3 }; } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames4() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames4() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() + [|Int32[][]|] a = new Int32[][] { - [|Int32[][]|] a = new Int32[][] - { - new[] { 1, 2 }, - new[] { 3, 4 } - }; - } + new[] { 1, 2 }, + new[] { 3, 4 } + }; } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames5() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames5() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + void Main() { - void Main() - { - [|IEnumerable|] a = new List { 1, 2 }.Where(x => x > 1); - } + [|IEnumerable|] a = new List { 1, 2 }.Where(x => x > 1); } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames6() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames6() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() - { - String name = "name"; - [|String|] s = $"Hello, {name}" - } + String name = "name"; + [|String|] s = $"Hello, {name}" } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames7() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames7() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() - { - Object name = "name"; - [|String|] s = (String) name; - } + Object name = "name"; + [|String|] s = (String) name; } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames8() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames8() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public async void ProcessRead() { - public async void ProcessRead() - { - [|String|] text = await ReadTextAsync(null); - } + [|String|] text = await ReadTextAsync(null); + } - private async Task ReadTextAsync(string filePath) - { - return String.Empty; - } + private async Task ReadTextAsync(string filePath) + { + return String.Empty; } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames9() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames9() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() - { - String number = "12"; - Int32.TryParse(name, out [|Int32|] number) - } + String number = "12"; + Int32.TryParse(name, out [|Int32|] number) } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames10() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames10() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Main() { - void Main() + for ([|Int32|] i = 0; i < 5; i++) { - for ([|Int32|] i = 0; i < 5; i++) - { - } } } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] - public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames11() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20244")] + public async Task ExplicitTypeOnPredefinedTypesByTheirMetadataNames11() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + void Main() { - void Main() - { - [|List|] a = new List { 1, 2 }; - } + [|List|] a = new List { 1, 2 }; } - """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - } + } + """, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26923")] - public async Task NoSuggestionOnForeachCollectionExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26923")] + public async Task NoSuggestionOnForeachCollectionExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class Program + class Program + { + void Method(List var) { - void Method(List var) + foreach (int value in [|var|]) { - foreach (int value in [|var|]) - { - Console.WriteLine(value.Value); - } + Console.WriteLine(value.Value); } } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnConstVar() - { - // This error case is handled by a separate code fix (UseExplicitTypeForConst). - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task NotOnConstVar() + { + // This error case is handled by a separate code fix (UseExplicitTypeForConst). + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - const [|var|] v = 0; - } + const [|var|] v = 0; } - """, new TestParameters(options: ExplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ExplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task WithNormalFuncSynthesizedLambdaType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task WithNormalFuncSynthesizedLambdaType() + { + var before = """ + class Program + { + void Method() { - void Method() - { - [|var|] x = (int i) => i.ToString(); - } + [|var|] x = (int i) => i.ToString(); } - """; - var after = """ - class Program + } + """; + var after = """ + class Program + { + void Method() { - void Method() - { - System.Func x = (int i) => i.ToString(); - } + System.Func x = (int i) => i.ToString(); } - """; - // The type is not apparent and not intrinsic - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); - } + } + """; + // The type is not apparent and not intrinsic + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestInRegularAndScriptAsync(before, after, options: ExplicitTypeExceptWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] - public async Task WithAnonymousSynthesizedLambdaType() - { - var before = """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23907")] + public async Task WithAnonymousSynthesizedLambdaType() + { + var before = """ + class Program + { + void Method() { - void Method() - { - [|var|] x = (ref int i) => i.ToString(); - } + [|var|] x = (ref int i) => i.ToString(); } - """; - // The type is apparent and not intrinsic - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeEverywhere())); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeExceptWhereApparent())); - } + } + """; + // The type is apparent and not intrinsic + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeEverywhere())); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeForBuiltInTypesOnly())); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ExplicitTypeExceptWhereApparent())); } } diff --git a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests_FixAllTests.cs index 1e574440d84a0..13720b33529d7 100644 --- a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseExplicitTypeTests_FixAllTests.cs @@ -8,412 +8,411 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseExplicitType +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseExplicitType; + +public partial class UseExplicitTypeTests { - public partial class UseExplicitTypeTests + #region "Fix all occurrences tests" + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocumentScope_PreferExplicitTypeEverywhere() { - #region "Fix all occurrences tests" - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocumentScope_PreferExplicitTypeEverywhere() - { - var input = """ - - - - using System; - - class Program + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInDocument:var|} i1 = 0; - var p = new Program(); - var tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + {|FixAllInDocument:var|} i1 = 0; + var p = new Program(); + var tuple = Tuple.Create(true, 1); - class Program2 - { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + return i1; } - - - - - using System; - - class Program2 + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program p = new Program(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); - class Program2 - { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + return i1; } - - - - - using System; - - class Program2 + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + int i1 = 0; + Program p = new Program(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeEverywhere()); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject_PreferExplicitTypeEverywhere() - { - var input = """ - - - - using System; - - class Program + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInProject:var|} i1 = 0; - var p = new Program(); - var tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); - class Program2 + return i1; + } + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i2 = 0; - var p2 = new Program2(); - var tuple2 = Tuple.Create(true, 1); - - return i2; - } + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - - using System; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeEverywhere()); + } - class Program2 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject_PreferExplicitTypeEverywhere() + { + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i3 = 0; - Program2 p3 = new Program2(); - Tuple<bool, int> tuple3 = Tuple.Create(true, 1); - - return i3; - } + {|FixAllInProject:var|} i1 = 0; + var p = new Program(); + var tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program p = new Program(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + var i2 = 0; + var p2 = new Program2(); + var tuple2 = Tuple.Create(true, 1); - class Program2 - { - static int F(int x, int y) - { - int i2 = 0; - Program2 p2 = new Program2(); - Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - - return i2; - } + return i2; } - - - - - using System; - - class Program2 + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i3 = 0; - Program2 p3 = new Program2(); - Tuple<bool, int> tuple3 = Tuple.Create(true, 1); - - return i3; - } + int i3 = 0; + Program2 p3 = new Program2(); + Tuple<bool, int> tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeEverywhere()); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution_PreferExplicitTypeEverywhere() - { - var input = """ - - - - using System; - - class Program + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInSolution:var|} i1 = 0; - var p = new Program(); - var tuple = Tuple.Create(true, 1); - - return i1; - } + int i1 = 0; + Program p = new Program(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - using System; + } + + + using System; + + class Program2 + { + static int F(int x, int y) + { + int i2 = 0; + Program2 p2 = new Program2(); + Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - class Program2 + return i2; + } + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i2 = 0; - var p2 = new Program2(); - var tuple2 = Tuple.Create(true, 1); - - return i2; - } + int i3 = 0; + Program2 p3 = new Program2(); + Tuple<bool, int> tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - - using System; + } + + + + """; - class Program2 + await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeEverywhere()); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution_PreferExplicitTypeEverywhere() + { + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i3 = 0; - var p3 = new Program2(); - var tuple3 = Tuple.Create(true, 1); - - return i3; - } + {|FixAllInSolution:var|} i1 = 0; + var p = new Program(); + var tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program p = new Program(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + var i2 = 0; + var p2 = new Program2(); + var tuple2 = Tuple.Create(true, 1); - class Program2 + return i2; + } + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i2 = 0; - Program2 p2 = new Program2(); - Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - - return i2; - } + var i3 = 0; + var p3 = new Program2(); + var tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - - using System; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) + { + int i1 = 0; + Program p = new Program(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); - class Program2 + return i1; + } + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i3 = 0; - Program2 p3 = new Program2(); - Tuple<bool, int> tuple3 = Tuple.Create(true, 1); - - return i3; - } + int i2 = 0; + Program2 p2 = new Program2(); + Tuple<bool, int> tuple2 = Tuple.Create(true, 1); + + return i2; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeEverywhere()); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocumentScope_PreferExplicitTypeExceptWhereApparent() - { - var input = """ - - - - using System; - - class Program + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInDocument:var|} p = this; - var i1 = 0; - var tuple = Tuple.Create(true, 1); - - return i1; - } + int i3 = 0; + Program2 p3 = new Program2(); + Tuple<bool, int> tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeEverywhere()); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocumentScope_PreferExplicitTypeExceptWhereApparent() + { + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - Program p = this; - int i1 = 0; - var tuple = Tuple.Create(true, 1); - - return i1; - } + {|FixAllInDocument:var|} p = this; + var i1 = 0; + var tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) + { + Program p = this; + int i1 = 0; + var tuple = Tuple.Create(true, 1); - await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeExceptWhereApparent()); - } + return i1; + } + } + + + + """; - #endregion + await TestInRegularAndScriptAsync(input, expected, options: ExplicitTypeExceptWhereApparent()); } + + #endregion } diff --git a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs index a2e9068b26ff4..d7336ad05a658 100644 --- a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs +++ b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests.cs @@ -16,3314 +16,3313 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseImplicitType +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseImplicitType; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] +public partial class UseImplicitTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - public partial class UseImplicitTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseImplicitTypeTests(ITestOutputHelper? logger = null) + : base(logger) { - public UseImplicitTypeTests(ITestOutputHelper? logger = null) - : base(logger) + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseImplicitTypeDiagnosticAnalyzer(), new UseImplicitTypeCodeFixProvider()); + + private static readonly CodeStyleOption2 onWithSilent = new(true, NotificationOption2.Silent); + private static readonly CodeStyleOption2 onWithInfo = new(true, NotificationOption2.Suggestion); + private static readonly CodeStyleOption2 offWithInfo = new(false, NotificationOption2.Suggestion); + private static readonly CodeStyleOption2 onWithWarning = new(true, NotificationOption2.Warning); + private static readonly CodeStyleOption2 onWithError = new(true, NotificationOption2.Error); + + // specify all options explicitly to override defaults. + internal OptionsCollection ImplicitTypeEverywhere() + => new(GetLanguage()) { - } + { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, + }; - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseImplicitTypeDiagnosticAnalyzer(), new UseImplicitTypeCodeFixProvider()); + private OptionsCollection ImplicitTypeWhereApparent() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; - private static readonly CodeStyleOption2 onWithSilent = new(true, NotificationOption2.Silent); - private static readonly CodeStyleOption2 onWithInfo = new(true, NotificationOption2.Suggestion); - private static readonly CodeStyleOption2 offWithInfo = new(false, NotificationOption2.Suggestion); - private static readonly CodeStyleOption2 onWithWarning = new(true, NotificationOption2.Warning); - private static readonly CodeStyleOption2 onWithError = new(true, NotificationOption2.Error); + private OptionsCollection ImplicitTypeWhereApparentAndForIntrinsics() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, + }; - // specify all options explicitly to override defaults. - internal OptionsCollection ImplicitTypeEverywhere() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, - }; + internal OptionsCollection ImplicitTypeButKeepIntrinsics() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + }; - private OptionsCollection ImplicitTypeWhereApparent() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; + private OptionsCollection ImplicitTypeEnforcements() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithWarning }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithError }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, + }; - private OptionsCollection ImplicitTypeWhereApparentAndForIntrinsics() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, - }; + private OptionsCollection ImplicitTypeSilentEnforcement() + => new(GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithSilent }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithSilent }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithSilent }, + }; - internal OptionsCollection ImplicitTypeButKeepIntrinsics() - => new(GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - }; + [Fact] + public async Task NotOnFieldDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - private OptionsCollection ImplicitTypeEnforcements() - => new(GetLanguage()) + class Program { - { CSharpCodeStyleOptions.VarElsewhere, onWithWarning }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithError }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, - }; + [|int|] _myfield = 5; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } + + [Fact] + public async Task NotOnFieldLikeEvents() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - private OptionsCollection ImplicitTypeSilentEnforcement() - => new(GetLanguage()) + class Program { - { CSharpCodeStyleOptions.VarElsewhere, onWithSilent }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithSilent }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithSilent }, - }; + public event [|D|] _myevent; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnFieldDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnConstants() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - [|int|] _myfield = 5; + const [|int|] x = 5; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnFieldLikeEvents() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnNullLiteral() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - public event [|D|] _myevent; + [|Program|] x = null; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } - - [Fact] - public async Task NotOnConstants() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] + public async Task NotOnRefVar() + { + await TestMissingInRegularAndScriptAsync(""" + class Program + { + void Method() { - void Method() - { - const [|int|] x = 5; - } + ref [|var|] x = Method2(); } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + ref int Method2() => throw null; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnNullLiteral() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnDynamic() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|Program|] x = null; - } + [|dynamic|] x = 1; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] - public async Task NotOnRefVar() - { - await TestMissingInRegularAndScriptAsync(""" - class Program + [Fact] + public async Task NotOnAnonymousMethodExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class Program + { + void Method() { - void Method() - { - ref [|var|] x = Method2(); - } - ref int Method2() => throw null; + [|Func|] comparer = delegate (string value) { + return value != "0"; + }; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnDynamic() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnLambdaExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|dynamic|] x = 1; - } + [|Func|] x = y => y * y; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnAnonymousMethodExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnMethodGroup() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|Func|] comparer = delegate (string value) { - return value != "0"; - }; - } + [|Func|] copyStr = string.Copy; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnLambdaExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnDeclarationWithMultipleDeclarators() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|Func|] x = y => y * y; - } + [|int|] x = 5, y = x; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnMethodGroup() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnDeclarationWithoutInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|Func|] copyStr = string.Copy; - } + [|Program|] x; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnDeclarationWithMultipleDeclarators() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnIFormattable() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|int|] x = 5, y = x; - } + [|IFormattable|] s = $"Hello, {name}" } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnDeclarationWithoutInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnFormattableString() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|Program|] x; - } + [|FormattableString|] s = $"Hello, {name}" } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnIFormattable() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotInCatchDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() + try { - [|IFormattable|] s = $"Hello, {name}" } - } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } - - [Fact] - public async Task NotOnFormattableString() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class Program - { - void Method() + catch ([|Exception|] e) { - [|FormattableString|] s = $"Hello, {name}" + throw; } } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotInCatchDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotDuringConflicts() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - try - { - } - catch ([|Exception|] e) - { - throw; - } - } + [|Program|] p = new Program(); } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact] - public async Task NotDuringConflicts() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - - class Program + class var { - void Method() - { - [|Program|] p = new Program(); - } - - class var - { - } } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotIfAlreadyImplicitlyTyped() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotIfAlreadyImplicitlyTyped() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - [|var|] p = new Program(); - } + [|var|] p = new Program(); } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnImplicitConversion() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnImplicitConversion() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - int i = int.MaxValue; - [|long|] l = i; - } + int i = int.MaxValue; + [|long|] l = i; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnBoxingImplicitConversion() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnBoxingImplicitConversion() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class Program + class Program + { + void Method() { - void Method() - { - int i = int.MaxValue; - [|object|] o = i; - } + int i = int.MaxValue; + [|object|] o = i; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnRHS() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnRHS() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - C c = new [|C|](); - } + C c = new [|C|](); } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnVariablesUsedInInitalizerExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnVariablesUsedInInitalizerExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - [|int|] i = (i = 20); - } + [|int|] i = (i = 20); } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] - public async Task NotOnVariablesOfEnumTypeNamedAsEnumTypeUsedInInitalizerExpressionAtFirstPosition() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] + public async Task NotOnVariablesOfEnumTypeNamedAsEnumTypeUsedInInitalizerExpressionAtFirstPosition() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - enum A { X, Y } + enum A { X, Y } - class C + class C + { + void M() { - void M() - { - [|A|] A = A.X; - } + [|A|] A = A.X; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] - public async Task NotOnVariablesNamedAsTypeUsedInInitalizerExpressionContainingTypeNameAtFirstPositionOfMemberAccess() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] + public async Task NotOnVariablesNamedAsTypeUsedInInitalizerExpressionContainingTypeNameAtFirstPositionOfMemberAccess() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class A - { - public static A Instance; - } + class A + { + public static A Instance; + } - class C + class C + { + void M() { - void M() - { - [|A|] A = A.Instance; - } + [|A|] A = A.Instance; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] - public async Task SuggestOnVariablesUsedInInitalizerExpressionAsInnerPartsOfQualifiedNameStartedWithGlobal() - { - await TestAsync( - """ - enum A { X, Y } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] + public async Task SuggestOnVariablesUsedInInitalizerExpressionAsInnerPartsOfQualifiedNameStartedWithGlobal() + { + await TestAsync( + """ + enum A { X, Y } - class C + class C + { + void M() { - void M() - { - [|A|] A = global::A.X; - } + [|A|] A = global::A.X; } - """, - """ - enum A { X, Y } + } + """, + """ + enum A { X, Y } - class C + class C + { + void M() { - void M() - { - var A = global::A.X; - } + var A = global::A.X; } - """, CSharpParseOptions.Default, options: ImplicitTypeEverywhere()); - } + } + """, CSharpParseOptions.Default, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] - public async Task SuggestOnVariablesUsedInInitalizerExpressionAsInnerPartsOfQualifiedName() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] + public async Task SuggestOnVariablesUsedInInitalizerExpressionAsInnerPartsOfQualifiedName() + { + await TestInRegularAndScriptAsync( + """ + using System; - namespace N - { - class A - { - public static A Instance; - } + namespace N + { + class A + { + public static A Instance; } + } - class C + class C + { + void M() { - void M() - { - [|N.A|] A = N.A.Instance; - } + [|N.A|] A = N.A.Instance; } - """, - """ - using System; + } + """, + """ + using System; - namespace N - { - class A - { - public static A Instance; - } + namespace N + { + class A + { + public static A Instance; } + } - class C + class C + { + void M() { - void M() - { - var A = N.A.Instance; - } + var A = N.A.Instance; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] - public async Task SuggestOnVariablesUsedInInitalizerExpressionAsLastPartOfQualifiedName() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26894")] + public async Task SuggestOnVariablesUsedInInitalizerExpressionAsLastPartOfQualifiedName() + { + await TestInRegularAndScriptAsync( + """ + using System; - class A {} + class A {} - class X - { - public static A A; - } + class X + { + public static A A; + } - class C + class C + { + void M() { - void M() - { - [|A|] A = X.A; - } + [|A|] A = X.A; } - """, - """ - using System; + } + """, + """ + using System; - class A {} + class A {} - class X - { - public static A A; - } + class X + { + public static A A; + } - class C + class C + { + void M() { - void M() - { - var A = X.A; - } + var A = X.A; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task NotOnAssignmentToInterfaceType() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnAssignmentToInterfaceType() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void ProcessRead() { - public void ProcessRead() - { - [|IInterface|] i = new A(); - } + [|IInterface|] i = new A(); } + } - class A : IInterface - { - } + class A : IInterface + { + } - interface IInterface - { - } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + interface IInterface + { + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task NotOnArrayInitializerWithoutNewKeyword() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotOnArrayInitializerWithoutNewKeyword() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|int[]|] n1 = { - 2, - 4, - 6, - 8 - }; - } + [|int[]|] n1 = { + 2, + 4, + 6, + 8 + }; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task SuggestVarOnLocalWithIntrinsicTypeString() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnLocalWithIntrinsicTypeString() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|string|] s = "hello"; - } + [|string|] s = "hello"; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var s = "hello"; - } + var s = "hello"; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnIntrinsicType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnIntrinsicType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|int|] s = 5; - } + [|int|] s = 5; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var s = 5; - } + var s = 5; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] - public async Task SuggestVarOnRefIntrinsicType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] + public async Task SuggestVarOnRefIntrinsicType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - ref [|int|] s = Ref(); - } - static ref int Ref() => throw null; + ref [|int|] s = Ref(); } - """, - """ - using System; + static ref int Ref() => throw null; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - ref var s = Ref(); - } - static ref int Ref() => throw null; + ref var s = Ref(); } - """, options: ImplicitTypeEverywhere()); - } + static ref int Ref() => throw null; + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] - public async Task WithRefIntrinsicTypeInForeach() - { - var before = """ - class E - { - public ref int Current => throw null; - public bool MoveNext() => throw null; - public E GetEnumerator() => throw null; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/27221")] + public async Task WithRefIntrinsicTypeInForeach() + { + var before = """ + class E + { + public ref int Current => throw null; + public bool MoveNext() => throw null; + public E GetEnumerator() => throw null; - void M() - { - foreach (ref [|int|] x in this) { } - } - } - """; - var after = """ - class E + void M() { - public ref int Current => throw null; - public bool MoveNext() => throw null; - public E GetEnumerator() => throw null; + foreach (ref [|int|] x in this) { } + } + } + """; + var after = """ + class E + { + public ref int Current => throw null; + public bool MoveNext() => throw null; + public E GetEnumerator() => throw null; - void M() - { - foreach (ref var x in this) { } - } + void M() + { + foreach (ref var x in this) { } } - """; - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); - } + } + """; + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnFrameworkType() - { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; + [Fact] + public async Task SuggestVarOnFrameworkType() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - [|List|] c = new List(); - } + [|List|] c = new List(); } - """, - """ - using System.Collections.Generic; + } + """, + """ + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - var c = new List(); - } + var c = new List(); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnUserDefinedType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnUserDefinedType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - [|C|] c = new C(); - } + [|C|] c = new C(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - var c = new C(); - } + var c = new C(); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnGenericType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnGenericType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|C|] c = new C(); - } + [|C|] c = new C(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var c = new C(); - } + var c = new C(); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnSeeminglyConflictingType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnSeeminglyConflictingType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class var + class var + { + void M() { - void M() - { - [|var|] c = new var(); - } + [|var|] c = new var(); } - """, - """ - using System; + } + """, + """ + using System; - class var + class var + { + void M() { - void M() - { - var c = new var(); - } + var c = new var(); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnSingleDimensionalArrayTypeWithNewOperator() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnSingleDimensionalArrayTypeWithNewOperator() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|int[]|] n1 = new int[4] { 2, 4, 6, 8 }; - } + [|int[]|] n1 = new int[4] { 2, 4, 6, 8 }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var n1 = new int[4] { 2, 4, 6, 8 }; - } + var n1 = new int[4] { 2, 4, 6, 8 }; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnSingleDimensionalArrayTypeWithNewOperator2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnSingleDimensionalArrayTypeWithNewOperator2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|int[]|] n1 = new[] { 2, 4, 6, 8 }; - } + [|int[]|] n1 = new[] { 2, 4, 6, 8 }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var n1 = new[] { 2, 4, 6, 8 }; - } + var n1 = new[] { 2, 4, 6, 8 }; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnSingleDimensionalJaggedArrayType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnSingleDimensionalJaggedArrayType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|int[][]|] cs = new[] { - new[] { 1, 2, 3, 4 }, - new[] { 5, 6, 7, 8 } - }; - } + [|int[][]|] cs = new[] { + new[] { 1, 2, 3, 4 }, + new[] { 5, 6, 7, 8 } + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var cs = new[] { - new[] { 1, 2, 3, 4 }, - new[] { 5, 6, 7, 8 } - }; - } + var cs = new[] { + new[] { 1, 2, 3, 4 }, + new[] { 5, 6, 7, 8 } + }; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnDeclarationWithObjectInitializer() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnDeclarationWithObjectInitializer() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|Customer|] cc = new Customer { City = "Madras" }; - } + [|Customer|] cc = new Customer { City = "Madras" }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var cc = new Customer { City = "Madras" }; - } + var cc = new Customer { City = "Madras" }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnDeclarationWithCollectionInitializer() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task SuggestVarOnDeclarationWithCollectionInitializer() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - [|List|] digits = new List { 1, 2, 3 }; - } + [|List|] digits = new List { 1, 2, 3 }; } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() - { - var digits = new List { 1, 2, 3 }; - } + var digits = new List { 1, 2, 3 }; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnDeclarationWithCollectionAndObjectInitializers() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task SuggestVarOnDeclarationWithCollectionAndObjectInitializers() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + [|List|] cs = new List { - [|List|] cs = new List - { - new Customer { City = "Madras" } - }; - } + new Customer { City = "Madras" } + }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + var cs = new List { - var cs = new List - { - new Customer { City = "Madras" } - }; - } + new Customer { City = "Madras" } + }; + } - private class Customer - { - public string City { get; set; } - } + private class Customer + { + public string City { get; set; } } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnForStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnForStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() + for ([|int|] i = 0; i < 5; i++) { - for ([|int|] i = 0; i < 5; i++) - { - } } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() + for (var i = 0; i < 5; i++) { - for (var i = 0; i < 5; i++) - { - } } } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnForeachStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact] + public async Task SuggestVarOnForeachStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + var l = new List { 1, 3, 5 }; + foreach ([|int|] item in l) { - var l = new List { 1, 3, 5 }; - foreach ([|int|] item in l) - { - } } } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void M() { - static void M() + var l = new List { 1, 3, 5 }; + foreach (var item in l) { - var l = new List { 1, 3, 5 }; - foreach (var item in l) - { - } } } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnQueryExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; - using System.Linq; + [Fact] + public async Task SuggestVarOnQueryExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + using System.Linq; - class C + class C + { + static void M() { - static void M() - { - var customers = new List(); - [|IEnumerable|] expr = from c in customers - where c.City == "London" - select c; - } - - private class Customer - { - public string City { get; set; } - } - } + var customers = new List(); + [|IEnumerable|] expr = from c in customers + where c.City == "London" + select c; } - """, - """ - using System; - using System.Collections.Generic; - using System.Linq; - class C + private class Customer { - static void M() - { - var customers = new List(); - var expr = from c in customers - where c.City == "London" - select c; - } - - private class Customer - { - public string City { get; set; } - } - } + public string City { get; set; } } - """, options: ImplicitTypeEverywhere()); - } - - [Fact] - public async Task SuggestVarInUsingStatement() - { - await TestInRegularAndScriptAsync( - """ - using System; + } + } + """, + """ + using System; + using System.Collections.Generic; + using System.Linq; - class C + class C + { + static void M() { - static void M() - { - using ([|Res|] r = new Res()) - { - } - } - - private class Res : IDisposable - { - public void Dispose() - { - throw new NotImplementedException(); - } - } + var customers = new List(); + var expr = from c in customers + where c.City == "London" + select c; } - """, - """ - using System; - class C + private class Customer { - static void M() - { - using (var r = new Res()) - { - } - } - - private class Res : IDisposable - { - public void Dispose() - { - throw new NotImplementedException(); - } - } + public string City { get; set; } } - """, options: ImplicitTypeEverywhere()); - } + } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarOnExplicitConversion() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarInUsingStatement() + { + await TestInRegularAndScriptAsync( + """ + using System; - class Program + class C + { + static void M() { - void Method() + using ([|Res|] r = new Res()) { - double x = 1234.7; - [|int|] a = (int)x; } } - """, - """ - using System; - class Program + private class Res : IDisposable { - void Method() + public void Dispose() { - double x = 1234.7; - var a = (int)x; + throw new NotImplementedException(); } } - """, options: ImplicitTypeEverywhere()); - } - - [Fact] - public async Task SuggestVarInConditionalAccessExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - C obj = new C(); - [|C|] anotherObj = obj?.Test(); - } - - C Test() + using (var r = new Res()) { - return this; } } - """, - """ - using System; - class C + private class Res : IDisposable { - static void M() - { - C obj = new C(); - var anotherObj = obj?.Test(); - } - - C Test() + public void Dispose() { - return this; + throw new NotImplementedException(); } } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarInCheckedExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarOnExplicitConversion() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class Program + { + void Method() { - static void M() - { - long number1 = int.MaxValue + 20L; - [|int|] intNumber = checked((int)number1); - } + double x = 1234.7; + [|int|] a = (int)x; } - """, - """ - using System; + } + """, + """ + using System; - class C + class Program + { + void Method() { - static void M() - { - long number1 = int.MaxValue + 20L; - var intNumber = checked((int)number1); - } + double x = 1234.7; + var a = (int)x; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarInUnCheckedExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarInConditionalAccessExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - long number1 = int.MaxValue + 20L; - [|int|] intNumber = unchecked((int)number1); - } + C obj = new C(); + [|C|] anotherObj = obj?.Test(); } - """, - """ - using System; - class C + C Test() { - static void M() - { - long number1 = int.MaxValue + 20L; - var intNumber = unchecked((int)number1); - } + return this; } - """, options: ImplicitTypeEverywhere()); - } - - [Fact] - public async Task SuggestVarInAwaitExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; - class C + class C + { + static void M() { - public async void ProcessRead() - { - [|string|] text = await ReadTextAsync(null); - } - - private async Task ReadTextAsync(string filePath) - { - return string.Empty; - } + C obj = new C(); + var anotherObj = obj?.Test(); } - """, - """ - using System; - using System.Threading.Tasks; - class C + C Test() { - public async void ProcessRead() - { - var text = await ReadTextAsync(null); - } - - private async Task ReadTextAsync(string filePath) - { - return string.Empty; - } + return this; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarInParenthesizedExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarInCheckedExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - public void ProcessRead() - { - [|int|] text = (5); - } + long number1 = int.MaxValue + 20L; + [|int|] intNumber = checked((int)number1); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - public void ProcessRead() - { - var text = (5); - } + long number1 = int.MaxValue + 20L; + var intNumber = checked((int)number1); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task DoNotSuggestVarOnBuiltInType_Literal_WithOption() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarInUnCheckedExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|int|] s = 5; - } + long number1 = int.MaxValue + 20L; + [|int|] intNumber = unchecked((int)number1); } - """, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); - } - - [Fact] - public async Task DoNotSuggestVarOnBuiltInType_WithOption() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - private const int maxValue = int.MaxValue; - - static void M() - { - [|int|] s = (unchecked(maxValue + 10)); - } + long number1 = int.MaxValue + 20L; + var intNumber = unchecked((int)number1); } - """, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task DoNotSuggestVarOnFrameworkTypeEquivalentToBuiltInType() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarInAwaitExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public async void ProcessRead() { - private const int maxValue = int.MaxValue; - - static void M() - { - [|Int32|] s = (unchecked(maxValue + 10)); - } + [|string|] text = await ReadTextAsync(null); } - """, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); - } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_DefaultExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + private async Task ReadTextAsync(string filePath) + { + return string.Empty; + } + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + public async void ProcessRead() { - public void Process() - { - [|C|] text = default(C); - } + var text = await ReadTextAsync(null); } - """, - """ - using System; - class C + private async Task ReadTextAsync(string filePath) { - public void Process() - { - var text = default(C); - } + return string.Empty; } - """, options: ImplicitTypeWhereApparent()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_Literals() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarInParenthesizedExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void ProcessRead() { - public void Process() - { - [|int|] text = 5; - } + [|int|] text = (5); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void ProcessRead() { - public void Process() - { - var text = 5; - } + var text = (5); } - """, options: ImplicitTypeWhereApparentAndForIntrinsics()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact] - public async Task DoNotSuggestVarWhereTypeIsEvident_Literals() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task DoNotSuggestVarOnBuiltInType_Literal_WithOption() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - public void Process() - { - [|int|] text = 5; - } + [|int|] s = 5; } - """, new TestParameters(options: ImplicitTypeWhereApparent())); - } + } + """, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_ObjectCreationExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task DoNotSuggestVarOnBuiltInType_WithOption() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C - { - public void Process() - { - [|C|] c = new C(); - } - } - """, - """ - using System; + class C + { + private const int maxValue = int.MaxValue; - class C + static void M() { - public void Process() - { - var c = new C(); - } + [|int|] s = (unchecked(maxValue + 10)); } - """, options: ImplicitTypeWhereApparent()); - } + } + """, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_CastExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task DoNotSuggestVarOnFrameworkTypeEquivalentToBuiltInType() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C - { - public void Process() - { - object o = DateTime.MaxValue; - [|DateTime|] date = (DateTime)o; - } - } - """, - """ - using System; + class C + { + private const int maxValue = int.MaxValue; - class C + static void M() { - public void Process() - { - object o = DateTime.MaxValue; - var date = (DateTime)o; - } + [|Int32|] s = (unchecked(maxValue + 10)); } - """, options: ImplicitTypeWhereApparent()); - } + } + """, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); + } - [Fact] - public async Task DoNotSuggestVar_BuiltInTypesRulePrecedesOverTypeIsApparentRule1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarWhereTypeIsEvident_DefaultExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - object o = int.MaxValue; - [|int|] i = (Int32)o; - } + [|C|] text = default(C); } - """, new TestParameters(options: ImplicitTypeWhereApparent())); - } - - [Fact] - public async Task DoNotSuggestVar_BuiltInTypesRulePrecedesOverTypeIsApparentRule2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - object o = int.MaxValue; - [|Int32|] i = (Int32)o; - } + var text = default(C); } - """, new TestParameters(options: ImplicitTypeWhereApparent())); - } + } + """, options: ImplicitTypeWhereApparent()); + } - [Fact] - public async Task DoNotSuggestVarWhereTypeIsEvident_IsExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarWhereTypeIsEvident_Literals() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - A a = new A(); - [|Boolean|] s = a is IInterface; - } + [|int|] text = 5; } + } + """, + """ + using System; - class A : IInterface + class C + { + public void Process() { + var text = 5; } + } + """, options: ImplicitTypeWhereApparentAndForIntrinsics()); + } - interface IInterface - { + [Fact] + public async Task DoNotSuggestVarWhereTypeIsEvident_Literals() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + public void Process() + { + [|int|] text = 5; } - """, new TestParameters(options: ImplicitTypeWhereApparent())); - } + } + """, new TestParameters(options: ImplicitTypeWhereApparent())); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_AsExpression() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarWhereTypeIsEvident_ObjectCreationExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - A a = new A(); - [|IInterface|] s = a as IInterface; - } + [|C|] c = new C(); } + } + """, + """ + using System; - class A : IInterface + class C + { + public void Process() { + var c = new C(); } + } + """, options: ImplicitTypeWhereApparent()); + } + + [Fact] + public async Task SuggestVarWhereTypeIsEvident_CastExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - interface IInterface + class C + { + public void Process() { + object o = DateTime.MaxValue; + [|DateTime|] date = (DateTime)o; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - A a = new A(); - var s = a as IInterface; - } + object o = DateTime.MaxValue; + var date = (DateTime)o; } + } + """, options: ImplicitTypeWhereApparent()); + } - class A : IInterface + [Fact] + public async Task DoNotSuggestVar_BuiltInTypesRulePrecedesOverTypeIsApparentRule1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + public void Process() { + object o = int.MaxValue; + [|int|] i = (Int32)o; } + } + """, new TestParameters(options: ImplicitTypeWhereApparent())); + } - interface IInterface + [Fact] + public async Task DoNotSuggestVar_BuiltInTypesRulePrecedesOverTypeIsApparentRule2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class C + { + public void Process() { + object o = int.MaxValue; + [|Int32|] i = (Int32)o; } - """, options: ImplicitTypeWhereApparent()); - } + } + """, new TestParameters(options: ImplicitTypeWhereApparent())); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_ConversionHelpers() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task DoNotSuggestVarWhereTypeIsEvident_IsExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - [|DateTime|] a = DateTime.Parse("1"); - } + A a = new A(); + [|Boolean|] s = a is IInterface; } - """, - """ - using System; + } + + class A : IInterface + { + } + + interface IInterface + { + } + """, new TestParameters(options: ImplicitTypeWhereApparent())); + } + + [Fact] + public async Task SuggestVarWhereTypeIsEvident_AsExpression() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - var a = DateTime.Parse("1"); - } + A a = new A(); + [|IInterface|] s = a as IInterface; } - """, options: ImplicitTypeWhereApparent()); - } + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_CreationHelpers() - { - await TestInRegularAndScriptAsync( - """ - class C + class A : IInterface + { + } + + interface IInterface + { + } + """, + """ + using System; + + class C + { + public void Process() { - public void Process() - { - [|XElement|] a = XElement.Load(); - } + A a = new A(); + var s = a as IInterface; + } + } + + class A : IInterface + { + } + + interface IInterface + { + } + """, options: ImplicitTypeWhereApparent()); + } + + [Fact] + public async Task SuggestVarWhereTypeIsEvident_ConversionHelpers() + { + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + public void Process() + { + [|DateTime|] a = DateTime.Parse("1"); } + } + """, + """ + using System; - class XElement + class C + { + public void Process() { - internal static XElement Load() => return null; + var a = DateTime.Parse("1"); } - """, - """ - class C + } + """, options: ImplicitTypeWhereApparent()); + } + + [Fact] + public async Task SuggestVarWhereTypeIsEvident_CreationHelpers() + { + await TestInRegularAndScriptAsync( + """ + class C + { + public void Process() { - public void Process() - { - var a = XElement.Load(); - } + [|XElement|] a = XElement.Load(); } + } - class XElement + class XElement + { + internal static XElement Load() => return null; + } + """, + """ + class C + { + public void Process() { - internal static XElement Load() => return null; + var a = XElement.Load(); } - """, options: ImplicitTypeWhereApparent()); - } + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_CreationHelpersWithInferredTypeArguments() - { - await TestInRegularAndScriptAsync( - """ - using System; + class XElement + { + internal static XElement Load() => return null; + } + """, options: ImplicitTypeWhereApparent()); + } + + [Fact] + public async Task SuggestVarWhereTypeIsEvident_CreationHelpersWithInferredTypeArguments() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - [|Tuple|] a = Tuple.Create(0, true); - } + [|Tuple|] a = Tuple.Create(0, true); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - var a = Tuple.Create(0, true); - } + var a = Tuple.Create(0, true); } - """, options: ImplicitTypeWhereApparent()); - } + } + """, options: ImplicitTypeWhereApparent()); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_ConvertToType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarWhereTypeIsEvident_ConvertToType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - int integralValue = 12534; - [|DateTime|] date = Convert.ToDateTime(integralValue); - } + int integralValue = 12534; + [|DateTime|] date = Convert.ToDateTime(integralValue); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - int integralValue = 12534; - var date = Convert.ToDateTime(integralValue); - } + int integralValue = 12534; + var date = Convert.ToDateTime(integralValue); } - """, options: ImplicitTypeWhereApparent()); - } + } + """, options: ImplicitTypeWhereApparent()); + } - [Fact] - public async Task SuggestVarWhereTypeIsEvident_IConvertibleToType() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task SuggestVarWhereTypeIsEvident_IConvertibleToType() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - int codePoint = 1067; - IConvertible iConv = codePoint; - [|DateTime|] date = iConv.ToDateTime(null); - } + int codePoint = 1067; + IConvertible iConv = codePoint; + [|DateTime|] date = iConv.ToDateTime(null); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public void Process() { - public void Process() - { - int codePoint = 1067; - IConvertible iConv = codePoint; - var date = iConv.ToDateTime(null); - } + int codePoint = 1067; + IConvertible iConv = codePoint; + var date = iConv.ToDateTime(null); } - """, options: ImplicitTypeWhereApparent()); - } + } + """, options: ImplicitTypeWhereApparent()); + } - [Fact] - public async Task SuggestVarNotificationLevelSilent() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestVarNotificationLevelSilent() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|C|] n1 = new C(); - } + [|C|] n1 = new C(); } - """; - await TestDiagnosticInfoAsync(source, - options: ImplicitTypeSilentEnforcement(), - diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Hidden); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ImplicitTypeSilentEnforcement(), + diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Hidden); + } - [Fact] - public async Task SuggestVarNotificationLevelInfo() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestVarNotificationLevelInfo() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|int|] s = 5; - } + [|int|] s = 5; } - """; - await TestDiagnosticInfoAsync(source, - options: ImplicitTypeEnforcements(), - diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Info); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ImplicitTypeEnforcements(), + diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Info); + } - [Fact] - public async Task SuggestVarNotificationLevelWarning() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestVarNotificationLevelWarning() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|C[]|] n1 = new[] { new C() }; // type not apparent and not intrinsic - } + [|C[]|] n1 = new[] { new C() }; // type not apparent and not intrinsic } - """; - await TestDiagnosticInfoAsync(source, - options: ImplicitTypeEnforcements(), - diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Warning); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ImplicitTypeEnforcements(), + diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Warning); + } - [Fact] - public async Task SuggestVarNotificationLevelError() - { - var source = - """ - using System; - class C + [Fact] + public async Task SuggestVarNotificationLevelError() + { + var source = + """ + using System; + class C + { + static void M() { - static void M() - { - [|C|] n1 = new C(); - } + [|C|] n1 = new C(); } - """; - await TestDiagnosticInfoAsync(source, - options: ImplicitTypeEnforcements(), - diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, - diagnosticSeverity: DiagnosticSeverity.Error); - } + } + """; + await TestDiagnosticInfoAsync(source, + options: ImplicitTypeEnforcements(), + diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Error); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] - public async Task SuggestVarOnLocalWithIntrinsicArrayType() - { - var before = @"class C { static void M() { [|int[]|] s = new int[0]; } }"; - var after = @"class C { static void M() { var s = new int[0]; } }"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] + public async Task SuggestVarOnLocalWithIntrinsicArrayType() + { + var before = @"class C { static void M() { [|int[]|] s = new int[0]; } }"; + var after = @"class C { static void M() { var s = new int[0]; } }"; - //The type is intrinsic and apparent - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); // Preference of intrinsic types dominates - } + //The type is intrinsic and apparent + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); // Preference of intrinsic types dominates + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] - public async Task SuggestVarOnLocalWithCustomArrayType() - { - var before = @"class C { static void M() { [|C[]|] s = new C[0]; } }"; - var after = @"class C { static void M() { var s = new C[0]; } }"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] + public async Task SuggestVarOnLocalWithCustomArrayType() + { + var before = @"class C { static void M() { [|C[]|] s = new C[0]; } }"; + var after = @"class C { static void M() { var s = new C[0]; } }"; - //The type is not intrinsic but apparent - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeButKeepIntrinsics()); - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeWhereApparent()); - } + //The type is not intrinsic but apparent + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeButKeepIntrinsics()); + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeWhereApparent()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] - public async Task SuggestVarOnLocalWithNonApparentCustomArrayType() - { - var before = @"class C { static void M() { [|C[]|] s = new[] { new C() }; } }"; - var after = @"class C { static void M() { var s = new[] { new C() }; } }"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] + public async Task SuggestVarOnLocalWithNonApparentCustomArrayType() + { + var before = @"class C { static void M() { [|C[]|] s = new[] { new C() }; } }"; + var after = @"class C { static void M() { var s = new[] { new C() }; } }"; - //The type is not intrinsic and not apparent - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeButKeepIntrinsics()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); - } + //The type is not intrinsic and not apparent + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeButKeepIntrinsics()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); + } - private static readonly string trivial2uple = - """ - namespace System + private static readonly string trivial2uple = + """ + namespace System + { + public class ValueTuple { - public class ValueTuple - { - public static ValueTuple Create(T1 item1, T2 item2) => new ValueTuple(item1, item2); - } - public struct ValueTuple - { - public T1 Item1; - public T2 Item2; + public static ValueTuple Create(T1 item1, T2 item2) => new ValueTuple(item1, item2); + } + public struct ValueTuple + { + public T1 Item1; + public T2 Item2; - public ValueTuple(T1 item1, T2 item2) { } - } + public ValueTuple(T1 item1, T2 item2) { } } - """; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11094")] - public async Task SuggestVarOnLocalWithIntrinsicTypeTuple() - { - var before = @"class C { static void M() { [|(int a, string)|] s = (a: 1, ""hello""); } }"; - var after = @"class C { static void M() { var s = (a: 1, ""hello""); } }"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11094")] + public async Task SuggestVarOnLocalWithIntrinsicTypeTuple() + { + var before = @"class C { static void M() { [|(int a, string)|] s = (a: 1, ""hello""); } }"; + var after = @"class C { static void M() { var s = (a: 1, ""hello""); } }"; - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeWhereApparentAndForIntrinsics()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); - } + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeWhereApparentAndForIntrinsics()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11094")] - public async Task SuggestVarOnLocalWithNonApparentTupleType() - { - var before = @"class C { static void M(C c) { [|(int a, C b)|] s = (a: 1, b: c); } }"; - var after = @"class C { static void M(C c) { var s = (a: 1, b: c); } }"; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11094")] + public async Task SuggestVarOnLocalWithNonApparentTupleType() + { + var before = @"class C { static void M(C c) { [|(int a, C b)|] s = (a: 1, b: c); } }"; + var after = @"class C { static void M(C c) { var s = (a: 1, b: c); } }"; - await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparentAndForIntrinsics())); - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); - } + await TestInRegularAndScriptAsync(before, after, options: ImplicitTypeEverywhere()); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparentAndForIntrinsics())); + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeWhereApparent())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11154")] - public async Task ValueTupleCreate() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11154")] + public async Task ValueTupleCreate() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|ValueTuple|] s = ValueTuple.Create(1, 1); - } + [|ValueTuple|] s = ValueTuple.Create(1, 1); } - """ + trivial2uple, - """ - using System; + } + """ + trivial2uple, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var s = ValueTuple.Create(1, 1); - } + var s = ValueTuple.Create(1, 1); } - """ + trivial2uple, + } + """ + trivial2uple, options: ImplicitTypeWhereApparent()); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11095")] - public async Task ValueTupleCreate_2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/11095")] + public async Task ValueTupleCreate_2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - [|(int, int)|] s = ValueTuple.Create(1, 1); - } + [|(int, int)|] s = ValueTuple.Create(1, 1); } - """ + trivial2uple, - """ - using System; + } + """ + trivial2uple, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - var s = ValueTuple.Create(1, 1); - } + var s = ValueTuple.Create(1, 1); } - """ + trivial2uple, + } + """ + trivial2uple, options: ImplicitTypeWhereApparent()); - } + } - [Fact] - public async Task TupleWithDifferentNames() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TupleWithDifferentNames() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + static void M() { - static void M() - { - [|(int, string)|] s = (c: 1, d: "hello"); - } + [|(int, string)|] s = (c: 1, d: "hello"); } - """, + } + """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14052")] - public async Task DoNotOfferOnForEachConversionIfItChangesSemantics() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14052")] + public async Task DoNotOfferOnForEachConversionIfItChangesSemantics() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - interface IContractV1 - { - } + interface IContractV1 + { + } - interface IContractV2 : IContractV1 - { - } + interface IContractV2 : IContractV1 + { + } - class ContractFactory + class ContractFactory + { + public IEnumerable GetContracts() { - public IEnumerable GetContracts() - { - } } + } - class Program + class Program + { + static void M() { - static void M() + var contractFactory = new ContractFactory(); + foreach ([|IContractV2|] contract in contractFactory.GetContracts()) { - var contractFactory = new ContractFactory(); - foreach ([|IContractV2|] contract in contractFactory.GetContracts()) - { - } } } - """, + } + """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14052")] - public async Task OfferOnForEachConversionIfItDoesNotChangesSemantics() - { - await TestInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14052")] + public async Task OfferOnForEachConversionIfItDoesNotChangesSemantics() + { + await TestInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - interface IContractV1 - { - } + interface IContractV1 + { + } - interface IContractV2 : IContractV1 - { - } + interface IContractV2 : IContractV1 + { + } - class ContractFactory + class ContractFactory + { + public IEnumerable GetContracts() { - public IEnumerable GetContracts() - { - } } + } - class Program + class Program + { + static void M() { - static void M() + var contractFactory = new ContractFactory(); + foreach ([|IContractV1|] contract in contractFactory.GetContracts()) { - var contractFactory = new ContractFactory(); - foreach ([|IContractV1|] contract in contractFactory.GetContracts()) - { - } } } - """, - """ - using System; - using System.Collections.Generic; + } + """, + """ + using System; + using System.Collections.Generic; - interface IContractV1 - { - } + interface IContractV1 + { + } - interface IContractV2 : IContractV1 - { - } + interface IContractV2 : IContractV1 + { + } - class ContractFactory + class ContractFactory + { + public IEnumerable GetContracts() { - public IEnumerable GetContracts() - { - } } + } - class Program + class Program + { + static void M() { - static void M() + var contractFactory = new ContractFactory(); + foreach (var contract in contractFactory.GetContracts()) { - var contractFactory = new ContractFactory(); - foreach (var contract in contractFactory.GetContracts()) - { - } } } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20437")] - public async Task SuggestVarOnDeclarationExpressionSyntax() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/20437")] + public async Task SuggestVarOnDeclarationExpressionSyntax() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + static void M() { - static void M() - { - DateTime.TryParse(string.Empty, [|out DateTime|] date); - } + DateTime.TryParse(string.Empty, [|out DateTime|] date); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + static void M() { - static void M() - { - DateTime.TryParse(string.Empty, out var date); - } + DateTime.TryParse(string.Empty, out var date); } - """, + } + """, options: ImplicitTypeEverywhere()); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] - public async Task DoNotSuggestVarOnDeclarationExpressionSyntaxWithIntrinsicType() - { - var before = - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23893")] + public async Task DoNotSuggestVarOnDeclarationExpressionSyntaxWithIntrinsicType() + { + var before = + """ + class C + { + static void M(out int x) { - static void M(out int x) - { - M([|out int|] x); - } + M([|out int|] x); } - """; - await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); - } + } + """; + await TestMissingInRegularAndScriptAsync(before, new TestParameters(options: ImplicitTypeButKeepIntrinsics())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task DoNotSuggestVarOnStackAllocExpressions_SpanType() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - namespace System + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task DoNotSuggestVarOnStackAllocExpressions_SpanType() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + namespace System + { + public readonly ref struct Span { - public readonly ref struct Span - { - unsafe public Span(void* pointer, int length) { } - } + unsafe public Span(void* pointer, int length) { } } - class C + } + class C + { + static void M() { - static void M() - { - [|Span|] x = stackalloc int [10]; - } + [|Span|] x = stackalloc int [10]; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedConditional() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - namespace System + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedConditional() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + namespace System + { + public readonly ref struct Span { - public readonly ref struct Span - { - unsafe public Span(void* pointer, int length) { } - } + unsafe public Span(void* pointer, int length) { } } - class C + } + class C + { + static void M(bool choice) { - static void M(bool choice) - { - [|Span|] x = choice ? stackalloc int [10] : stackalloc int [100]; - } + [|Span|] x = choice ? stackalloc int [10] : stackalloc int [100]; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedCast() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - namespace System + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task DoNotSuggestVarOnStackAllocExpressions_SpanType_NestedCast() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + namespace System + { + public readonly ref struct Span { - public readonly ref struct Span - { - unsafe public Span(void* pointer, int length) { } - } + unsafe public Span(void* pointer, int length) { } } - class C + } + class C + { + static void M() { - static void M() - { - [|Span|] x = (Span)stackalloc int [100]; - } + [|Span|] x = (Span)stackalloc int [100]; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task SuggestVarOnLambdasWithNestedStackAllocs() - { - await TestInRegularAndScriptAsync(""" - using System.Linq; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task SuggestVarOnLambdasWithNestedStackAllocs() + { + await TestInRegularAndScriptAsync(""" + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + [|int|] x = new int[] { 1, 2, 3 }.First(i => { - [|int|] x = new int[] { 1, 2, 3 }.First(i => - { - int* y = stackalloc int[10]; - return i == 1; - }); - } + int* y = stackalloc int[10]; + return i == 1; + }); } - """, """ - using System.Linq; - class C + } + """, """ + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + var x = new int[] { 1, 2, 3 }.First(i => { - var x = new int[] { 1, 2, 3 }.First(i => - { - int* y = stackalloc int[10]; - return i == 1; - }); - } + int* y = stackalloc int[10]; + return i == 1; + }); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task SuggestVarOnAnonymousMethodsWithNestedStackAllocs() - { - await TestInRegularAndScriptAsync(""" - using System.Linq; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task SuggestVarOnAnonymousMethodsWithNestedStackAllocs() + { + await TestInRegularAndScriptAsync(""" + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + [|int|] x = new int[] { 1, 2, 3 }.First(delegate (int i) { - [|int|] x = new int[] { 1, 2, 3 }.First(delegate (int i) - { - int* y = stackalloc int[10]; - return i == 1; - }); - } + int* y = stackalloc int[10]; + return i == 1; + }); } - """, """ - using System.Linq; - class C + } + """, """ + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + var x = new int[] { 1, 2, 3 }.First(delegate (int i) { - var x = new int[] { 1, 2, 3 }.First(delegate (int i) - { - int* y = stackalloc int[10]; - return i == 1; - }); - } + int* y = stackalloc int[10]; + return i == 1; + }); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task SuggestVarOnStackAllocsNestedInLambdas() - { - await TestInRegularAndScriptAsync(""" - using System.Linq; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task SuggestVarOnStackAllocsNestedInLambdas() + { + await TestInRegularAndScriptAsync(""" + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + var x = new int[] { 1, 2, 3 }.First(i => { - var x = new int[] { 1, 2, 3 }.First(i => - { - [|int*|] y = stackalloc int[10]; - return i == 1; - }); - } + [|int*|] y = stackalloc int[10]; + return i == 1; + }); } - """, """ - using System.Linq; - class C + } + """, """ + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + var x = new int[] { 1, 2, 3 }.First(i => { - var x = new int[] { 1, 2, 3 }.First(i => - { - var y = stackalloc int[10]; - return i == 1; - }); - } + var y = stackalloc int[10]; + return i == 1; + }); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task SuggestVarOnStackAllocsNestedInAnonymousMethods() - { - await TestInRegularAndScriptAsync(""" - using System.Linq; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task SuggestVarOnStackAllocsNestedInAnonymousMethods() + { + await TestInRegularAndScriptAsync(""" + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + var x = new int[] { 1, 2, 3 }.First(delegate (int i) { - var x = new int[] { 1, 2, 3 }.First(delegate (int i) - { - [|int*|] y = stackalloc int[10]; - return i == 1; - }); - } + [|int*|] y = stackalloc int[10]; + return i == 1; + }); } - """, """ - using System.Linq; - class C + } + """, """ + using System.Linq; + class C + { + unsafe static void M() { - unsafe static void M() + var x = new int[] { 1, 2, 3 }.First(delegate (int i) { - var x = new int[] { 1, 2, 3 }.First(delegate (int i) - { - var y = stackalloc int[10]; - return i == 1; - }); - } + var y = stackalloc int[10]; + return i == 1; + }); } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] - public async Task SuggestVarOnStackAllocsInOuterMethodScope() - { - await TestInRegularAndScriptAsync(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22768")] + public async Task SuggestVarOnStackAllocsInOuterMethodScope() + { + await TestInRegularAndScriptAsync(""" + class C + { + unsafe static void M() { - unsafe static void M() - { - [|int*|] x = stackalloc int [10]; - } + [|int*|] x = stackalloc int [10]; } - """, """ - class C + } + """, """ + class C + { + unsafe static void M() { - unsafe static void M() - { - var x = stackalloc int [10]; - } + var x = stackalloc int [10]; } - """, options: ImplicitTypeEverywhere()); - } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] - public async Task DoSuggestForDeclarationExpressionIfItWouldNotChangeOverloadResolution2() - { - await TestInRegularAndScriptAsync(""" - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] + public async Task DoSuggestForDeclarationExpressionIfItWouldNotChangeOverloadResolution2() + { + await TestInRegularAndScriptAsync(""" + class Program + { + static int Main(string[] args) { - static int Main(string[] args) - { - TryGetValue("key", out [|int|] value); - return value; - } - - public static bool TryGetValue(string key, out int value) => false; - public static bool TryGetValue(string key, out bool value, int x) => false; + TryGetValue("key", out [|int|] value); + return value; } - """, """ - class Program - { - static int Main(string[] args) - { - TryGetValue("key", out var value); - return value; - } - public static bool TryGetValue(string key, out int value) => false; - public static bool TryGetValue(string key, out bool value, int x) => false; + public static bool TryGetValue(string key, out int value) => false; + public static bool TryGetValue(string key, out bool value, int x) => false; + } + """, """ + class Program + { + static int Main(string[] args) + { + TryGetValue("key", out var value); + return value; } - """, options: ImplicitTypeEverywhere()); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] - public async Task DoNotSuggestForDeclarationExpressionIfItWouldChangeOverloadResolution() - { - await TestMissingInRegularAndScriptAsync(""" - class Program + public static bool TryGetValue(string key, out int value) => false; + public static bool TryGetValue(string key, out bool value, int x) => false; + } + """, options: ImplicitTypeEverywhere()); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] + public async Task DoNotSuggestForDeclarationExpressionIfItWouldChangeOverloadResolution() + { + await TestMissingInRegularAndScriptAsync(""" + class Program + { + static int Main(string[] args) { - static int Main(string[] args) - { - TryGetValue("key", out [|int|] value); - return value; - } + TryGetValue("key", out [|int|] value); + return value; + } - public static bool TryGetValue(string key, out object value) => false; + public static bool TryGetValue(string key, out object value) => false; - public static bool TryGetValue(string key, out T value) => false; - } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + public static bool TryGetValue(string key, out T value) => false; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] - public async Task DoNotSuggestIfChangesGenericTypeInference() - { - await TestMissingInRegularAndScriptAsync(""" - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] + public async Task DoNotSuggestIfChangesGenericTypeInference() + { + await TestMissingInRegularAndScriptAsync(""" + class Program + { + static int Main(string[] args) { - static int Main(string[] args) - { - TryGetValue("key", out [|int|] value); - return value; - } - - public static bool TryGetValue(string key, out T value) => false; + TryGetValue("key", out [|int|] value); + return value; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] - public async Task SuggestIfDoesNotChangeGenericTypeInference1() - { - await TestInRegularAndScriptAsync(""" - class Program - { - static int Main(string[] args) - { - TryGetValue("key", out [|int|] value); - return value; - } + public static bool TryGetValue(string key, out T value) => false; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - public static bool TryGetValue(string key, out T value) => false; - } - """, """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] + public async Task SuggestIfDoesNotChangeGenericTypeInference1() + { + await TestInRegularAndScriptAsync(""" + class Program + { + static int Main(string[] args) { - static int Main(string[] args) - { - TryGetValue("key", out var value); - return value; - } - - public static bool TryGetValue(string key, out T value) => false; + TryGetValue("key", out [|int|] value); + return value; } - """, options: ImplicitTypeEverywhere()); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] - public async Task SuggestIfDoesNotChangeGenericTypeInference2() - { - await TestInRegularAndScriptAsync(""" - class Program + public static bool TryGetValue(string key, out T value) => false; + } + """, """ + class Program + { + static int Main(string[] args) { - static int Main(string[] args) - { - TryGetValue(0, out [|int|] value); - return value; - } - - public static bool TryGetValue(T key, out T value) => false; + TryGetValue("key", out var value); + return value; } - """, """ - class Program - { - static int Main(string[] args) - { - TryGetValue(0, out var value); - return value; - } - public static bool TryGetValue(T key, out T value) => false; - } - """, options: ImplicitTypeEverywhere()); - } + public static bool TryGetValue(string key, out T value) => false; + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] - public async Task SuggestVarForDelegateType() - { - await TestInRegularAndScriptAsync(""" - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23116")] + public async Task SuggestIfDoesNotChangeGenericTypeInference2() + { + await TestInRegularAndScriptAsync(""" + class Program + { + static int Main(string[] args) { - static void Main(string[] args) - { - [|GetHandler|] handler = Handler; - } - - private static GetHandler Handler; - - delegate object GetHandler(); + TryGetValue(0, out [|int|] value); + return value; } - """, """ - class Program + + public static bool TryGetValue(T key, out T value) => false; + } + """, """ + class Program + { + static int Main(string[] args) { - static void Main(string[] args) - { - var handler = Handler; - } + TryGetValue(0, out var value); + return value; + } - private static GetHandler Handler; + public static bool TryGetValue(T key, out T value) => false; + } + """, options: ImplicitTypeEverywhere()); + } - delegate object GetHandler(); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] + public async Task SuggestVarForDelegateType() + { + await TestInRegularAndScriptAsync(""" + class Program + { + static void Main(string[] args) + { + [|GetHandler|] handler = Handler; } - """, options: ImplicitTypeEverywhere()); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] - public async Task DoNotSuggestVarForDelegateType1() - { - await TestMissingInRegularAndScriptAsync(""" - class Program + private static GetHandler Handler; + + delegate object GetHandler(); + } + """, """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - [|GetHandler|] handler = () => new object(); - } + var handler = Handler; + } - private static GetHandler Handler; + private static GetHandler Handler; - delegate object GetHandler(); - } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + delegate object GetHandler(); + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] - public async Task DoNotSuggestVarForDelegateType2() - { - await TestMissingInRegularAndScriptAsync(""" - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] + public async Task DoNotSuggestVarForDelegateType1() + { + await TestMissingInRegularAndScriptAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - [|GetHandler|] handler = Foo; - } + [|GetHandler|] handler = () => new object(); + } - private static GetHandler Handler; + private static GetHandler Handler; - private static object Foo() => new object(); + delegate object GetHandler(); + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - delegate object GetHandler(); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] + public async Task DoNotSuggestVarForDelegateType2() + { + await TestMissingInRegularAndScriptAsync(""" + class Program + { + static void Main(string[] args) + { + [|GetHandler|] handler = Foo; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] - public async Task DoNotSuggestVarForDelegateType3() - { - await TestMissingInRegularAndScriptAsync(""" - class Program - { - static void Main(string[] args) - { - [|GetHandler|] handler = delegate { return new object(); }; - } + private static GetHandler Handler; - private static GetHandler Handler; + private static object Foo() => new object(); - delegate object GetHandler(); - } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + delegate object GetHandler(); + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] - public async Task DoNotSuggestVarForInterfaceVariableInForeachStatement() - { - await TestMissingInRegularAndScriptAsync(""" - public interface ITest - { - string Value { get; } - } - public class TestInstance : ITest + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23711")] + public async Task DoNotSuggestVarForDelegateType3() + { + await TestMissingInRegularAndScriptAsync(""" + class Program + { + static void Main(string[] args) { - string ITest.Value => "Hi"; + [|GetHandler|] handler = delegate { return new object(); }; } - public class Test - { - public TestInstance[] Instances { get; } + private static GetHandler Handler; - public void TestIt() - { - foreach ([|ITest|] test in Instances) - { - Console.WriteLine(test.Value); - } - } - } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + delegate object GetHandler(); + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] - public async Task DoNotSuggestVarForInterfaceVariableInDeclarationStatement() - { - await TestMissingInRegularAndScriptAsync(""" - public interface ITest - { - string Value { get; } - } - public class TestInstance : ITest - { - string ITest.Value => "Hi"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] + public async Task DoNotSuggestVarForInterfaceVariableInForeachStatement() + { + await TestMissingInRegularAndScriptAsync(""" + public interface ITest + { + string Value { get; } + } + public class TestInstance : ITest + { + string ITest.Value => "Hi"; + } + + public class Test + { + public TestInstance[] Instances { get; } - public class Test + public void TestIt() { - public void TestIt() + foreach ([|ITest|] test in Instances) { - [|ITest|] test = new TestInstance(); Console.WriteLine(test.Value); } } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] + public async Task DoNotSuggestVarForInterfaceVariableInDeclarationStatement() + { + await TestMissingInRegularAndScriptAsync(""" + public interface ITest + { + string Value { get; } + } + public class TestInstance : ITest + { + string ITest.Value => "Hi"; + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] - public async Task DoNotSuggestVarForAbstractClassVariableInForeachStatement() - { - await TestMissingInRegularAndScriptAsync(""" - public abstract class MyAbClass + public class Test + { + public void TestIt() { - string Value { get; } + [|ITest|] test = new TestInstance(); + Console.WriteLine(test.Value); } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - public class TestInstance : MyAbClass - { - public string Value => "Hi"; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] + public async Task DoNotSuggestVarForAbstractClassVariableInForeachStatement() + { + await TestMissingInRegularAndScriptAsync(""" + public abstract class MyAbClass + { + string Value { get; } + } - public class Test - { - public TestInstance[] Instances { get; } + public class TestInstance : MyAbClass + { + public string Value => "Hi"; + } + + public class Test + { + public TestInstance[] Instances { get; } - public void TestIt() + public void TestIt() + { + foreach ([|MyAbClass|] instance in Instances) { - foreach ([|MyAbClass|] instance in Instances) - { - Console.WriteLine(instance); - } + Console.WriteLine(instance); } } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] - public async Task DoNotSuggestVarForAbstractClassVariableInDeclarationStatement() - { - await TestMissingInRegularAndScriptAsync(""" - public abstract class MyAbClass - { - string Value { get; } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24262")] + public async Task DoNotSuggestVarForAbstractClassVariableInDeclarationStatement() + { + await TestMissingInRegularAndScriptAsync(""" + public abstract class MyAbClass + { + string Value { get; } + } - public class TestInstance : MyAbClass - { - public string Value => "Hi"; - } + public class TestInstance : MyAbClass + { + public string Value => "Hi"; + } - public class Test - { - public TestInstance[] Instances { get; } + public class Test + { + public TestInstance[] Instances { get; } - public void TestIt() - { - [|MyAbClass|] test = new TestInstance(); - } + public void TestIt() + { + [|MyAbClass|] test = new TestInstance(); } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact] - public async Task DoNoSuggestVarForRefForeachVar() - { - await TestMissingInRegularAndScriptAsync(""" - using System; - namespace System + [Fact] + public async Task DoNoSuggestVarForRefForeachVar() + { + await TestMissingInRegularAndScriptAsync(""" + using System; + namespace System + { + public readonly ref struct Span { - public readonly ref struct Span - { - unsafe public Span(void* pointer, int length) { } + unsafe public Span(void* pointer, int length) { } - public ref SpanEnum GetEnumerator() => throw new Exception(); + public ref SpanEnum GetEnumerator() => throw new Exception(); - public struct SpanEnum - { - public ref int Current => 0; - public bool MoveNext() => false; - } + public struct SpanEnum + { + public ref int Current => 0; + public bool MoveNext() => false; } } - class C + } + class C + { + public void M(Span span) { - public void M(Span span) + foreach ([|ref|] var rx in span) { - foreach ([|ref|] var rx in span) - { - } } } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26923")] - public async Task NoSuggestionOnForeachCollectionExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26923")] + public async Task NoSuggestionOnForeachCollectionExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) + foreach (string arg in [|args|]) { - foreach (string arg in [|args|]) - { - } } } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39171")] - public async Task NoSuggestionForSwitchExpressionDifferentTypes() - { - await TestMissingInRegularAndScriptAsync( - """ - class Program - { - interface IFruit { } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39171")] + public async Task NoSuggestionForSwitchExpressionDifferentTypes() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + interface IFruit { } - class Apple : IFruit { } + class Apple : IFruit { } - class Banana : IFruit { } + class Banana : IFruit { } - public static void Test(string name) + public static void Test(string name) + { + [|IFruit|] fruit = name switch { - [|IFruit|] fruit = name switch - { - "apple" => new Apple(), - "banana" => new Banana(), - _ => null, - }; - } + "apple" => new Apple(), + "banana" => new Banana(), + _ => null, + }; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39171")] - public async Task SuggestSwitchExpressionSameOrInheritedTypes() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39171")] + public async Task SuggestSwitchExpressionSameOrInheritedTypes() + { + await TestInRegularAndScriptAsync( + """ + using System; - class Test { } + class Test { } - class Test2 : Test { } + class Test2 : Test { } - class C + class C + { + void M() { - void M() + var str = "one"; + [|Test|] t = str switch { - var str = "one"; - [|Test|] t = str switch - { - "one" => new Test(), - "two" => new Test2(), - _ => throw new InvalidOperationException("Unknown test."), - }; - } - } - """, - """ - using System; + "one" => new Test(), + "two" => new Test2(), + _ => throw new InvalidOperationException("Unknown test."), + }; + } + } + """, + """ + using System; - class Test { } + class Test { } - class Test2 : Test { } + class Test2 : Test { } - class C + class C + { + void M() { - void M() + var str = "one"; + var t = str switch { - var str = "one"; - var t = str switch - { - "one" => new Test(), - "two" => new Test2(), - _ => throw new InvalidOperationException("Unknown test."), - }; - } - } - """, options: ImplicitTypeEverywhere()); - } + "one" => new Test(), + "two" => new Test2(), + _ => throw new InvalidOperationException("Unknown test."), + }; + } + } + """, options: ImplicitTypeEverywhere()); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32088")] - public async Task DoNotSuggestVarOnDeclarationExpressionWithInferredTupleNames() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - using System.Linq; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32088")] + public async Task DoNotSuggestVarOnDeclarationExpressionWithInferredTupleNames() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + using System.Linq; - static class Program + static class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - if (!_data.TryGetValue(0, [|out List<(int X, int Y)>|] value)) - return; - - var x = value.FirstOrDefault().X; - } + if (!_data.TryGetValue(0, [|out List<(int X, int Y)>|] value)) + return; - private static Dictionary> _data = - new Dictionary>(); + var x = value.FirstOrDefault().X; } - """, parameters: new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32088")] - public async Task DoSuggestVarOnDeclarationExpressionWithMatchingTupleNames() - { - await TestInRegularAndScriptAsync( - """ - using System.Collections.Generic; - using System.Linq; + private static Dictionary> _data = + new Dictionary>(); + } + """, parameters: new TestParameters(options: ImplicitTypeEverywhere())); + } - static class Program - { - static void Main(string[] args) - { - if (!_data.TryGetValue(0, [|out List<(int X, int Y)>|] value)) - return; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/32088")] + public async Task DoSuggestVarOnDeclarationExpressionWithMatchingTupleNames() + { + await TestInRegularAndScriptAsync( + """ + using System.Collections.Generic; + using System.Linq; - var x = value.FirstOrDefault().X; - } + static class Program + { + static void Main(string[] args) + { + if (!_data.TryGetValue(0, [|out List<(int X, int Y)>|] value)) + return; - private static Dictionary> _data = - new Dictionary>(); + var x = value.FirstOrDefault().X; } - """, - """ - using System.Collections.Generic; - using System.Linq; - static class Program - { - static void Main(string[] args) - { - if (!_data.TryGetValue(0, out var value)) - return; + private static Dictionary> _data = + new Dictionary>(); + } + """, + """ + using System.Collections.Generic; + using System.Linq; - var x = value.FirstOrDefault().X; - } + static class Program + { + static void Main(string[] args) + { + if (!_data.TryGetValue(0, out var value)) + return; - private static Dictionary> _data = - new Dictionary>(); + var x = value.FirstOrDefault().X; } - """, + + private static Dictionary> _data = + new Dictionary>(); + } + """, options: ImplicitTypeEverywhere()); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44507")] - public async Task DoNotSuggestVarInAmbiguousSwitchExpression() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44507")] + public async Task DoNotSuggestVarInAmbiguousSwitchExpression() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + var i = 1; + [||]C x = i switch { - var i = 1; - [||]C x = i switch - { - 0 => new A(), - 1 => new B(), - _ => throw new ArgumentException(), - }; - } + 0 => new A(), + 1 => new B(), + _ => throw new ArgumentException(), + }; } + } + + class A : C + { + } + + class B : C + { + } + """, parameters: new TestParameters(options: ImplicitTypeEverywhere())); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44507")] + public async Task DoNotSuggestVarInSwitchExpressionWithDelegateType() + { + await TestMissingAsync( + """ + using System; - class A : C + class C + { + private void M(object sender, EventArgs e) { + var x = 1; + [||]Action a = x switch + { + 0 => (sender, e) => f1(sender, e), + 1 => (sender, e) => f2(sender, e), + _ => throw new ArgumentException() + }; + + a(sender, e); } - class B : C + private readonly Action f1; + private readonly Action f2; + } + """, parameters: new TestParameters(options: ImplicitTypeEverywhere())); + } + + [Fact] + public async Task DoNotSuggestVarForImplicitObjectCreation() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + + class Program + { + void Method() { + [|string|] p = new('c', 1); } - """, parameters: new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44507")] - public async Task DoNotSuggestVarInSwitchExpressionWithDelegateType() - { - await TestMissingAsync( - """ - using System; + } + """, new TestParameters(options: ImplicitTypeEverywhere())); + } - class C - { - private void M(object sender, EventArgs e) - { - var x = 1; - [||]Action a = x switch - { - 0 => (sender, e) => f1(sender, e), - 1 => (sender, e) => f2(sender, e), - _ => throw new ArgumentException() - }; - - a(sender, e); - } + [Fact] + public Task SuggestForNullable1() + => TestInRegularAndScriptAsync( + """ + #nullable enable - private readonly Action f1; - private readonly Action f2; + class C + { + string? M() + { + [|string?|] a = NullableString(); + return a; } - """, parameters: new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact] - public async Task DoNotSuggestVarForImplicitObjectCreation() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + string? NullableString() => null; + } + """, + """ + #nullable enable - class Program + class C + { + string? M() { - void Method() - { - [|string|] p = new('c', 1); - } - + var a = NullableString(); + return a; } - """, new TestParameters(options: ImplicitTypeEverywhere())); - } - [Fact] - public Task SuggestForNullable1() - => TestInRegularAndScriptAsync( - """ - #nullable enable + string? NullableString() => null; + } + """, +options: ImplicitTypeEverywhere()); + + [Fact] + public Task SuggestForNullable2() + => TestInRegularAndScriptAsync( + """ + #nullable enable - class C + class C + { + string? M() { - string? M() - { - [|string?|] a = NullableString(); - return a; - } + [|string?|] a = NonNullString(); + return a; + } + + string NonNullString() => string.Empty; + } + """, + """ + #nullable enable - string? NullableString() => null; + class C + { + string? M() + { + var a = NonNullString(); + return a; } - """, - """ - #nullable enable - class C + string NonNullString() => string.Empty; + } + """, +options: ImplicitTypeEverywhere()); + + [Fact] + public Task SuggestForNullable3() + => TestInRegularAndScriptAsync( + """ + #nullable enable + + class C + { + string? M() { - string? M() - { - var a = NullableString(); - return a; - } + [|string|] a = NonNullString(); + return a; + } + + string NonNullString() => string.Empty; + } + """, + """ + #nullable enable - string? NullableString() => null; + class C + { + string? M() + { + var a = NonNullString(); + return a; } - """, + + string NonNullString() => string.Empty; + } + """, options: ImplicitTypeEverywhere()); - [Fact] - public Task SuggestForNullable2() - => TestInRegularAndScriptAsync( - """ - #nullable enable + [Fact] + public Task SuggestForNullableOut1() + => TestInRegularAndScriptAsync( + """ + #nullable enable - class C + class C + { + string? M() { - string? M() + if (GetNullString(out [|string?|] a)) { - [|string?|] a = NonNullString(); return a; } - string NonNullString() => string.Empty; + return null; + } + + bool GetNullString(out string? s) + { + s = null; + return true; } - """, - """ - #nullable enable + } + """, + """ + #nullable enable - class C + class C + { + string? M() { - string? M() + if (GetNullString(out var a)) { - var a = NonNullString(); return a; } - string NonNullString() => string.Empty; + return null; + } + + bool GetNullString(out string? s) + { + s = null; + return true; } - """, + } + """, options: ImplicitTypeEverywhere()); - [Fact] - public Task SuggestForNullable3() - => TestInRegularAndScriptAsync( - """ - #nullable enable + [Fact] + public Task SuggestForNullableOut2() + => TestInRegularAndScriptAsync( + """ + #nullable enable - class C + class C + { + string? M() { - string? M() + if (GetNonNullString(out [|string?|] a)) { - [|string|] a = NonNullString(); return a; } - string NonNullString() => string.Empty; + return null; } - """, - """ - #nullable enable - class C + bool GetNonNullString(out string s) { - string? M() - { - var a = NonNullString(); - return a; - } - - string NonNullString() => string.Empty; + s = string.Empty; + return true; } - """, -options: ImplicitTypeEverywhere()); - - [Fact] - public Task SuggestForNullableOut1() - => TestInRegularAndScriptAsync( - """ - #nullable enable + } + """, + """ + #nullable enable - class C + class C + { + string? M() { - string? M() + if (GetNonNullString(out var a)) { - if (GetNullString(out [|string?|] a)) - { - return a; - } - - return null; + return a; } - bool GetNullString(out string? s) - { - s = null; - return true; - } + return null; } - """, - """ - #nullable enable - class C + bool GetNonNullString(out string s) { - string? M() - { - if (GetNullString(out var a)) - { - return a; - } - - return null; - } - - bool GetNullString(out string? s) - { - s = null; - return true; - } + s = string.Empty; + return true; } - """, + } + """, options: ImplicitTypeEverywhere()); - [Fact] - public Task SuggestForNullableOut2() - => TestInRegularAndScriptAsync( - """ - #nullable enable + [Fact] + public Task SuggestForNullableOut3() + => TestInRegularAndScriptAsync( + """ + #nullable enable - class C + class C + { + string? M() { - string? M() + if (GetNonNullString(out [|string|] a)) { - if (GetNonNullString(out [|string?|] a)) - { - return a; - } - - return null; + return a; } - bool GetNonNullString(out string s) - { - s = string.Empty; - return true; - } + return null; } - """, - """ - #nullable enable - class C + bool GetNonNullString(out string s) { - string? M() - { - if (GetNonNullString(out var a)) - { - return a; - } - - return null; - } - - bool GetNonNullString(out string s) - { - s = string.Empty; - return true; - } + s = string.Empty; + return true; } - """, -options: ImplicitTypeEverywhere()); - - [Fact] - public Task SuggestForNullableOut3() - => TestInRegularAndScriptAsync( - """ - #nullable enable + } + """, + """ + #nullable enable - class C + class C + { + string? M() { - string? M() + if (GetNonNullString(out var a)) { - if (GetNonNullString(out [|string|] a)) - { - return a; - } - - return null; + return a; } - bool GetNonNullString(out string s) - { - s = string.Empty; - return true; - } + return null; } - """, - """ - #nullable enable - class C + bool GetNonNullString(out string s) { - string? M() - { - if (GetNonNullString(out var a)) - { - return a; - } - - return null; - } - - bool GetNonNullString(out string s) - { - s = string.Empty; - return true; - } + s = string.Empty; + return true; } - """, + } + """, options: ImplicitTypeEverywhere()); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41780")] - public async Task SuggestOnRefType1() - { - await TestAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41780")] + public async Task SuggestOnRefType1() + { + await TestAsync( + """ + class C + { + void Method(ref int x) { - void Method(ref int x) - { - ref [|int|] y = ref x; - } + ref [|int|] y = ref x; } - """, - """ - class C + } + """, + """ + class C + { + void Method(ref int x) { - void Method(ref int x) - { - ref var y = ref x; - } + ref var y = ref x; } - """, CSharpParseOptions.Default, options: ImplicitTypeEverywhere()); - } + } + """, CSharpParseOptions.Default, options: ImplicitTypeEverywhere()); } } diff --git a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests_FixAllTests.cs index 3609f9a2c5488..e6ad934c8b88f 100644 --- a/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/UseImplicitOrExplicitType/UseImplicitTypeTests_FixAllTests.cs @@ -8,412 +8,411 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseImplicitType +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.UseImplicitType; + +public partial class UseImplicitTypeTests { - public partial class UseImplicitTypeTests + #region "Fix all occurrences tests" + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocumentScope_PreferImplicitTypeEverywhere() { - #region "Fix all occurrences tests" - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocumentScope_PreferImplicitTypeEverywhere() - { - var input = """ - - - - using System; - - class Program + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInDocument:int|} i1 = 0; - Program p = new Program(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + {|FixAllInDocument:int|} i1 = 0; + Program p = new Program(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); - class Program2 - { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + return i1; } - - - - - using System; - - class Program2 + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i1 = 0; - var p = new Program(); - var tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); - class Program2 - { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + return i1; } - - - - - using System; - - class Program2 + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i1 = 0; - Program2 p = new Program2(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + var i1 = 0; + var p = new Program(); + var tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeEverywhere()); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInProject_PreferImplicitTypeEverywhere() - { - var input = """ - - - - using System; - - class Program + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInProject:int|} i1 = 0; - Program p = new Program(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); - class Program2 + return i1; + } + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i2 = 0; - Program2 p2 = new Program2(); - Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - - return i2; - } + int i1 = 0; + Program2 p = new Program2(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - - using System; + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeEverywhere()); + } - class Program2 + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject_PreferImplicitTypeEverywhere() + { + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i3 = 0; - Program2 p3 = new Program2(); - Tuple<bool, int> tuple3 = Tuple.Create(true, 1); - - return i3; - } + {|FixAllInProject:int|} i1 = 0; + Program p = new Program(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i1 = 0; - var p = new Program(); - var tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + int i2 = 0; + Program2 p2 = new Program2(); + Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - class Program2 - { - static int F(int x, int y) - { - var i2 = 0; - var p2 = new Program2(); - var tuple2 = Tuple.Create(true, 1); - - return i2; - } + return i2; } - - - - - using System; - - class Program2 + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i3 = 0; - Program2 p3 = new Program2(); - Tuple<bool, int> tuple3 = Tuple.Create(true, 1); - - return i3; - } + int i3 = 0; + Program2 p3 = new Program2(); + Tuple<bool, int> tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeEverywhere()); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInSolution_PreferImplicitTypeEverywhere() - { - var input = """ - - - - using System; - - class Program + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInSolution:int|} i1 = 0; - Program p = new Program(); - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + var i1 = 0; + var p = new Program(); + var tuple = Tuple.Create(true, 1); + + return i1; } - - - using System; + } + + + using System; + + class Program2 + { + static int F(int x, int y) + { + var i2 = 0; + var p2 = new Program2(); + var tuple2 = Tuple.Create(true, 1); - class Program2 + return i2; + } + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i2 = 0; - Program2 p2 = new Program2(); - Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - - return i2; - } + int i3 = 0; + Program2 p3 = new Program2(); + Tuple<bool, int> tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - - using System; + } + + + + """; - class Program2 + await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeEverywhere()); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution_PreferImplicitTypeEverywhere() + { + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - int i3 = 0; - Program2 p3 = new Program2(); - Tuple<bool, int> tuple3 = Tuple.Create(true, 1); - - return i3; - } + {|FixAllInSolution:int|} i1 = 0; + Program p = new Program(); + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i1 = 0; - var p = new Program(); - var tuple = Tuple.Create(true, 1); - - return i1; - } - } - - - using System; + int i2 = 0; + Program2 p2 = new Program2(); + Tuple<bool, int> tuple2 = Tuple.Create(true, 1); - class Program2 + return i2; + } + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i2 = 0; - var p2 = new Program2(); - var tuple2 = Tuple.Create(true, 1); - - return i2; - } + int i3 = 0; + Program2 p3 = new Program2(); + Tuple<bool, int> tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - - using System; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) + { + var i1 = 0; + var p = new Program(); + var tuple = Tuple.Create(true, 1); - class Program2 + return i1; + } + } + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - var i3 = 0; - var p3 = new Program2(); - var tuple3 = Tuple.Create(true, 1); - - return i3; - } + var i2 = 0; + var p2 = new Program2(); + var tuple2 = Tuple.Create(true, 1); + + return i2; } - - - - """; - - await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeEverywhere()); - } - - [Fact] - [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] - [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] - public async Task TestFixAllInDocumentScope_PreferBuiltInTypes() - { - var input = """ - - - - using System; - - class Program + } + + + + + using System; + + class Program2 + { + static int F(int x, int y) { - static int F(int x, int y) - { - {|FixAllInDocument:Program|} p = new Program(); - int i1 = 0; - Tuple<bool, int> tuple = Tuple.Create(true, 1); - - return i1; - } + var i3 = 0; + var p3 = new Program2(); + var tuple3 = Tuple.Create(true, 1); + + return i3; } - - - - """; - - var expected = """ - - - - using System; - - class Program + } + + + + """; + + await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeEverywhere()); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocumentScope_PreferBuiltInTypes() + { + var input = """ + + + + using System; + + class Program + { + static int F(int x, int y) { - static int F(int x, int y) - { - var p = new Program(); - int i1 = 0; - var tuple = Tuple.Create(true, 1); - - return i1; - } + {|FixAllInDocument:Program|} p = new Program(); + int i1 = 0; + Tuple<bool, int> tuple = Tuple.Create(true, 1); + + return i1; } - - - - """; + } + + + + """; + + var expected = """ + + + + using System; + + class Program + { + static int F(int x, int y) + { + var p = new Program(); + int i1 = 0; + var tuple = Tuple.Create(true, 1); - await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeButKeepIntrinsics()); - } + return i1; + } + } + + + + """; - #endregion + await TestInRegularAndScriptAsync(input, expected, options: ImplicitTypeButKeepIntrinsics()); } + + #endregion } diff --git a/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseIndexOperatorTests.cs b/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseIndexOperatorTests.cs index 4d958c710be5f..aaa1b12f1e9a8 100644 --- a/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseIndexOperatorTests.cs +++ b/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseIndexOperatorTests.cs @@ -11,819 +11,818 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIndexOrRangeOperator -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseIndexOperatorDiagnosticAnalyzer, - CSharpUseIndexOperatorCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIndexOrRangeOperator; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseIndexOperatorDiagnosticAnalyzer, + CSharpUseIndexOperatorCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseIndexOperator)] - public class UseIndexOperatorTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseIndexOperator)] +public class UseIndexOperatorTests +{ + [Fact] + public async Task TestNotInCSharp7() { - [Fact] - public async Task TestNotInCSharp7() - { - var source = - """ - class C + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[s.Length - 1]; - } + var v = s[s.Length - 1]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } + } + """; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseRangeOperator)] - public async Task TestWithMissingReference() + await new VerifyCS.Test { - var source = - """ - class {|#0:C|} - { - {|#1:void|} Goo({|#2:string|} s) - { - var v = s[s.Length - {|#3:1|}]; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseRangeOperator)] + public async Task TestWithMissingReference() + { + var source = + """ + class {|#0:C|} { - ReferenceAssemblies = new ReferenceAssemblies("custom"), - TestCode = source, - ExpectedDiagnostics = + {|#1:void|} Goo({|#2:string|} s) { - // /0/Test0.cs(1,7): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(0).WithArguments("System.Object"), - // /0/Test0.cs(1,7): error CS1729: 'object' does not contain a constructor that takes 0 arguments - DiagnosticResult.CompilerError("CS1729").WithLocation(0).WithArguments("object", "0"), - // /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Void' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(1).WithArguments("System.Void"), - // /0/Test0.cs(3,14): error CS0518: Predefined type 'System.String' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(2).WithArguments("System.String"), - // /0/Test0.cs(5,30): error CS0518: Predefined type 'System.Int32' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(3).WithArguments("System.Int32"), - }, - FixedCode = source, - }.RunAsync(); - } + var v = s[s.Length - {|#3:1|}]; + } + } + """; - [Fact] - public async Task TestSimple() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = new ReferenceAssemblies("custom"), + TestCode = source, + ExpectedDiagnostics = + { + // /0/Test0.cs(1,7): error CS0518: Predefined type 'System.Object' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(0).WithArguments("System.Object"), + // /0/Test0.cs(1,7): error CS1729: 'object' does not contain a constructor that takes 0 arguments + DiagnosticResult.CompilerError("CS1729").WithLocation(0).WithArguments("object", "0"), + // /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Void' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(1).WithArguments("System.Void"), + // /0/Test0.cs(3,14): error CS0518: Predefined type 'System.String' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(2).WithArguments("System.String"), + // /0/Test0.cs(5,30): error CS0518: Predefined type 'System.Int32' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(3).WithArguments("System.Int32"), + }, + FixedCode = source, + }.RunAsync(); + } + + [Fact] + public async Task TestSimple() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[[|s.Length - 1|]]; - } + var v = s[[|s.Length - 1|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[^1]; - } + var v = s[^1]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestMultipleDefinitions() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestMultipleDefinitions() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[[|s.Length - 1|]]; - } + var v = s[[|s.Length - 1|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[^1]; - } + var v = s[^1]; } - """; + } + """; - // Adding a dependency with internal definitions of Index and Range should not break the feature - var source1 = "namespace System { internal struct Index { } internal struct Range { } }"; + // Adding a dependency with internal definitions of Index and Range should not break the feature + var source1 = "namespace System { internal struct Index { } internal struct Range { } }"; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestState = { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestState = + Sources = { source }, + AdditionalProjects = { - Sources = { source }, - AdditionalProjects = + ["DependencyProject"] = { - ["DependencyProject"] = - { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20, - Sources = { source1 }, - }, + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20, + Sources = { source1 }, }, - AdditionalProjectReferences = { "DependencyProject" }, }, - FixedCode = fixedSource, - }.RunAsync(); - } + AdditionalProjectReferences = { "DependencyProject" }, + }, + FixedCode = fixedSource, + }.RunAsync(); + } - [Fact] - public async Task TestComplexSubtaction() - { - var source = - """ - class C + [Fact] + public async Task TestComplexSubtaction() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[[|s.Length - (1 + 1)|]]; - } + var v = s[[|s.Length - (1 + 1)|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[^(1 + 1)]; - } + var v = s[^(1 + 1)]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestComplexInstance() + await new VerifyCS.Test { - var source = - """ - using System.Linq; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - class C - { - void Goo(string[] ss) - { - var v = ss.Last()[[|ss.Last().Length - 3|]]; - } - } - """; - var fixedSource = - """ - using System.Linq; + [Fact] + public async Task TestComplexInstance() + { + var source = + """ + using System.Linq; - class C + class C + { + void Goo(string[] ss) { - void Goo(string[] ss) - { - var v = ss.Last()[^3]; - } + var v = ss.Last()[[|ss.Last().Length - 3|]]; } - """; + } + """; + var fixedSource = + """ + using System.Linq; - await new VerifyCS.Test + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithoutSubtraction1() - { - var source = - """ - class C + void Goo(string[] ss) { - void Goo(string s) - { - var v = s[s.Length]; - } + var v = ss.Last()[^3]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotWithoutSubtraction2() + await new VerifyCS.Test { - var source = - """ - class C - { - void Goo(string s) - { - var v = s[s.Length + 1]; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestNotWithoutSubtraction1() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + void Goo(string s) + { + var v = s[s.Length]; + } + } + """; - [Fact] - public async Task TestNotWithMultipleArgs() + await new VerifyCS.Test { - var source = - """ - struct S { public int Length { get; } public int this[int i] { get => 0; } public int this[int i, int j] { get => 0; } public int this[System.Index i] { get => 0; } } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithoutSubtraction2() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(S s) - { - var v = s[s.Length - 1, 2]; - } + var v = s[s.Length + 1]; } - """; + } + """; + + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestNotWithMultipleArgs() + { + var source = + """ + struct S { public int Length { get; } public int this[int i] { get => 0; } public int this[int i, int j] { get => 0; } public int this[System.Index i] { get => 0; } } + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + void Goo(S s) + { + var v = s[s.Length - 1, 2]; + } + } + """; - [Fact] - public async Task TestUserDefinedTypeWithLength() + await new VerifyCS.Test { - var source = - """ - struct S { public int Length { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } + + [Fact] + public async Task TestUserDefinedTypeWithLength() + { + var source = + """ + struct S { public int Length { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[[|s.Length - 2|]]; - } + var v = s[[|s.Length - 2|]]; } - """; - var fixedSource = - """ - struct S { public int Length { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } - class C + } + """; + var fixedSource = + """ + struct S { public int Length { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[^2]; - } + var v = s[^2]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestUserDefinedTypeWithCount() + await new VerifyCS.Test { - var source = - """ - struct S { public int Count { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestUserDefinedTypeWithCount() + { + var source = + """ + struct S { public int Count { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[[|s.Count - 2|]]; - } + var v = s[[|s.Count - 2|]]; } - """; - var fixedSource = - """ - struct S { public int Count { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } - class C + } + """; + var fixedSource = + """ + struct S { public int Count { get; } public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[^2]; - } + var v = s[^2]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestUserDefinedTypeWithNoLengthOrCount() + await new VerifyCS.Test { - var source = - """ - struct S { public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } - class C - { - void Goo(S s) - { - var v = s[s.{|CS1061:Count|} - 2]; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestUserDefinedTypeWithNoLengthOrCount() + { + var source = + """ + struct S { public int this[int i] { get => 0; } public int this[System.Index i] { get => 0; } } + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } - - [Fact] - public async Task TestUserDefinedTypeWithNoInt32Indexer() - { - var source = - """ - struct S { public int Length { get; } public int this[System.Index i] { get => 0; } } - class C + void Goo(S s) { - void Goo(S s) - { - var v = s[s.Length - 2]; - } + var v = s[s.{|CS1061:Count|} - 2]; } - """; + } + """; + + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestUserDefinedTypeWithNoInt32Indexer() + { + var source = + """ + struct S { public int Length { get; } public int this[System.Index i] { get => 0; } } + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + void Goo(S s) + { + var v = s[s.Length - 2]; + } + } + """; - [Fact] - public async Task TestUserDefinedTypeWithNoIndexIndexer() + await new VerifyCS.Test { - var source = - """ - struct S { public int Count { get; } public int this[int i] { get => 0; } } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } + + [Fact] + public async Task TestUserDefinedTypeWithNoIndexIndexer() + { + var source = + """ + struct S { public int Count { get; } public int this[int i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[[|s.Count - 2|]]; - } + var v = s[[|s.Count - 2|]]; } - """; - var fixedSource = - """ - struct S { public int Count { get; } public int this[int i] { get => 0; } } - class C + } + """; + var fixedSource = + """ + struct S { public int Count { get; } public int this[int i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[^2]; - } + var v = s[^2]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestMethodToMethod() + await new VerifyCS.Test { - var source = - """ - struct S { public int Length { get; } public int Get(int i) => 0; public int Get(System.Index i) => 0; } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestMethodToMethod() + { + var source = + """ + struct S { public int Length { get; } public int Get(int i) => 0; public int Get(System.Index i) => 0; } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s.Get([|s.Length - 1|]); - } + var v = s.Get([|s.Length - 1|]); } - """; - var fixedSource = - """ - struct S { public int Length { get; } public int Get(int i) => 0; public int Get(System.Index i) => 0; } - class C + } + """; + var fixedSource = + """ + struct S { public int Length { get; } public int Get(int i) => 0; public int Get(System.Index i) => 0; } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s.Get(^1); - } + var v = s.Get(^1); } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestMethodToMethodMissingIndexIndexer() + await new VerifyCS.Test { - var source = - """ - struct S { public int Length { get; } public int Get(int i) => 0; } - class C - { - void Goo(S s) - { - var v = s.Get(s.Length - 1); - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestMethodToMethodMissingIndexIndexer() + { + var source = + """ + struct S { public int Length { get; } public int Get(int i) => 0; } + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } - - [Fact] - public async Task TestMethodToMethodWithIntIndexer() - { - var source = - """ - struct S { public int Length { get; } public int Get(int i) => 0; public int this[int i] { get => 0; } } - class C + void Goo(S s) { - void Goo(S s) - { - var v = s.Get(s.Length - 1); - } + var v = s.Get(s.Length - 1); } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36909")] - public async Task TestMissingWithNoSystemIndex() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } + + [Fact] + public async Task TestMethodToMethodWithIntIndexer() + { + var source = + """ + struct S { public int Length { get; } public int Get(int i) => 0; public int this[int i] { get => 0; } } + class C + { + void Goo(S s) { - void Goo(string[] s) - { - var v = s[s.Length - 1]; - } + var v = s.Get(s.Length - 1); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36909")] + public async Task TestMissingWithNoSystemIndex() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + void Goo(string[] s) + { + var v = s[s.Length - 1]; + } + } + """; - [Fact] - public async Task TestMissingWithInaccessibleSystemIndex() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestMissingWithInaccessibleSystemIndex() + { + var source = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v = s[s.Length - 1]; - } + var v = s[s.Length - 1]; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, + TestState = { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, - TestState = + Sources = { source }, + AdditionalProjects = { - Sources = { source }, - AdditionalProjects = + ["AdditionalProject"] = { - ["AdditionalProject"] = + Sources = { - Sources = - { - "namespace System { internal struct Index { } }" - } + "namespace System { internal struct Index { } }" } - }, - AdditionalProjectReferences = { "AdditionalProject" }, + } }, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + AdditionalProjectReferences = { "AdditionalProject" }, + }, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - [Fact] - public async Task TestArray() - { - var source = - """ - class C + [Fact] + public async Task TestArray() + { + var source = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v = s[[|s.Length - 1|]]; - } + var v = s[[|s.Length - 1|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v = s[^1]; - } + var v = s[^1]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestFixAll1() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestFixAll1() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v1 = s[[|s.Length - 1|]]; - var v2 = s[[|s.Length - 1|]]; - } + var v1 = s[[|s.Length - 1|]]; + var v2 = s[[|s.Length - 1|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v1 = s[^1]; - var v2 = s[^1]; - } + var v1 = s[^1]; + var v2 = s[^1]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestNestedFixAll1() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestNestedFixAll1() + { + var source = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v1 = s[[|s.Length - 2|]][[|s[[|s.Length - 2|]].Length - 1|]]; - } + var v1 = s[[|s.Length - 2|]][[|s[[|s.Length - 2|]].Length - 1|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v1 = s[^2][^1]; - } + var v1 = s[^2][^1]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestNestedFixAll2() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestNestedFixAll2() + { + var source = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v1 = s[[|s.Length - 2|]][[|s[[|s.Length - 2|]].Length - 1|]]; - } + var v1 = s[[|s.Length - 2|]][[|s[[|s.Length - 2|]].Length - 1|]]; } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string[] s) { - void Goo(string[] s) - { - var v1 = s[^2][^1]; - } + var v1 = s[^2][^1]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestSimple_NoIndexIndexer_SupportsIntIndexer() + await new VerifyCS.Test { - var source = - """ - using System.Collections.Generic; - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestSimple_NoIndexIndexer_SupportsIntIndexer() + { + var source = + """ + using System.Collections.Generic; + class C + { + void Goo(List s) { - void Goo(List s) - { - var v = s[[|s.Count - 1|]]; - } + var v = s[[|s.Count - 1|]]; } - """; - var fixedSource = - """ - using System.Collections.Generic; - class C + } + """; + var fixedSource = + """ + using System.Collections.Generic; + class C + { + void Goo(List s) { - void Goo(List s) - { - var v = s[^1]; - } + var v = s[^1]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestSimple_NoIndexIndexer_SupportsIntIndexer_Set() + await new VerifyCS.Test { - var source = - """ - using System.Collections.Generic; - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestSimple_NoIndexIndexer_SupportsIntIndexer_Set() + { + var source = + """ + using System.Collections.Generic; + class C + { + void Goo(List s) { - void Goo(List s) - { - s[[|s.Count - 1|]] = 1; - } + s[[|s.Count - 1|]] = 1; } - """; - var fixedSource = - """ - using System.Collections.Generic; - class C + } + """; + var fixedSource = + """ + using System.Collections.Generic; + class C + { + void Goo(List s) { - void Goo(List s) - { - s[^1] = 1; - } + s[^1] = 1; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task NotOnConstructedIndexer() + await new VerifyCS.Test { - var source = - """ - using System.Collections.Generic; - class C - { - void Goo(Dictionary s) - { - var v = s[s.Count - 1]; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task NotOnConstructedIndexer() + { + var source = + """ + using System.Collections.Generic; + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + void Goo(Dictionary s) + { + var v = s[s.Count - 1]; + } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49347")] - public async Task TestNotInExpressionTree() + await new VerifyCS.Test { - var source = - """ - using System; - using System.Collections.Generic; - using System.Linq.Expressions; - class C - { - void Goo(List s) - { - Expression> f = () => s[s.Count - 1]; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49347")] + public async Task TestNotInExpressionTree() + { + var source = + """ + using System; + using System.Collections.Generic; + using System.Linq.Expressions; + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + void Goo(List s) + { + Expression> f = () => s[s.Count - 1]; + } + } + """; + + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseRangeOperatorTests.cs b/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseRangeOperatorTests.cs index 501c2444e9b39..1465302c90134 100644 --- a/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseRangeOperatorTests.cs +++ b/src/Analyzers/CSharp/Tests/UseIndexOrRangeOperator/UseRangeOperatorTests.cs @@ -11,1347 +11,1346 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIndexOrRangeOperator -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseRangeOperatorDiagnosticAnalyzer, - CSharpUseRangeOperatorCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIndexOrRangeOperator; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseRangeOperatorDiagnosticAnalyzer, + CSharpUseRangeOperatorCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseRangeOperator)] - public class UseRangeOperatorTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseRangeOperator)] +public class UseRangeOperatorTests +{ + [Fact] + public async Task TestNotInCSharp7() { - [Fact] - public async Task TestNotInCSharp7() - { - var source = - """ - class C + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring(1, s.Length - 1); - } + var v = s.Substring(1, s.Length - 1); } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } - - [Fact] - public async Task TestWithMissingReference() + await new VerifyCS.Test { - var source = - """ - class {|#0:C|} + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } + + [Fact] + public async Task TestWithMissingReference() + { + var source = + """ + class {|#0:C|} + { + {|#1:void|} Goo({|#2:string|} s) { - {|#1:void|} Goo({|#2:string|} s) - { - var v = s.Substring({|#3:1|}, s.Length - {|#4:1|}); - } + var v = s.Substring({|#3:1|}, s.Length - {|#4:1|}); } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = new ReferenceAssemblies("custom"), - TestCode = source, - ExpectedDiagnostics = - { - // /0/Test0.cs(1,7): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(0).WithArguments("System.Object"), - // /0/Test0.cs(1,7): error CS1729: 'object' does not contain a constructor that takes 0 arguments - DiagnosticResult.CompilerError("CS1729").WithLocation(0).WithArguments("object", "0"), - // /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Void' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(1).WithArguments("System.Void"), - // /0/Test0.cs(3,14): error CS0518: Predefined type 'System.String' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(2).WithArguments("System.String"), - // /0/Test0.cs(5,29): error CS0518: Predefined type 'System.Int32' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(3).WithArguments("System.Int32"), - // /0/Test0.cs(5,43): error CS0518: Predefined type 'System.Int32' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithLocation(4).WithArguments("System.Int32"), - }, - FixedCode = source, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36909")] - public async Task TestNotWithoutSystemRange() + await new VerifyCS.Test { - var source = - """ - class C - { - void Goo(string s) - { - var v = s.Substring(1, s.Length - 1); - } - } - """; + ReferenceAssemblies = new ReferenceAssemblies("custom"), + TestCode = source, + ExpectedDiagnostics = + { + // /0/Test0.cs(1,7): error CS0518: Predefined type 'System.Object' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(0).WithArguments("System.Object"), + // /0/Test0.cs(1,7): error CS1729: 'object' does not contain a constructor that takes 0 arguments + DiagnosticResult.CompilerError("CS1729").WithLocation(0).WithArguments("object", "0"), + // /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Void' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(1).WithArguments("System.Void"), + // /0/Test0.cs(3,14): error CS0518: Predefined type 'System.String' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(2).WithArguments("System.String"), + // /0/Test0.cs(5,29): error CS0518: Predefined type 'System.Int32' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(3).WithArguments("System.Int32"), + // /0/Test0.cs(5,43): error CS0518: Predefined type 'System.Int32' is not defined or imported + DiagnosticResult.CompilerError("CS0518").WithLocation(4).WithArguments("System.Int32"), + }, + FixedCode = source, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36909")] + public async Task TestNotWithoutSystemRange() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + void Goo(string s) + { + var v = s.Substring(1, s.Length - 1); + } + } + """; - [Fact] - public async Task TestNotWithInaccessibleSystemRange() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithInaccessibleSystemRange() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring(1, s.Length - 1); - } + var v = s.Substring(1, s.Length - 1); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, + TestState = { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp20, - TestState = + Sources = { source }, + AdditionalProjects = { - Sources = { source }, - AdditionalProjects = + ["AdditionalProject"] = { - ["AdditionalProject"] = + Sources = { - Sources = - { - "namespace System { internal struct Range { } }" - } + "namespace System { internal struct Range { } }" } - }, - AdditionalProjectReferences = { "AdditionalProject" }, + } }, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + AdditionalProjectReferences = { "AdditionalProject" }, + }, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - [Fact] - public async Task TestSimple() - { - var source = - """ - class C + [Fact] + public async Task TestSimple() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|1, s.Length - 1|]); - } + var v = s.Substring([|1, s.Length - 1|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[1..]; - } + var v = s[1..]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIndexOperator)] - public async Task TestMultipleDefinitions() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseIndexOperator)] + public async Task TestMultipleDefinitions() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|1, s.Length - 1|]); - } + var v = s.Substring([|1, s.Length - 1|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[1..]; - } + var v = s[1..]; } - """; + } + """; - // Adding a dependency with internal definitions of Index and Range should not break the feature - var source1 = "namespace System { internal struct Index { } internal struct Range { } }"; + // Adding a dependency with internal definitions of Index and Range should not break the feature + var source1 = "namespace System { internal struct Index { } internal struct Range { } }"; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestState = { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestState = + Sources = { source }, + AdditionalProjects = { - Sources = { source }, - AdditionalProjects = + ["DependencyProject"] = { - ["DependencyProject"] = - { - ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20, - Sources = { source1 }, - }, + ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20, + Sources = { source1 }, }, - AdditionalProjectReferences = { "DependencyProject" }, }, - FixedCode = fixedSource, - }.RunAsync(); - } + AdditionalProjectReferences = { "DependencyProject" }, + }, + FixedCode = fixedSource, + }.RunAsync(); + } - [Fact] - public async Task TestComplexSubstraction() - { - var source = - """ - class C + [Fact] + public async Task TestComplexSubstraction() + { + var source = + """ + class C + { + void Goo(string s, int bar, int baz) { - void Goo(string s, int bar, int baz) - { - var v = s.Substring([|bar, s.Length - baz - bar|]); - } + var v = s.Substring([|bar, s.Length - baz - bar|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s, int bar, int baz) { - void Goo(string s, int bar, int baz) - { - var v = s[bar..^baz]; - } + var v = s[bar..^baz]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestSubstringOneArgument() + await new VerifyCS.Test { - var source = - """ - class C - { - void Goo(string s) - { - var v = s.Substring([|1|]); - } - } - """; - var fixedSource = - """ - class C - { - void Goo(string s) - { - var v = s[1..]; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestSubstringOneArgument() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestSliceOneArgument() - { - var source = - """ - using System; - class C + void Goo(string s) { - void Goo(Span s) - { - var v = s.Slice([|1|]); - } + var v = s.Substring([|1|]); } - """; - var fixedSource = - """ - using System; - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(Span s) - { - var v = s[1..]; - } + var v = s[1..]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestExpressionOneArgument() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestSliceOneArgument() + { + var source = + """ + using System; + class C + { + void Goo(Span s) { - void Goo(string s, int bar) - { - var v = s.Substring([|bar|]); - } + var v = s.Slice([|1|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + using System; + class C + { + void Goo(Span s) { - void Goo(string s, int bar) - { - var v = s[bar..]; - } + var v = s[1..]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestConstantSubtraction1() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestExpressionOneArgument() + { + var source = + """ + class C + { + void Goo(string s, int bar) { - void Goo(string s) - { - var v = s.Substring([|1, s.Length - 2|]); - } + var v = s.Substring([|bar|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s, int bar) { - void Goo(string s) - { - var v = s[1..^1]; - } + var v = s[bar..]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithoutSubtraction() + await new VerifyCS.Test { - var source = - """ - class C - { - void Goo(string s) - { - var v = s.Substring(1, 2); - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestConstantSubtraction1() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } - - [Fact] - public async Task TestNonStringType() - { - var source = - """ - struct S { public S Slice(int start, int length) => default; public int Length { get; } public S this[System.Range r] { get => default; } } - class C + void Goo(string s) { - void Goo(S s) - { - var v = s.Slice([|1, s.Length - 2|]); - } + var v = s.Substring([|1, s.Length - 2|]); } - """; - var fixedSource = - """ - struct S { public S Slice(int start, int length) => default; public int Length { get; } public S this[System.Range r] { get => default; } } - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(S s) - { - var v = s[1..^1]; - } + var v = s[1..^1]; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithoutSubtraction() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + void Goo(string s) + { + var v = s.Substring(1, 2); + } + } + """; - [Fact] - public async Task TestNonStringTypeWithoutRangeIndexer() + await new VerifyCS.Test { - var source = - """ - struct S { public S Slice(int start, int length) => default; public int Length { get; } } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } + + [Fact] + public async Task TestNonStringType() + { + var source = + """ + struct S { public S Slice(int start, int length) => default; public int Length { get; } public S this[System.Range r] { get => default; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s.Slice([|1, s.Length - 2|]); - } + var v = s.Slice([|1, s.Length - 2|]); } - """; - var fixedSource = - """ - struct S { public S Slice(int start, int length) => default; public int Length { get; } } - class C + } + """; + var fixedSource = + """ + struct S { public S Slice(int start, int length) => default; public int Length { get; } public S this[System.Range r] { get => default; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s[1..^1]; - } + var v = s[1..^1]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestNonStringType_Assignment() + await new VerifyCS.Test { - var source = - """ - struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public ref S this[System.Range r] { get => throw null; } } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestNonStringTypeWithoutRangeIndexer() + { + var source = + """ + struct S { public S Slice(int start, int length) => default; public int Length { get; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - s.Slice([|1, s.Length - 2|]) = default; - } + var v = s.Slice([|1, s.Length - 2|]); } - """; - var fixedSource = - """ - struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public ref S this[System.Range r] { get => throw null; } } - class C + } + """; + var fixedSource = + """ + struct S { public S Slice(int start, int length) => default; public int Length { get; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - s[1..^1] = default; - } + var v = s[1..^1]; } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestMethodToMethod() + await new VerifyCS.Test { - var source = - """ - struct S { public int Slice(int start, int length) => 0; public int Length { get; } public int Slice(System.Range r) => 0; } - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestNonStringType_Assignment() + { + var source = + """ + struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public ref S this[System.Range r] { get => throw null; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s.Slice([|1, s.Length - 2|]); - } + s.Slice([|1, s.Length - 2|]) = default; } - """; - var fixedSource = - """ - struct S { public int Slice(int start, int length) => 0; public int Length { get; } public int Slice(System.Range r) => 0; } - class C + } + """; + var fixedSource = + """ + struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public ref S this[System.Range r] { get => throw null; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - var v = s.Slice(1..^1); - } + s[1..^1] = default; } - """; + } + """; + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestMethodToMethod() + { + var source = + """ + struct S { public int Slice(int start, int length) => 0; public int Length { get; } public int Slice(System.Range r) => 0; } + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestFixAllInvocationToElementAccess1() - { - // Note: once the IOp tree has support for range operators, this should - // simplify even further. - var source = - """ - class C + void Goo(S s) { - void Goo(string s, string t) - { - var v = t.Substring([|s.Substring([|1, s.Length - 2|])[0], t.Length - s.Substring([|1, s.Length - 2|])[0]|]); - } + var v = s.Slice([|1, s.Length - 2|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + struct S { public int Slice(int start, int length) => 0; public int Length { get; } public int Slice(System.Range r) => 0; } + class C + { + void Goo(S s) { - void Goo(string s, string t) - { - var v = t[s[1..^1][0]..]; - } + var v = s.Slice(1..^1); } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact] - public async Task TestFixAllInvocationToElementAccess2() + await new VerifyCS.Test { - // Note: once the IOp tree has support for range operators, this should - // simplify even further. - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestFixAllInvocationToElementAccess1() + { + // Note: once the IOp tree has support for range operators, this should + // simplify even further. + var source = + """ + class C + { + void Goo(string s, string t) { - void Goo(string s, string t) - { - var v = t.Substring([|s.Substring([|1|])[0]|]); - } + var v = t.Substring([|s.Substring([|1, s.Length - 2|])[0], t.Length - s.Substring([|1, s.Length - 2|])[0]|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s, string t) { - void Goo(string s, string t) - { - var v = t[s[1..][0]..]; - } + var v = t[s[1..^1][0]..]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestWithTypeWithActualSliceMethod1() + await new VerifyCS.Test { - var source = - """ - using System; - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestFixAllInvocationToElementAccess2() + { + // Note: once the IOp tree has support for range operators, this should + // simplify even further. + var source = + """ + class C + { + void Goo(string s, string t) { - void Goo(Span s) - { - var v = s.Slice([|1, s.Length - 1|]); - } + var v = t.Substring([|s.Substring([|1|])[0]|]); } - """; - var fixedSource = - """ - using System; - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s, string t) { - void Goo(Span s) - { - var v = s[1..]; - } + var v = t[s[1..][0]..]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestWithTypeWithActualSliceMethod2() + await new VerifyCS.Test { - var source = - """ - using System; - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestWithTypeWithActualSliceMethod1() + { + var source = + """ + using System; + class C + { + void Goo(Span s) { - void Goo(Span s) - { - var v = s.Slice([|1, s.Length - 2|]); - } + var v = s.Slice([|1, s.Length - 1|]); } - """; - var fixedSource = - """ - using System; - class C + } + """; + var fixedSource = + """ + using System; + class C + { + void Goo(Span s) { - void Goo(Span s) - { - var v = s[1..^1]; - } + var v = s[1..]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43202")] - public async Task TestWritableType() + await new VerifyCS.Test { - var source = - """ - using System; - struct S { - public ref S Slice(int start, int length) => throw null; - public int Length { get; } - public S this[System.Range r] { get => default; } - } - - class C - { - void Goo(S s) - { - s.Slice(1, s.Length - 2) = default; - } - } - """; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestWithTypeWithActualSliceMethod2() + { + var source = + """ + using System; + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } - [Fact] - public async Task TestReturnByRef() - { - var source = - """ - struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public S this[System.Range r] { get => throw null; } } - class C + void Goo(Span s) { - void Goo(S s) - { - var x = s.Slice([|1, s.Length - 2|]); - } + var v = s.Slice([|1, s.Length - 2|]); } - """; - var fixedSource = - """ - struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public S this[System.Range r] { get => throw null; } } - class C + } + """; + var fixedSource = + """ + using System; + class C + { + void Goo(Span s) { - void Goo(S s) - { - var x = s[1..^1]; - } + var v = s[1..^1]; } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43202")] - public async Task TestIntWritableType() + await new VerifyCS.Test { - var source = - """ - using System; - struct S { - public ref S Slice(int start, int length) => throw null; - public int Length { get; } - public S this[int r] { get => default; } - } + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43202")] + public async Task TestWritableType() + { + var source = + """ + using System; + struct S { + public ref S Slice(int start, int length) => throw null; + public int Length { get; } + public S this[System.Range r] { get => default; } + } + + class C + { + void Goo(S s) { - void Goo(S s) - { - s.Slice([|1, s.Length - 2|]) = default; - } - } - """; - var fixedSource = - """ - using System; - struct S { - public ref S Slice(int start, int length) => throw null; - public int Length { get; } - public S this[int r] { get => default; } + s.Slice(1, s.Length - 2) = default; } + } + """; - class C + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } + [Fact] + public async Task TestReturnByRef() + { + var source = + """ + struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public S this[System.Range r] { get => throw null; } } + class C + { + void Goo(S s) { - void Goo(S s) - { - s[1..^1] = default; - } + var x = s.Slice([|1, s.Length - 2|]); } - """; - - await new VerifyCS.Test + } + """; + var fixedSource = + """ + struct S { public ref S Slice(int start, int length) => throw null; public int Length { get; } public S this[System.Range r] { get => throw null; } } + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43202")] - public async Task TestReadWriteProperty() - { - var source = - """ - using System; - struct S { - public ref S Slice(int start, int length) => throw null; - public int Length { get; } - public S this[System.Range r] { get => default; set { } } - } - - class C + void Goo(S s) { - void Goo(S s) - { - s.Slice([|1, s.Length - 2|]) = default; - } - } - """; - var fixedSource = - """ - using System; - struct S { - public ref S Slice(int start, int length) => throw null; - public int Length { get; } - public S this[System.Range r] { get => default; set { } } + var x = s[1..^1]; } + } + """; + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43202")] + public async Task TestIntWritableType() + { + var source = + """ + using System; + struct S { + public ref S Slice(int start, int length) => throw null; + public int Length { get; } + public S this[int r] { get => default; } + } + + class C + { + void Goo(S s) + { + s.Slice([|1, s.Length - 2|]) = default; + } + } + """; + var fixedSource = + """ + using System; + struct S { + public ref S Slice(int start, int length) => throw null; + public int Length { get; } + public S this[int r] { get => default; } + } + + class C + { + void Goo(S s) { - void Goo(S s) - { - s[1..^1] = default; - } + s[1..^1] = default; } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestWithTypeWithActualSliceMethod3() + await new VerifyCS.Test { - var source = - """ - using System; - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43202")] + public async Task TestReadWriteProperty() + { + var source = + """ + using System; + struct S { + public ref S Slice(int start, int length) => throw null; + public int Length { get; } + public S this[System.Range r] { get => default; set { } } + } + + class C + { + void Goo(S s) + { + s.Slice([|1, s.Length - 2|]) = default; + } + } + """; + var fixedSource = + """ + using System; + struct S { + public ref S Slice(int start, int length) => throw null; + public int Length { get; } + public S this[System.Range r] { get => default; set { } } + } + + class C + { + void Goo(S s) { - void Goo(Span s) - { - var v = s.Slice([|1|]); - } + s[1..^1] = default; } - """; - var fixedSource = - """ - using System; - class C + } + """; + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestWithTypeWithActualSliceMethod3() + { + var source = + """ + using System; + class C + { + void Goo(Span s) { - void Goo(Span s) - { - var v = s[1..]; - } + var v = s.Slice([|1|]); } - """; - await new VerifyCS.Test + } + """; + var fixedSource = + """ + using System; + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36997")] - public async Task TestExpressionWithAddOperatorArgument() - { - var source = - """ - class C + void Goo(Span s) { - void Goo(string s, int bar) - { - var v = s.Substring([|bar + 1|]); - } + var v = s[1..]; } - """; - var fixedSource = - """ - class C + } + """; + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36997")] + public async Task TestExpressionWithAddOperatorArgument() + { + var source = + """ + class C + { + void Goo(string s, int bar) { - void Goo(string s, int bar) - { - var v = s[(bar + 1)..]; - } + var v = s.Substring([|bar + 1|]); } - """; - - await new VerifyCS.Test + } + """; + var fixedSource = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + void Goo(string s, int bar) + { + var v = s[(bar + 1)..]; + } + } + """; - [Fact] - public async Task TestExpressionWithElementAccessShouldNotAddParentheses() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact] + public async Task TestExpressionWithElementAccessShouldNotAddParentheses() + { + var source = + """ + class C + { + void Goo(string s, int[] bar) { - void Goo(string s, int[] bar) - { - _ = s.Substring([|bar[0]|]); - } + _ = s.Substring([|bar[0]|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s, int[] bar) { - void Goo(string s, int[] bar) - { - _ = s[bar[0]..]; - } + _ = s[bar[0]..]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47183")] - public async Task TestExpressionWithNullConditionalAccess() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47183")] + public async Task TestExpressionWithNullConditionalAccess() + { + var source = + """ + #nullable enable + public class Test + { + public string? M(string? arg) + => arg?.Substring([|42|]); + } + """; + var fixedSource = + """ + #nullable enable + public class Test + { + public string? M(string? arg) + => arg?[42..]; + } + """; + await new VerifyCS.Test { - var source = - """ - #nullable enable - public class Test - { - public string? M(string? arg) - => arg?.Substring([|42|]); - } - """; - var fixedSource = - """ - #nullable enable - public class Test - { - public string? M(string? arg) - => arg?[42..]; - } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47183")] - public async Task TestExpressionWithNullConditionalAccessWithPropertyAccess() + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/47183")] + public async Task TestExpressionWithNullConditionalAccessWithPropertyAccess() + { + var source = + """ + public class Test + { + public int? M(string arg) + => arg?.Substring([|42|]).Length; + } + """; + var fixedSource = + """ + public class Test + { + public int? M(string arg) + => arg?[42..].Length; + } + """; + await new VerifyCS.Test { - var source = - """ - public class Test - { - public int? M(string arg) - => arg?.Substring([|42|]).Length; - } - """; - var fixedSource = - """ - public class Test - { - public int? M(string arg) - => arg?[42..].Length; - } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/47183")] - [InlineData( - "c.Prop.Substring([|42|])", - "c.Prop[42..]")] - [InlineData( - "c.Prop.Substring([|1, c.Prop.Length - 2|])", - "c.Prop[1..^1]")] - [InlineData( - "c?.Prop.Substring([|42|])", - "c?.Prop[42..]")] - [InlineData( - "c.Prop?.Substring([|42|])", - "c.Prop?[42..]")] - [InlineData( - "c?.Prop?.Substring([|42|])", - "c?.Prop?[42..]")] - public async Task TestExpressionWithNullConditionalAccessVariations(string subStringCode, string rangeCode) + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/47183")] + [InlineData( + "c.Prop.Substring([|42|])", + "c.Prop[42..]")] + [InlineData( + "c.Prop.Substring([|1, c.Prop.Length - 2|])", + "c.Prop[1..^1]")] + [InlineData( + "c?.Prop.Substring([|42|])", + "c?.Prop[42..]")] + [InlineData( + "c.Prop?.Substring([|42|])", + "c.Prop?[42..]")] + [InlineData( + "c?.Prop?.Substring([|42|])", + "c?.Prop?[42..]")] + public async Task TestExpressionWithNullConditionalAccessVariations(string subStringCode, string rangeCode) + { + var source = + $$""" + public class C + { + public string Prop { get; set; } + } + public class Test + { + public object M(C c) + => {{subStringCode}}; + } + """; + var fixedSource = + $$""" + public class C + { + public string Prop { get; set; } + } + public class Test + { + public object M(C c) + => {{rangeCode}}; + } + """; + await new VerifyCS.Test { - var source = - $$""" - public class C - { - public string Prop { get; set; } - } - public class Test + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38055")] + public async Task TestStringMethod() + { + var source = + """ + namespace System + { + public class Object {} + public class ValueType : Object {} + public struct Void {} + public struct Int32 {} + public struct Index { - public object M(C c) - => {{subStringCode}}; + public int GetOffset(int length) => 0; + public static implicit operator Index(int value) => default; } - """; - var fixedSource = - $$""" - public class C + public struct Range { - public string Prop { get; set; } + public Range(Index start, Index end) {} + public Index Start => default; + public Index End => default; } - public class Test + public class String : Object { - public object M(C c) - => {{rangeCode}}; - } - """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38055")] - public async Task TestStringMethod() - { - var source = - """ - namespace System - { - public class Object {} - public class ValueType : Object {} - public struct Void {} - public struct Int32 {} - public struct Index - { - public int GetOffset(int length) => 0; - public static implicit operator Index(int value) => default; - } - public struct Range - { - public Range(Index start, Index end) {} - public Index Start => default; - public Index End => default; - } - public class String : Object - { - public int Length => 0; - public string Substring(int start, int length) => this; + public int Length => 0; + public string Substring(int start, int length) => this; - string Foo(int x) => Substring([|1, x - 1|]); - } + string Foo(int x) => Substring([|1, x - 1|]); } - """; - var fixedSource = - """ - namespace System + } + """; + var fixedSource = + """ + namespace System + { + public class Object {} + public class ValueType : Object {} + public struct Void {} + public struct Int32 {} + public struct Index { - public class Object {} - public class ValueType : Object {} - public struct Void {} - public struct Int32 {} - public struct Index - { - public int GetOffset(int length) => 0; - public static implicit operator Index(int value) => default; - } - public struct Range - { - public Range(Index start, Index end) {} - public Index Start => default; - public Index End => default; - } - public class String : Object - { - public int Length => 0; - public string Substring(int start, int length) => this; - - string Foo(int x) => this[1..x]; - } + public int GetOffset(int length) => 0; + public static implicit operator Index(int value) => default; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = new ReferenceAssemblies("nostdlib"), - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38055")] - public async Task TestSliceOnThis() - { - var source = - """ - class C + public struct Range { - public int Length => 0; - public C Slice(int start, int length) => this; - - public C Foo(int x) => Slice([|1, x - 1|]); + public Range(Index start, Index end) {} + public Index Start => default; + public Index End => default; } - """; - var fixedSource = - """ - class C + public class String : Object { public int Length => 0; - public C Slice(int start, int length) => this; + public string Substring(int start, int length) => this; - public C Foo(int x) => this[1..x]; + string Foo(int x) => this[1..x]; } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + ReferenceAssemblies = new ReferenceAssemblies("nostdlib"), + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38055")] + public async Task TestSliceOnThis() + { + var source = + """ + class C { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + public int Length => 0; + public C Slice(int start, int length) => this; + + public C Foo(int x) => Slice([|1, x - 1|]); + } + """; + var fixedSource = + """ + class C + { + public int Length => 0; + public C Slice(int start, int length) => this; + + public C Foo(int x) => this[1..x]; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] - public async Task TestStartingFromZero() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] + public async Task TestStartingFromZero() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|0|]); - } + var v = s.Substring([|0|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[..]; - } + var v = s[..]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] - public async Task TestStartingFromAribtraryPosition() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] + public async Task TestStartingFromAribtraryPosition() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|5|]); - } + var v = s.Substring([|5|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[5..]; - } + var v = s[5..]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] - public async Task TestStartingFromZeroToArbitraryEnd() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] + public async Task TestStartingFromZeroToArbitraryEnd() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|0, 5|]); - } + var v = s.Substring([|0, 5|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[..5]; - } + var v = s[..5]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] - public async Task TestStartingFromZeroGoingToLength() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/56269")] + public async Task TestStartingFromZeroGoingToLength() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|0, s.Length|]); - } + var v = s.Substring([|0, s.Length|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[..]; - } + var v = s[..]; } - """; - - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40438")] - public async Task TestStartingFromZeroGoingToLengthMinus1() + await new VerifyCS.Test { - var source = - """ - class C + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40438")] + public async Task TestStartingFromZeroGoingToLengthMinus1() + { + var source = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s.Substring([|0, s.Length - 1|]); - } + var v = s.Substring([|0, s.Length - 1|]); } - """; - var fixedSource = - """ - class C + } + """; + var fixedSource = + """ + class C + { + void Goo(string s) { - void Goo(string s) - { - var v = s[..^1]; - } + var v = s[..^1]; } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = fixedSource, - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49347")] - public async Task TestNotInExpressionTree() + await new VerifyCS.Test { - var source = - """ - using System; - using System.Linq.Expressions; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = fixedSource, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49347")] + public async Task TestNotInExpressionTree() + { + var source = + """ + using System; + using System.Linq.Expressions; - class C + class C + { + void M() { - void M() - { - Expression> e = (s, i) => s.Substring(i); - } + Expression> e = (s, i) => s.Substring(i); } - """; + } + """; - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = source, - FixedCode = source, - }.RunAsync(); - } + await new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = source, + FixedCode = source, + }.RunAsync(); + } - [Fact, WorkItem(60988, "https://github.com/dotnet/roslyn/issues/60988")] - public async Task TestCheckedExpression() + [Fact, WorkItem(60988, "https://github.com/dotnet/roslyn/issues/60988")] + public async Task TestCheckedExpression() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, - TestCode = - """ - using System; - using System.Linq.Expressions; + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31, + TestCode = + """ + using System; + using System.Linq.Expressions; - class C + class C + { + void M() { - void M() - { - Span buffer = new byte[]{ (byte)'h', (byte)'i', 0 }; - long length = 2; - var sliced = buffer.Slice([|0, unchecked((int)length)|]); // or checked((int)length) - } + Span buffer = new byte[]{ (byte)'h', (byte)'i', 0 }; + long length = 2; + var sliced = buffer.Slice([|0, unchecked((int)length)|]); // or checked((int)length) } - """, - FixedCode = - """ - using System; - using System.Linq.Expressions; + } + """, + FixedCode = + """ + using System; + using System.Linq.Expressions; - class C + class C + { + void M() { - void M() - { - Span buffer = new byte[]{ (byte)'h', (byte)'i', 0 }; - long length = 2; - var sliced = buffer[..unchecked((int)length)]; // or checked((int)length) - } + Span buffer = new byte[]{ (byte)'h', (byte)'i', 0 }; + long length = 2; + var sliced = buffer[..unchecked((int)length)]; // or checked((int)length) } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseInferredMemberName/UseInferredMemberNameTests.cs b/src/Analyzers/CSharp/Tests/UseInferredMemberName/UseInferredMemberNameTests.cs index 99e3a2c78acde..28ef613aacf02 100644 --- a/src/Analyzers/CSharp/Tests/UseInferredMemberName/UseInferredMemberNameTests.cs +++ b/src/Analyzers/CSharp/Tests/UseInferredMemberName/UseInferredMemberNameTests.cs @@ -13,192 +13,191 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InferredMemberName +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InferredMemberName; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseInferredMemberName)] +public class UseInferredMemberNameTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseInferredMemberName)] - public class UseInferredMemberNameTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseInferredMemberNameTests(ITestOutputHelper logger) + : base(logger) { - public UseInferredMemberNameTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseInferredMemberNameDiagnosticAnalyzer(), new CSharpUseInferredMemberNameCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseInferredMemberNameDiagnosticAnalyzer(), new CSharpUseInferredMemberNameCodeFixProvider()); - private static readonly CSharpParseOptions s_parseOptions = - CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest); + private static readonly CSharpParseOptions s_parseOptions = + CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest); - [Fact] - public async Task TestInferredTupleName() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestInferredTupleName() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int a = 1; - var t = ([||]a: a, 2); - } + int a = 1; + var t = ([||]a: a, 2); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int a = 1; - var t = (a, 2); - } + int a = 1; + var t = (a, 2); } - """, parseOptions: s_parseOptions); - } + } + """, parseOptions: s_parseOptions); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24480")] - public async Task TestInferredTupleName_WithAmbiguity() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24480")] + public async Task TestInferredTupleName_WithAmbiguity() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int alice = 1; - (int, int, string) t = ([||]alice: alice, alice, null); - } + int alice = 1; + (int, int, string) t = ([||]alice: alice, alice, null); } - """, parameters: new TestParameters(parseOptions: s_parseOptions)); - } + } + """, parameters: new TestParameters(parseOptions: s_parseOptions)); + } - [Fact] - public async Task TestInferredTupleNameAfterCommaWithCSharp6() - { - await TestActionCountAsync( - """ - class C + [Fact] + public async Task TestInferredTupleNameAfterCommaWithCSharp6() + { + await TestActionCountAsync( + """ + class C + { + void M() { - void M() - { - int a = 2; - var t = (1, [||]a: a); - } + int a = 2; + var t = (1, [||]a: a); } - """, count: 0, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, count: 0, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task TestInferredTupleNameAfterCommaWithCSharp7() - { - await TestActionCountAsync( - """ - class C + [Fact] + public async Task TestInferredTupleNameAfterCommaWithCSharp7() + { + await TestActionCountAsync( + """ + class C + { + void M() { - void M() - { - int a = 2; - var t = (1, [||]a: a); - } + int a = 2; + var t = (1, [||]a: a); } - """, count: 0, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7))); - } + } + """, count: 0, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7))); + } - [Fact] - public async Task TestFixAllInferredTupleNameWithTrivia() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestFixAllInferredTupleNameWithTrivia() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int a = 1; - int b = 2; - var t = ( /*before*/ {|FixAllInDocument:a:|} /*middle*/ a /*after*/, /*before*/ b: /*middle*/ b /*after*/); - } + int a = 1; + int b = 2; + var t = ( /*before*/ {|FixAllInDocument:a:|} /*middle*/ a /*after*/, /*before*/ b: /*middle*/ b /*after*/); } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int a = 1; - int b = 2; - var t = ( /*before*/ /*middle*/ a /*after*/, /*before*/ /*middle*/ b /*after*/); - } + int a = 1; + int b = 2; + var t = ( /*before*/ /*middle*/ a /*after*/, /*before*/ /*middle*/ b /*after*/); } - """, parseOptions: s_parseOptions); - } + } + """, parseOptions: s_parseOptions); + } - [Fact] - public async Task TestInferredAnonymousTypeMemberName() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestInferredAnonymousTypeMemberName() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int a = 1; - var t = new { [||]a= a, 2 }; - } + int a = 1; + var t = new { [||]a= a, 2 }; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int a = 1; - var t = new { a, 2 }; - } + int a = 1; + var t = new { a, 2 }; } - """, parseOptions: s_parseOptions); - } + } + """, parseOptions: s_parseOptions); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24480")] - public async Task TestInferredAnonymousTypeMemberName_WithAmbiguity() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24480")] + public async Task TestInferredAnonymousTypeMemberName_WithAmbiguity() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - int alice = 1; - var t = new { [||]alice=alice, alice }; - } + int alice = 1; + var t = new { [||]alice=alice, alice }; } - """, parameters: new TestParameters(parseOptions: s_parseOptions)); - } + } + """, parameters: new TestParameters(parseOptions: s_parseOptions)); + } - [Fact] - public async Task TestFixAllInferredAnonymousTypeMemberNameWithTrivia() - { - await TestAsync( - """ - class C + [Fact] + public async Task TestFixAllInferredAnonymousTypeMemberNameWithTrivia() + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - int a = 1; - int b = 2; - var t = new { /*before*/ {|FixAllInDocument:a =|} /*middle*/ a /*after*/, /*before*/ b = /*middle*/ b /*after*/ }; - } + int a = 1; + int b = 2; + var t = new { /*before*/ {|FixAllInDocument:a =|} /*middle*/ a /*after*/, /*before*/ b = /*middle*/ b /*after*/ }; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int a = 1; - int b = 2; - var t = new { /*before*/ /*middle*/ a /*after*/, /*before*/ /*middle*/ b /*after*/ }; - } + int a = 1; + int b = 2; + var t = new { /*before*/ /*middle*/ a /*after*/, /*before*/ /*middle*/ b /*after*/ }; } - """, parseOptions: s_parseOptions); - } + } + """, parseOptions: s_parseOptions); } } diff --git a/src/Analyzers/CSharp/Tests/UseInterpolatedVerbatimString/UseInterpolatedVerbatimStringCodeFixTests.cs b/src/Analyzers/CSharp/Tests/UseInterpolatedVerbatimString/UseInterpolatedVerbatimStringCodeFixTests.cs index cdaaf5ada678a..d6ea15eb8db38 100644 --- a/src/Analyzers/CSharp/Tests/UseInterpolatedVerbatimString/UseInterpolatedVerbatimStringCodeFixTests.cs +++ b/src/Analyzers/CSharp/Tests/UseInterpolatedVerbatimString/UseInterpolatedVerbatimStringCodeFixTests.cs @@ -12,136 +12,135 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseInterpolatedVerbatimString +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseInterpolatedVerbatimString; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseInterpolatedVerbatimString)] +public class CSharpUseInterpolatedVerbatimStringCodeFixTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseInterpolatedVerbatimString)] - public class CSharpUseInterpolatedVerbatimStringCodeFixTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public CSharpUseInterpolatedVerbatimStringCodeFixTests(ITestOutputHelper logger) + : base(logger) { - public CSharpUseInterpolatedVerbatimStringCodeFixTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpUseInterpolatedVerbatimStringCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpUseInterpolatedVerbatimStringCodeFixProvider()); - [Fact] - public async Task Simple() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task Simple() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - var s = @[||]$"hello"; - } + var s = @[||]$"hello"; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var s = $@"hello"; - } + var s = $@"hello"; } - """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); - } + } + """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); + } - [Fact] - public async Task AfterString() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task AfterString() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - var s = @$"hello"[||]; - } + var s = @$"hello"[||]; } - """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); - } + } + """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); + } - [Fact] - public async Task InCall() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InCall() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(string x) { - void M(string x) - { - var s = M(@[||]$"hello"); - } + var s = M(@[||]$"hello"); } - """, - """ - class C + } + """, + """ + class C + { + void M(string x) { - void M(string x) - { - var s = M($@"hello"); - } + var s = M($@"hello"); } - """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); - } + } + """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); + } - [Fact] - public async Task FixAllInDocument() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task FixAllInDocument() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - var s = {|FixAllInDocument:@$"|}hello"; - var s2 = @$"hello"; - } + var s = {|FixAllInDocument:@$"|}hello"; + var s2 = @$"hello"; } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - var s = $@"hello"; - var s2 = $@"hello"; - } + var s = $@"hello"; + var s2 = $@"hello"; } - """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); - } + } + """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); + } - [Fact] - public async Task MissingOnInterpolatedVerbatimString() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task MissingOnInterpolatedVerbatimString() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var s = $[||]@"hello"; - } + var s = $[||]@"hello"; } - """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); - } + } + """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp7_3))); + } - [Fact] - public async Task MissingInCSharp8() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task MissingInCSharp8() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() - { - var s = @[||]$"hello"; - } + var s = @[||]$"hello"; } - """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp8))); - } + } + """, parameters: new TestParameters().WithParseOptions(new CSharpParseOptions(LanguageVersion.CSharp8))); } } diff --git a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs index 2f826bff7d9d2..b488f0fcc1a67 100644 --- a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs +++ b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForCastAndEqualityOperatorTests.cs @@ -13,514 +13,513 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] +public partial class UseIsNullCheckForCastAndEqualityOperatorTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] - public partial class UseIsNullCheckForCastAndEqualityOperatorTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseIsNullCheckForCastAndEqualityOperatorTests(ITestOutputHelper logger) + : base(logger) { - public UseIsNullCheckForCastAndEqualityOperatorTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer(), new CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider()); - - [Fact] - public async Task TestEquality() - { - await TestInRegularAndScriptAsync( - """ - using System; - - class C + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseIsNullCheckForCastAndEqualityOperatorDiagnosticAnalyzer(), new CSharpUseIsNullCheckForCastAndEqualityOperatorCodeFixProvider()); + + [Fact] + public async Task TestEquality() + { + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s == null) - return; - } + if ([||](object)s == null) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] - public async Task TestIsNullTitle() - { - await TestExactActionSetOfferedAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] + public async Task TestIsNullTitle() + { + await TestExactActionSetOfferedAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s == null) - return; - } + if ([||](object)s == null) + return; } - """, + } + """, [CSharpAnalyzersResources.Use_is_null_check]); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] - public async Task TestIsObjectTitle() - { - await TestExactActionSetOfferedAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] + public async Task TestIsObjectTitle() + { + await TestExactActionSetOfferedAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s != null) - return; - } + if ([||](object)s != null) + return; } - """, + } + """, [CSharpAnalyzersResources.Use_is_object_check], new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] - public async Task TestIsNotNullTitle() - { - await TestExactActionSetOfferedAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] + public async Task TestIsNotNullTitle() + { + await TestExactActionSetOfferedAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s != null) - return; - } + if ([||](object)s != null) + return; } - """, + } + """, [CSharpAnalyzersResources.Use_is_not_null_check], new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9))); - } + } - [Fact] - public async Task TestEqualitySwapped() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestEqualitySwapped() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]null == (object)s) - return; - } + if ([||]null == (object)s) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestNotEquality_CSharp8() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotEquality_CSharp8() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s != null) - return; - } + if ([||](object)s != null) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is object) - return; - } + if (s is object) + return; } - """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); - } + } + """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); + } - [Fact] - public async Task TestNotEquality_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotEquality_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s != null) - return; - } + if ([||](object)s != null) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is not null) - return; - } + if (s is not null) + return; } - """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } - [Fact] - public async Task TestNotEqualitySwapped_CSharp8() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotEqualitySwapped_CSharp8() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]null != (object)s) - return; - } + if ([||]null != (object)s) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is object) - return; - } + if (s is object) + return; } - """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); - } + } + """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); + } - [Fact] - public async Task TestNotEqualitySwapped_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotEqualitySwapped_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]null != (object)s) - return; - } + if ([||]null != (object)s) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is not null) - return; - } + if (s is not null) + return; } - """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } - [Fact] - public async Task TestMissingPreCSharp7() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingPreCSharp7() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](object)s == null) - return; - } + if ([||](object)s == null) + return; } - """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task TestOnlyForObjectCast() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestOnlyForObjectCast() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||](string)s == null) - return; - } + if ([||](string)s == null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ({|FixAllInDocument:|}(object)s == null) - return; - - if (null == (object)s) - return; - } - } - """, - """ - using System; + if ({|FixAllInDocument:|}(object)s == null) + return; - class C + if (null == (object)s) + return; + } + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - - if (s is null) - return; - } + if (s is null) + return; + + if (s is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAllNested1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestFixAllNested1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s2) { - void M(string s2) - { - if ({|FixAllInDocument:|}(object)((object)s2 == null) == null)) - return; - } + if ({|FixAllInDocument:|}(object)((object)s2 == null) == null)) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s2) { - void M(string s2) - { - if ((s2 is null) is null)) - return; - } + if ((s2 is null) is null)) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestTrivia1() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestTrivia1() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ( /*1*/ [||]( /*2*/ object /*3*/ ) /*4*/ s /*5*/ == /*6*/ null /*7*/ ) - return; - } + if ( /*1*/ [||]( /*2*/ object /*3*/ ) /*4*/ s /*5*/ == /*6*/ null /*7*/ ) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if ( /*1*/ s /*5*/ is /*6*/ null /*7*/ ) - return; - } + if ( /*1*/ s /*5*/ is /*6*/ null /*7*/ ) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestTrivia2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestTrivia2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ( /*1*/ [||]null /*2*/ == /*3*/ ( /*4*/ object /*5*/ ) /*6*/ s /*7*/ ) - return; - } + if ( /*1*/ [||]null /*2*/ == /*3*/ ( /*4*/ object /*5*/ ) /*6*/ s /*7*/ ) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s) { - void M(string s) - { - if ( /*1*/ s /*2*/ is /*3*/ null /*7*/ ) - return; - } + if ( /*1*/ s /*2*/ is /*3*/ null /*7*/ ) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestConstrainedTypeParameter() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestConstrainedTypeParameter() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(T s) where T : class { - void M(T s) where T : class - { - if ([||](object)s == null) - return; - } + if ([||](object)s == null) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(T s) where T : class { - void M(T s) where T : class - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestUnconstrainedTypeParameter() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestUnconstrainedTypeParameter() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(T s) { - void M(T s) - { - if ([||](object)s == null) - return; - } + if ([||](object)s == null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestComplexExpr() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestComplexExpr() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string[] s) { - void M(string[] s) - { - if ([||](object)s[0] == null) - return; - } + if ([||](object)s[0] == null) + return; } - """, - """ - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string[] s) { - void M(string[] s) - { - if (s[0] is null) - return; - } + if (s[0] is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnDefault() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestNotOnDefault() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(string[] s) { - void M(string[] s) - { - if ([||](object)s[0] == default) - return; - } + if ([||](object)s[0] == default) + return; } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs index cfb271ccd5c09..93c8af35b30c1 100644 --- a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs +++ b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs @@ -13,653 +13,652 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] +public partial class UseIsNullCheckForReferenceEqualsTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] - public partial class UseIsNullCheckForReferenceEqualsTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseIsNullCheckForReferenceEqualsTests(ITestOutputHelper logger) + : base(logger) { - public UseIsNullCheckForReferenceEqualsTests(ITestOutputHelper logger) - : base(logger) - { - } + } - private static readonly ParseOptions CSharp7 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7); - private static readonly ParseOptions CSharp8 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); - private static readonly ParseOptions CSharp9 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9); + private static readonly ParseOptions CSharp7 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7); + private static readonly ParseOptions CSharp8 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); + private static readonly ParseOptions CSharp9 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9); - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseIsNullCheckForReferenceEqualsDiagnosticAnalyzer(), new CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseIsNullCheckForReferenceEqualsDiagnosticAnalyzer(), new CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider()); - [Fact] - public async Task TestIdentifierName() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIdentifierName() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]ReferenceEquals(s, null)) - return; - } + if ([||]ReferenceEquals(s, null)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] - public async Task TestIsNullTitle() - { - await TestExactActionSetOfferedAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] + public async Task TestIsNullTitle() + { + await TestExactActionSetOfferedAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]ReferenceEquals(s, null)) - return; - } + if ([||]ReferenceEquals(s, null)) + return; } - """, + } + """, [CSharpAnalyzersResources.Use_is_null_check]); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] - public async Task TestIsObjectTitle() - { - await TestExactActionSetOfferedAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] + public async Task TestIsObjectTitle() + { + await TestExactActionSetOfferedAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (![||]ReferenceEquals(s, null)) - return; - } + if (![||]ReferenceEquals(s, null)) + return; } - """, + } + """, [CSharpAnalyzersResources.Use_is_object_check], new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] - public async Task TestIsNotNullTitle() - { - await TestExactActionSetOfferedAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58483")] + public async Task TestIsNotNullTitle() + { + await TestExactActionSetOfferedAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (![||]ReferenceEquals(s, null)) - return; - } + if (![||]ReferenceEquals(s, null)) + return; } - """, + } + """, [CSharpAnalyzersResources.Use_is_not_null_check], new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9))); - } + } - [Fact] - public async Task TestBuiltInType() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestBuiltInType() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (object.[||]ReferenceEquals(s, null)) - return; - } + if (object.[||]ReferenceEquals(s, null)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestNamedType() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestNamedType() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (Object.[||]ReferenceEquals(s, null)) - return; - } + if (Object.[||]ReferenceEquals(s, null)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestReversed() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestReversed() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]ReferenceEquals(null, s)) - return; - } + if ([||]ReferenceEquals(null, s)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s is null) - return; - } + if (s is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestNegated_CSharp7() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestNegated_CSharp7() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (![||]ReferenceEquals(null, s)) - return; - } + if (![||]ReferenceEquals(null, s)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s is object) - return; - } + if (s is object) + return; } - """, new TestParameters(parseOptions: CSharp7)); - } + } + """, new TestParameters(parseOptions: CSharp7)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] - public async Task TestNegated_CSharp9() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] + public async Task TestNegated_CSharp9() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (![||]ReferenceEquals(null, s)) - return; - } + if (![||]ReferenceEquals(null, s)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s is not null) - return; - } + if (s is not null) + return; } - """, new TestParameters(parseOptions: CSharp9)); - } + } + """, new TestParameters(parseOptions: CSharp9)); + } - [Fact] - public async Task TestNotInCSharp6() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestNotInCSharp6() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if ([||]ReferenceEquals(null, s)) - return; - } + if ([||]ReferenceEquals(null, s)) + return; } - """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s1, string s2) { - void M(string s1, string s2) - { - if ({|FixAllInDocument:ReferenceEquals|}(s1, null) || - ReferenceEquals(s2, null)) - return; - } + if ({|FixAllInDocument:ReferenceEquals|}(s1, null) || + ReferenceEquals(s2, null)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s1, string s2) { - void M(string s1, string s2) - { - if (s1 is null || - s2 is null) - return; - } + if (s1 is null || + s2 is null) + return; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s1, string s2) { - void M(string s1, string s2) - { - if (ReferenceEquals(s1, null) || - {|FixAllInDocument:ReferenceEquals|}(s2, null)) - return; - } + if (ReferenceEquals(s1, null) || + {|FixAllInDocument:ReferenceEquals|}(s2, null)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s1, string s2) { - void M(string s1, string s2) - { - if (s1 is null || - s2 is null) - return; - } + if (s1 is null || + s2 is null) + return; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23581")] - public async Task TestValueParameterTypeIsUnconstrainedGeneric_CSharp7() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23581")] + public async Task TestValueParameterTypeIsUnconstrainedGeneric_CSharp7() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if ([||]ReferenceEquals(value, null)) { - if ([||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """, """ - class C + } + """, """ + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if (value == null) { - if (value == null) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp7)); - } + } + """, new TestParameters(parseOptions: CSharp7)); + } - [Fact, WorkItem(23581, "https://github.com/dotnet/roslyn/issues/47972")] - public async Task TestValueParameterTypeIsUnconstrainedGeneric_CSharp8() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem(23581, "https://github.com/dotnet/roslyn/issues/47972")] + public async Task TestValueParameterTypeIsUnconstrainedGeneric_CSharp8() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if ({|FixAllInDocument:ReferenceEquals|}(value, null)) { - if ({|FixAllInDocument:ReferenceEquals|}(value, null)) - { - return; - } + return; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if (value is null) { - if (value is null) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp8)); - } + } + """, new TestParameters(parseOptions: CSharp8)); + } - [Fact] - public async Task TestValueParameterTypeIsUnconstrainedGenericNegated_CSharp7() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestValueParameterTypeIsUnconstrainedGenericNegated_CSharp7() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if (![||]ReferenceEquals(value, null)) { - if (![||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """, """ - class C + } + """, """ + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if (value is object) { - if (value is object) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp7)); - } + } + """, new TestParameters(parseOptions: CSharp7)); + } - [Fact] - public async Task TestValueParameterTypeIsUnconstrainedGenericNegated_CSharp9() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestValueParameterTypeIsUnconstrainedGenericNegated_CSharp9() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if (![||]ReferenceEquals(value, null)) { - if (![||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """, """ - class C + } + """, """ + class C + { + public static void NotNull(T value) { - public static void NotNull(T value) + if (value is not null) { - if (value is not null) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp9)); - } + } + """, new TestParameters(parseOptions: CSharp9)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23581")] - public async Task TestValueParameterTypeIsRefConstraintGeneric() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23581")] + public async Task TestValueParameterTypeIsRefConstraintGeneric() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void NotNull(T value) where T:class { - public static void NotNull(T value) where T:class + if ([||]ReferenceEquals(value, null)) { - if ([||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """, - """ - class C + } + """, + """ + class C + { + public static void NotNull(T value) where T:class { - public static void NotNull(T value) where T:class + if (value is null) { - if (value is null) - { - return; - } + return; } } - """); - } + } + """); + } - [Fact] - public async Task TestValueParameterTypeIsRefConstraintGenericNegated_CSharp7() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestValueParameterTypeIsRefConstraintGenericNegated_CSharp7() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void NotNull(T value) where T:class { - public static void NotNull(T value) where T:class + if (![||]ReferenceEquals(value, null)) { - if (![||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """, - """ - class C + } + """, + """ + class C + { + public static void NotNull(T value) where T:class { - public static void NotNull(T value) where T:class + if (value is object) { - if (value is object) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp7)); - } + } + """, new TestParameters(parseOptions: CSharp7)); + } - [Fact] - public async Task TestValueParameterTypeIsRefConstraintGenericNegated_CSharp9() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestValueParameterTypeIsRefConstraintGenericNegated_CSharp9() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void NotNull(T value) where T:class { - public static void NotNull(T value) where T:class + if (![||]ReferenceEquals(value, null)) { - if (![||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """, - """ - class C + } + """, + """ + class C + { + public static void NotNull(T value) where T:class { - public static void NotNull(T value) where T:class + if (value is not null) { - if (value is not null) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp9)); - } + } + """, new TestParameters(parseOptions: CSharp9)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23581")] - public async Task TestValueParameterTypeIsValueConstraintGeneric() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23581")] + public async Task TestValueParameterTypeIsValueConstraintGeneric() + { + await TestMissingAsync( + """ + class C + { + public static void NotNull(T value) where T:struct { - public static void NotNull(T value) where T:struct + if ([||]ReferenceEquals(value, null)) { - if ([||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """); - } + } + """); + } - [Fact] - public async Task TestValueParameterTypeIsValueConstraintGenericNegated() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestValueParameterTypeIsValueConstraintGenericNegated() + { + await TestMissingAsync( + """ + class C + { + public static void NotNull(T value) where T:struct { - public static void NotNull(T value) where T:struct + if (![||]ReferenceEquals(value, null)) { - if (![||]ReferenceEquals(value, null)) - { - return; - } + return; } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAllNested1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAllNested1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(string s2) { - void M(string s2) - { - if ({|FixAllInDocument:ReferenceEquals|}(ReferenceEquals(s2, null), null)) - return; - } + if ({|FixAllInDocument:ReferenceEquals|}(ReferenceEquals(s2, null), null)) + return; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s2) { - void M(string s2) - { - if (ReferenceEquals(s2, null) is null) - return; - } + if (ReferenceEquals(s2, null) is null) + return; } - """); - } + } + """); + } - [Fact, WorkItem(23581, "https://github.com/dotnet/roslyn/issues/47972")] - public async Task TestValueParameterTypeIsBaseTypeConstraintGeneric() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem(23581, "https://github.com/dotnet/roslyn/issues/47972")] + public async Task TestValueParameterTypeIsBaseTypeConstraintGeneric() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + public static void NotNull(T value) where T:C { - public static void NotNull(T value) where T:C + if ({|FixAllInDocument:ReferenceEquals|}(value, null)) { - if ({|FixAllInDocument:ReferenceEquals|}(value, null)) - { - return; - } + return; } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + public static void NotNull(T value) where T:C { - public static void NotNull(T value) where T:C + if (value is null) { - if (value is null) - { - return; - } + return; } } - """, new TestParameters(parseOptions: CSharp7)); - } + } + """, new TestParameters(parseOptions: CSharp7)); } } diff --git a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseNullCheckOverTypeCheckDiagnosticAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseNullCheckOverTypeCheckDiagnosticAnalyzerTests.cs index e56752818795e..8a1e17617ccf8 100644 --- a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseNullCheckOverTypeCheckDiagnosticAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseNullCheckOverTypeCheckDiagnosticAnalyzerTests.cs @@ -10,220 +10,219 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck -{ - using VerifyCS = CSharpCodeFixVerifier; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck; + +using VerifyCS = CSharpCodeFixVerifier; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] - public class CSharpUseNullCheckOverTypeCheckDiagnosticAnalyzerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseIsNullCheck)] +public class CSharpUseNullCheckOverTypeCheckDiagnosticAnalyzerTests +{ + private static async Task VerifyAsync(string source, string fixedSource, LanguageVersion languageVersion) { - private static async Task VerifyAsync(string source, string fixedSource, LanguageVersion languageVersion) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = source, - FixedCode = fixedSource, - LanguageVersion = languageVersion, - }.RunAsync(); - } + TestCode = source, + FixedCode = fixedSource, + LanguageVersion = languageVersion, + }.RunAsync(); + } - private static async Task VerifyCSharp9Async(string source, string fixedSource) - => await VerifyAsync(source, fixedSource, LanguageVersion.CSharp9); + private static async Task VerifyCSharp9Async(string source, string fixedSource) + => await VerifyAsync(source, fixedSource, LanguageVersion.CSharp9); - private static async Task VerifyCSharp8Async(string source, string fixedSource) - => await VerifyAsync(source, fixedSource, LanguageVersion.CSharp8); + private static async Task VerifyCSharp8Async(string source, string fixedSource) + => await VerifyAsync(source, fixedSource, LanguageVersion.CSharp8); - [Fact] - public async Task TestIsObjectCSharp8() - { - var source = """ - public class C + [Fact] + public async Task TestIsObjectCSharp8() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is object; - } + return value is object; } - """; - await VerifyCSharp8Async(source, source); - } + } + """; + await VerifyCSharp8Async(source, source); + } - [Fact] - public async Task TestIsObject() - { - var source = """ - public class C + [Fact] + public async Task TestIsObject() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return [|value is object|]/*comment*/; - } + return [|value is object|]/*comment*/; } - """; - var fixedSource = """ - public class C + } + """; + var fixedSource = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is not null/*comment*/; - } + return value is not null/*comment*/; } - """; - await VerifyCSharp9Async(source, fixedSource); - } + } + """; + await VerifyCSharp9Async(source, fixedSource); + } - [Fact] - public async Task TestIsObject2() - { - var source = """ - public class C + [Fact] + public async Task TestIsObject2() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is object x; - } + return value is object x; } - """; - await VerifyCSharp9Async(source, source); - } + } + """; + await VerifyCSharp9Async(source, source); + } - [Fact] - public async Task TestIsNotObject() - { - var source = """ - public class C + [Fact] + public async Task TestIsNotObject() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is [|not object|]; - } + return value is [|not object|]; } - """; - var fixedSource = """ - public class C + } + """; + var fixedSource = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is null; - } + return value is null; } - """; - await VerifyCSharp9Async(source, fixedSource); - } + } + """; + await VerifyCSharp9Async(source, fixedSource); + } - [Fact] - public async Task TestIsNotObject2() - { - var source = """ - public class C + [Fact] + public async Task TestIsNotObject2() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is not object o; - } + return value is not object o; } - """; - await VerifyCSharp9Async(source, source); - } + } + """; + await VerifyCSharp9Async(source, source); + } - [Fact] - public async Task TestIsStringAgainstObject_NoDiagnostic() - { - var source = """ - public class C + [Fact] + public async Task TestIsStringAgainstObject_NoDiagnostic() + { + var source = """ + public class C + { + public bool M(object value) { - public bool M(object value) - { - return value is string; - } + return value is string; } - """; - await VerifyCSharp9Async(source, source); - } + } + """; + await VerifyCSharp9Async(source, source); + } - [Fact] - public async Task TestIsStringAgainstString() - { - var source = """ - public class C + [Fact] + public async Task TestIsStringAgainstString() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return [|value is string|]; - } + return [|value is string|]; } - """; - var fixedSource = """ - public class C + } + """; + var fixedSource = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is not null; - } + return value is not null; } - """; - await VerifyCSharp9Async(source, fixedSource); - } + } + """; + await VerifyCSharp9Async(source, fixedSource); + } - [Fact] - public async Task TestIsNotStringAgainstObject_NoDiagnostic() - { - var source = """ - public class C + [Fact] + public async Task TestIsNotStringAgainstObject_NoDiagnostic() + { + var source = """ + public class C + { + public bool M(object value) { - public bool M(object value) - { - return value is string; - } + return value is string; } - """; - await VerifyCSharp9Async(source, source); - } + } + """; + await VerifyCSharp9Async(source, source); + } - [Fact] - public async Task TestIsNotStringAgainstString() - { - var source = """ - public class C + [Fact] + public async Task TestIsNotStringAgainstString() + { + var source = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is [|not string|]; - } + return value is [|not string|]; } - """; - var fixedSource = """ - public class C + } + """; + var fixedSource = """ + public class C + { + public bool M(string value) { - public bool M(string value) - { - return value is null; - } + return value is null; } - """; - await VerifyCSharp9Async(source, fixedSource); - } + } + """; + await VerifyCSharp9Async(source, fixedSource); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58377")] - public async Task TestNotInExpressionTree() - { - var source = """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58377")] + public async Task TestNotInExpressionTree() + { + var source = """ + using System; + using System.Linq.Expressions; + + class SomeClass + { + void M() + { + Bar(s => s is object ? 0 : 1); + } - class SomeClass + private void Bar(Expression> p) { - void M() - { - Bar(s => s is object ? 0 : 1); - } - - private void Bar(Expression> p) - { - } } - """; - await VerifyCSharp9Async(source, source); - } + } + """; + await VerifyCSharp9Async(source, source); } } diff --git a/src/Analyzers/CSharp/Tests/UseLocalFunction/UseLocalFunctionTests.cs b/src/Analyzers/CSharp/Tests/UseLocalFunction/UseLocalFunctionTests.cs index 4be283d7b50e4..d04291e4dd53d 100644 --- a/src/Analyzers/CSharp/Tests/UseLocalFunction/UseLocalFunctionTests.cs +++ b/src/Analyzers/CSharp/Tests/UseLocalFunction/UseLocalFunctionTests.cs @@ -13,3253 +13,3279 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseLocalFunction +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseLocalFunction; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)] +public partial class UseLocalFunctionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)] - public partial class UseLocalFunctionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseLocalFunctionTests(ITestOutputHelper logger) + : base(logger) { - public UseLocalFunctionTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseLocalFunctionDiagnosticAnalyzer(), new CSharpUseLocalFunctionCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseLocalFunctionDiagnosticAnalyzer(), new CSharpUseLocalFunctionCodeFixProvider()); - private static readonly ParseOptions CSharp72ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_2); + private static readonly ParseOptions CSharp72ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_2); - [Fact] - public async Task TestMissingBeforeCSharp7() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingBeforeCSharp7() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, parameters: new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task TestMissingIfWrittenAfter() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingIfWrittenAfter() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; + return fibonacci(v - 1, v - 2); + }; - fibonacci = null; - } + fibonacci = null; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingIfWrittenInside() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingIfWrittenInside() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + fibonacci = null; + if (v <= 1) { - fibonacci = null; - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingForErrorType() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMissingForErrorType() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + // Func can't be bound. + Func [||]fibonacci = v => { - // Func can't be bound. - Func [||]fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingForMultipleVariables() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingForMultipleVariables() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }, fib2 = x => x; - } + return fibonacci(v - 1, v - 2); + }, fib2 = x => x; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingForField() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestMissingForField() + { + await TestMissingAsync( + """ + using System; - class C - { - Func [||]fibonacci = v => + class C + { + Func [||]fibonacci = v => + { + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } - """); - } + return fibonacci(v - 1, v - 2); + }; + } + """); + } - [Fact] - public async Task TestSimpleInitialization_SimpleLambda_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSimpleInitialization_SimpleLambda_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSimpleInitialization_ParenLambdaNoType_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSimpleInitialization_ParenLambdaNoType_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = (v) => { - Func [||]fibonacci = (v) => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSimpleInitialization_ParenLambdaWithType_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSimpleInitialization_ParenLambdaWithType_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = (int v) => { - Func [||]fibonacci = (int v) => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSimpleInitialization_AnonymousMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSimpleInitialization_AnonymousMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = delegate (int v) { - Func [||]fibonacci = delegate (int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } - } - } - """); - } - - [Fact] - public async Task TestSimpleInitialization_SimpleLambda_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C - { - void M() - { - Func [||]fibonacci = v => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } - } - """, - """ - using System; - class C - { - void M() - { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); + return fibonacci(v - 1, v - 2); } } - """); - } - - [Fact] - public async Task TestSimpleInitialization_ParenLambdaNoType_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + } + """); + } - class C - { - void M() - { - Func [||]fibonacci = (v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } - } - """, - """ - using System; + [Fact] + public async Task TestSimpleInitialization_SimpleLambda_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } - } - """); - } - - [Fact] - public async Task TestSimpleInitialization_ParenLambdaWithType_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + Func [||]fibonacci = v => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - class C - { - void M() - { - Func [||]fibonacci = (int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } - } - """, - """ - using System; + [Fact] + public async Task TestSimpleInitialization_ParenLambdaNoType_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + Func [||]fibonacci = (v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - class C - { - void M() - { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } - } - """); - } + [Fact] + public async Task TestSimpleInitialization_ParenLambdaWithType_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + Func [||]fibonacci = (int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - [Fact] - public async Task TestCastInitialization_SimpleLambda_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestCastInitialization_SimpleLambda_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + var [||]fibonacci = (Func)(v => { - var [||]fibonacci = (Func)(v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }); - } + return fibonacci(v - 1, v - 2); + }); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestCastInitialization_SimpleLambda_Block_ExtraParens() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestCastInitialization_SimpleLambda_Block_ExtraParens() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + var [||]fibonacci = ((Func)(v => { - var [||]fibonacci = ((Func)(v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - })); - } + return fibonacci(v - 1, v - 2); + })); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestCastInitialization_ParenLambdaNoType_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestCastInitialization_ParenLambdaNoType_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + var [||]fibonacci = (Func)((v) => { - var [||]fibonacci = (Func)((v) => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }); - } + return fibonacci(v - 1, v - 2); + }); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestCastInitialization_ParenLambdaWithType_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestCastInitialization_ParenLambdaWithType_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + var [||]fibonacci = (Func)((int v) => { - var [||]fibonacci = (Func)((int v) => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }); - } + return fibonacci(v - 1, v - 2); + }); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestCastInitialization_AnonymousMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestCastInitialization_AnonymousMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + var [||]fibonacci = (Func)(delegate (int v) { - var [||]fibonacci = (Func)(delegate (int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }); - } + return fibonacci(v - 1, v - 2); + }); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestCastInitialization_SimpleLambda_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestCastInitialization_SimpleLambda_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + var [||]fibonacci = (Func)(v => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2)); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - class C - { - void M() - { - var [||]fibonacci = (Func)(v => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2)); - } - } - """, - """ - using System; + [Fact] + public async Task TestCastInitialization_ParenLambdaNoType_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + var [||]fibonacci = (Func)((v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2)); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - class C - { - void M() - { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } - } - """); - } + [Fact] + public async Task TestCastInitialization_ParenLambdaWithType_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + var [||]fibonacci = (Func)((int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2)); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - [Fact] - public async Task TestCastInitialization_ParenLambdaNoType_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_WrongName() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fib = null; + fibonacci = v => { - var [||]fibonacci = (Func)((v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2)); - } - } - """, - """ - using System; + if (v <= 1) + { + return 1; + } - class C - { - void M() - { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } + return fibonacci(v - 1, v - 2); + }; } - """); - } + } + """); + } - [Fact] - public async Task TestCastInitialization_ParenLambdaWithType_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_InitializedToOtherValue() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = GetCallback(); + fibonacci = v => { - var [||]fibonacci = (Func)((int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2)); - } - } - """, - """ - using System; + if (v <= 1) + { + return 1; + } - class C - { - void M() - { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } + return fibonacci(v - 1, v - 2); + }; } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_WrongName() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task TestSplitInitialization_SimpleLambda_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = null; + fibonacci = v => { - Func [||]fib = null; - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """); - } - - [Fact] - public async Task TestSplitInitialization_InitializedToOtherValue() - { - await TestMissingAsync( - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - Func [||]fibonacci = GetCallback(); - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_SimpleLambda_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_SimpleLambda_Block_NoInitializer() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci; + fibonacci = v => { - Func [||]fibonacci = null; - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_SimpleLambda_Block_NoInitializer() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_SimpleLambda_Block_DefaultLiteral() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = default; + fibonacci = v => { - Func [||]fibonacci; - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """, + // 7.1 is required for default literals, so 7.2 should be sufficient + // and is used in other tests + new TestParameters(parseOptions: CSharp72ParseOptions)); + } - [Fact] - public async Task TestSplitInitialization_SimpleLambda_Block_DefaultLiteral() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_SimpleLambda_Block_DefaultExpression() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = default(Func); + fibonacci = v => { - Func [||]fibonacci = default; - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """, - // 7.1 is required for default literals, so 7.2 should be sufficient - // and is used in other tests - new TestParameters(parseOptions: CSharp72ParseOptions)); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_SimpleLambda_Block_DefaultExpression() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_SimpleLambda_Block_DefaultExpression_var() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + var [||]fibonacci = default(Func); + fibonacci = v => { - Func [||]fibonacci = default(Func); - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_SimpleLambda_Block_DefaultExpression_var() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_ParenLambdaNoType_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = null; + fibonacci = (v) => { - var [||]fibonacci = default(Func); - fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_ParenLambdaNoType_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_ParenLambdaWithType_Block() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = null; + fibonacci = (int v) => { - Func [||]fibonacci = null; - fibonacci = (v) => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_ParenLambdaWithType_Block() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_AnonymousMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = null; + fibonacci = delegate (int v) { - Func [||]fibonacci = null; - fibonacci = (int v) => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } + + [Fact] + public async Task TestSplitInitialization_SimpleLambda_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + Func [||]fibonacci = null; + fibonacci = v => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } + + [Fact] + public async Task TestSplitInitialization_ParenLambdaNoType_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + Func [||]fibonacci = null; + fibonacci = (v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } - [Fact] - public async Task TestSplitInitialization_AnonymousMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestSplitInitialization_ParenLambdaWithType_ExprBody() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M() + { + Func [||]fibonacci = null; + fibonacci = (int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """, + """ + using System; + + class C + { + void M() + { + static int fibonacci(int v) => + v <= 1 + ? 1 + : fibonacci(v - 1, v - 2); + } + } + """); + } + + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func {|FixAllInDocument:fibonacci|} = v => { - Func [||]fibonacci = null; - fibonacci = delegate (int v) - { - if (v <= 1) - { - return 1; - } + Func isTrue = b => b; - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) - { - if (v <= 1) - { - return 1; - } + bool isTrue(bool b) => b; - return fibonacci(v - 1, v - 2); - } + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_SimpleLambda_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func fibonacci = v => { - Func [||]fibonacci = null; - fibonacci = v => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } + Func {|FixAllInDocument:isTrue|} = b => b; + + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); + bool isTrue(bool b) => b; + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_ParenLambdaNoType_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll3() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func fibonacci = null; + fibonacci = v => { - Func [||]fibonacci = null; - fibonacci = (v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } + Func {|FixAllInDocument:isTrue|} = null; + isTrue = b => b; + + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); + bool isTrue(bool b) => b; + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestSplitInitialization_ParenLambdaWithType_ExprBody() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll4() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func {|FixAllInDocument:fibonacci|} = null; + fibonacci = v => { - Func [||]fibonacci = null; - fibonacci = (int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); - } + Func fibonacciHelper = null; + fibonacciHelper = n => fibonacci.Invoke(n - 1) + fibonacci(arg: n - 2); + + return fibonacciHelper(v); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) => - v <= 1 - ? 1 - : fibonacci(v - 1, v - 2); + int fibonacciHelper(int n) => fibonacci(n - 1) + fibonacci(v: n - 2); + return fibonacciHelper(v); } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestTrivia() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + // Leading trivia + Func [||]fibonacci = v => { - Func {|FixAllInDocument:fibonacci|} = v => + if (v <= 1) { - Func isTrue = b => b; + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; // Trailing trivia } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + // Leading trivia + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - bool isTrue(bool b) => b; - - return fibonacci(v - 1, v - 2); + return 1; } - } + + return fibonacci(v - 1, v - 2); + } // Trailing trivia } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestInWithParameters() + { + await TestInRegularAndScript1Async( + """ + delegate void D(in int p); + class C + { + void M() + { + D [||]lambda = (in int p) => throw null; + } + } + """, + """ + delegate void D(in int p); + class C + { + void M() + { + void lambda(in int p) => throw null; + } + } + """, + // Run with 7.2 to get read-only references + new TestParameters(parseOptions: CSharp72ParseOptions)); + } - class C - { - void M() - { - Func fibonacci = v => - { - Func {|FixAllInDocument:isTrue|} = b => b; + [Fact] + public async Task TestRefReadOnlyWithReturnType() + { + await TestInRegularAndScript1Async( + """ + delegate ref readonly int D(); + class C + { + void M() + { + D [||]lambda = () => throw null; + } + } + """, + """ + delegate ref readonly int D(); + class C + { + void M() + { + static ref readonly int lambda() => throw null; + } + } + """); + } - return fibonacci(v - 1, v - 2); - }; - } - } - """, - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestMissingIfConvertedToNonDelegate() + { + await TestMissingAsync( + """ + using System; + using System.Threading.Tasks; - class C + class Program + { + static void Main(string[] args) { - void M() - { - static int fibonacci(int v) - { - bool isTrue(bool b) => b; - - return fibonacci(v - 1, v - 2); - } - } + Func [||]f = x => { return Task.CompletedTask; }; + Func actual = null; + AssertSame(f, actual); } - """); - } - [Fact] - public async Task TestFixAll3() - { - await TestInRegularAndScript1Async( - """ - using System; - - class C - { - void M() - { - Func fibonacci = null; - fibonacci = v => - { - Func {|FixAllInDocument:isTrue|} = null; - isTrue = b => b; + public static void AssertSame(object expected, object actual) { } + } + """); + } - return fibonacci(v - 1, v - 2); - }; - } - } - """, - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestAvailableIfConvertedToDelegate() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Threading.Tasks; - class C + class Program + { + static void Main(string[] args) { - void M() - { - static int fibonacci(int v) - { - bool isTrue(bool b) => b; - return fibonacci(v - 1, v - 2); - } - } + Func [||]f = x => { return Task.CompletedTask; }; + Func actual = null; + AssertSame(f, actual); } - """); - } - [Fact] - public async Task TestFixAll4() - { - await TestInRegularAndScript1Async( - """ - using System; + public static void AssertSame(Func expected, object actual) { } + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class Program + { + static void Main(string[] args) { - void M() - { - Func {|FixAllInDocument:fibonacci|} = null; - fibonacci = v => - { - Func fibonacciHelper = null; - fibonacciHelper = n => fibonacci.Invoke(n - 1) + fibonacci(arg: n - 2); - - return fibonacciHelper(v); - }; - } + static Task f(string x) { return Task.CompletedTask; } + Func actual = null; + AssertSame(f, actual); } - """, - """ - using System; - class C - { - void M() - { - static int fibonacci(int v) - { - int fibonacciHelper(int n) => fibonacci(n - 1) + fibonacci(v: n - 2); - return fibonacciHelper(v); - } - } - } - """); - } + public static void AssertSame(Func expected, object actual) { } + } + """); + } - [Fact] - public async Task TestTrivia() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestNotAvailableIfConvertedToSystemDelegate() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class Program + { + static void Main(string[] args) { - void M() - { - // Leading trivia - Func [||]fibonacci = v => - { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); - }; // Trailing trivia - } + Func [||]f = x => ""; + M(f); } - """, - """ - using System; - class C - { - void M() - { - // Leading trivia - static int fibonacci(int v) - { - if (v <= 1) - { - return 1; - } + public static void M(Delegate expected) { } + } + """); + } - return fibonacci(v - 1, v - 2); - } // Trailing trivia - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestNotAvailableIfConvertedToSystemMulticastDelegate() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - [Fact] - public async Task TestInWithParameters() - { - await TestInRegularAndScript1Async( - """ - delegate void D(in int p); - class C - { - void M() - { - D [||]lambda = (in int p) => throw null; - } - } - """, - """ - delegate void D(in int p); - class C + class Program + { + static void Main(string[] args) { - void M() - { - void lambda(in int p) => throw null; - } + Func [||]f = x => ""; + M(f); } - """, - // Run with 7.2 to get read-only references - new TestParameters(parseOptions: CSharp72ParseOptions)); - } - [Fact] - public async Task TestRefReadOnlyWithReturnType() - { - await TestInRegularAndScript1Async( - """ - delegate ref readonly int D(); - class C - { - void M() - { - D [||]lambda = () => throw null; - } - } - """, - """ - delegate ref readonly int D(); - class C - { - void M() - { - static ref readonly int lambda() => throw null; - } - } - """); - } + public static void M(MulticastDelegate expected) { } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestMissingIfConvertedToNonDelegate() - { - await TestMissingAsync( - """ - using System; - using System.Threading.Tasks; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestAvailableIfConvertedToCoContraVariantDelegate0() + { + await TestInRegularAndScript1Async( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = x => { return Task.CompletedTask; }; - Func actual = null; - AssertSame(f, actual); - } - - public static void AssertSame(object expected, object actual) { } + Func [||]f = x => ""; + M(f); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestAvailableIfConvertedToDelegate() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Threading.Tasks; + public static void M(Func expected) { } + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = x => { return Task.CompletedTask; }; - Func actual = null; - AssertSame(f, actual); - } - - public static void AssertSame(Func expected, object actual) { } + static string f(object x) => ""; + M(f); } - """, - """ - using System; - using System.Threading.Tasks; - - class Program - { - static void Main(string[] args) - { - static Task f(string x) { return Task.CompletedTask; } - Func actual = null; - AssertSame(f, actual); - } - public static void AssertSame(Func expected, object actual) { } - } - """); - } + public static void M(Func expected) { } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestNotAvailableIfConvertedToSystemDelegate() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56938")] + [WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestAvailableIfConvertedToCoContraVariantDelegate1() + { + await TestInRegularAndScript1Async( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = x => ""; - M(f); - } - - public static void M(Delegate expected) { } + Func [||]f = x => ""; + M(f); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestNotAvailableIfConvertedToSystemMulticastDelegate() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + public static void M(Func expected) { } + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = x => ""; - M(f); - } - - public static void M(MulticastDelegate expected) { } + static string f(object x) => ""; + M(f); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestAvailableIfConvertedToCoContraVariantDelegate0() - { - await TestInRegularAndScript1Async( - """ - using System; - - class Program - { - static void Main(string[] args) - { - Func [||]f = x => ""; - M(f); - } + public static void M(Func expected) { } + } + """); + } - public static void M(Func expected) { } - } - """, - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56938")] + [WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestAvailableIfConvertedToCoContraVariantDelegate2() + { + await TestInRegularAndScript1Async( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - static string f(object x) => ""; - M(f); - } - - public static void M(Func expected) { } + Func [||]f = x => ""; + M(f); } - """); - } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56938")] - [WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestAvailableIfConvertedToCoContraVariantDelegate1() - { - await TestInRegularAndScript1Async( - """ - using System; + public static void M(Func expected) { } + } + """, + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = x => ""; - M(f); - } - - public static void M(Func expected) { } + static string f(string x) => ""; + M(f); } - """, - """ - using System; - - class Program - { - static void Main(string[] args) - { - static string f(object x) => ""; - M(f); - } - public static void M(Func expected) { } - } - """); - } + public static void M(Func expected) { } + } + """); + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56938")] - [WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestAvailableIfConvertedToCoContraVariantDelegate2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56938")] + [WorkItem("https://github.com/dotnet/roslyn/issues/23118")] + public async Task TestAvailableIfConvertedToCoContraVariantDelegate3() + { + await TestInRegularAndScript1Async( + """ + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = x => ""; - M(f); - } - - public static void M(Func expected) { } + Func [||]f = x => ""; + M(f); } - """, - """ - using System; - class Program - { - static void Main(string[] args) - { - static string f(string x) => ""; - M(f); - } + public static void M(Func expected) { } + } + """, + """ + using System; - public static void M(Func expected) { } + class Program + { + static void Main(string[] args) + { + static object f(object x) => ""; + M(f); } - """); - } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56938")] - [WorkItem("https://github.com/dotnet/roslyn/issues/23118")] - public async Task TestAvailableIfConvertedToCoContraVariantDelegate3() - { - await TestInRegularAndScript1Async( - """ - using System; + public static void M(Func expected) { } + } + """); + } - class Program - { - static void Main(string[] args) - { - Func [||]f = x => ""; - M(f); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22672")] + public async Task TestMissingIfAdded() + { + await TestMissingAsync( + """ + using System; + using System.Linq.Expressions; - public static void M(Func expected) { } - } - """, - """ - using System; + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - class Program + public class Class + { + public void Caller() { - static void Main(string[] args) - { - static object f(object x) => ""; - M(f); - } + MyDelegate [||]local = x => x; - public static void M(Func expected) { } + var doubleDelegate = local + local; } - """); - } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22672")] - public async Task TestMissingIfAdded() - { - await TestMissingAsync( - """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22672")] + public async Task TestMissingIfUsedInMemberAccess1() + { + await TestMissingAsync( + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class - { + public class Class + { public void Caller() { - MyDelegate [||]local = x => x; + MyDelegate [||]local = x => x; - var doubleDelegate = local + local; + var str = local.ToString(); } - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22672")] - public async Task TestMissingIfUsedInMemberAccess1() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] + public async Task TestMissingIfUsedInMemberAccess2() + { + await TestMissingAsync( + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller() - { - MyDelegate [||]local = x => x; + MyDelegate[||]local = x => x; - var str = local.ToString(); - } + Console.Write(local.Invoke(t)); + + var str = local.ToString(); + local.Invoke(t); } } - """); - } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22672")] + public async Task TestMissingIfUsedInExpressionTree() + { + await TestMissingAsync( + """ + using System; + using System.Linq.Expressions; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] - public async Task TestMissingIfUsedInMemberAccess2() - { - await TestMissingAsync( - """ - using System; + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - class Enclosing where T : class + public class Class + { + public void Caller() { - delegate T MyDelegate(T t = null); + MyDelegate [||]local = x => x; - public class Class - { - public void Caller(T t) - { - MyDelegate[||]local = x => x; + Expression expression = () => local(null); + } + } + } + """); + } - Console.Write(local.Invoke(t)); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24344")] + public async Task TestMissingIfUsedInExpressionTree2() + { + await TestMissingAsync( + """ + using System; + using System.Linq.Expressions; - var str = local.ToString(); - local.Invoke(t); - } - } + public class C + { + void Method(Action action) { } + + Expression Example() + { + Action [||]action = () => Method(null); + return () => Method(action); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22672")] - public async Task TestMissingIfUsedInExpressionTree() - { - await TestMissingAsync( - """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] + public async Task TestWithInvokeMethod1() + { + await TestInRegularAndScript1Async( + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class - { + public class Class + { public void Caller() { - MyDelegate [||]local = x => x; + MyDelegate [||]local = x => x; - Expression expression = () => local(null); + local.Invoke(); } - } } - """); - } + } + """, + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24344")] - public async Task TestMissingIfUsedInExpressionTree2() - { - await TestMissingAsync( - """ - using System; - using System.Linq.Expressions; + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class C + public class Class { - void Method(Action action) { } - - Expression Example() + public void Caller() { - Action [||]action = () => Method(null); - return () => Method(action); + static T local(T x = null) => x; + + local(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] - public async Task TestWithInvokeMethod1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] + public async Task TestWithInvokeMethod2() + { + await TestInRegularAndScript1Async( + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller() - { - MyDelegate [||]local = x => x; + MyDelegate [||]local = x => x; - local.Invoke(); - } + Console.Write(local.Invoke(t)); } } - """, - """ - using System; + } + """, + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller() - { - static T local(T x = null) => x; + static T local(T x = null) => x; - local(); - } + Console.Write(local(t)); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] - public async Task TestWithInvokeMethod2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] + public async Task TestWithInvokeMethod3() + { + await TestInRegularAndScript1Async( + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller(T t) - { - MyDelegate [||]local = x => x; + MyDelegate [||]local = x => x; - Console.Write(local.Invoke(t)); - } + Console.Write(local.Invoke(t)); + + var val = local.Invoke(t); + local.Invoke(t); } } - """, - """ - using System; + } + """, + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller(T t) - { - static T local(T x = null) => x; + static T local(T x = null) => x; - Console.Write(local(t)); - } + Console.Write(local(t)); + + var val = local(t); + local(t); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] - public async Task TestWithInvokeMethod3() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] + public async Task TestWithInvokeMethod4() + { + await TestInRegularAndScript1Async( + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller(T t) - { - MyDelegate [||]local = x => x; + MyDelegate [||]local = x => x; - Console.Write(local.Invoke(t)); + Console.Write(local.Invoke(t)); - var val = local.Invoke(t); - local.Invoke(t); - } + var val = local.Invoke(t); + local(t); } } - """, - """ - using System; + } + """, + """ + using System; - class Enclosing where T : class - { - delegate T MyDelegate(T t = null); + class Enclosing where T : class + { + delegate T MyDelegate(T t = null); - public class Class + public class Class + { + public void Caller(T t) { - public void Caller(T t) - { - static T local(T x = null) => x; + static T local(T x = null) => x; - Console.Write(local(t)); + Console.Write(local(t)); - var val = local(t); - local(t); - } + var val = local(t); + local(t); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23150")] - public async Task TestWithInvokeMethod4() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364807853")] + public async Task TestWithRecursiveInvokeMethod1() + { + await TestInRegularAndScript1Async( + """ + using System; - class Enclosing where T : class + class C + { + void M() { - delegate T MyDelegate(T t = null); + Action [||]local = null; + local = () => local.Invoke(); + } + } + """, + """ + using System; - public class Class - { - public void Caller(T t) - { - MyDelegate [||]local = x => x; + class C + { + void M() + { + static void local() => local(); + } + } + """); + } - Console.Write(local.Invoke(t)); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364807853")] + public async Task TestWithRecursiveInvokeMethod2() + { + await TestInRegularAndScript1Async( + """ + using System; - var val = local.Invoke(t); - local(t); - } - } + class C + { + void M() + { + Action [||]local = null; + local = () => { local.Invoke(); } } - """, - """ - using System; + } + """, + """ + using System; - class Enclosing where T : class + class C + { + void M() { - delegate T MyDelegate(T t = null); + static void local() { local(); } + } + } + """); + } - public class Class - { - public void Caller(T t) - { - static T local(T x = null) => x; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364935495")] + public async Task TestWithNestedInvokeMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - Console.Write(local(t)); + class C + { + void M() + { + Func [||]a = s => s; + a.Invoke(a.Invoke(null)); + } + } + """, + """ + using System; - var val = local(t); - local(t); - } - } + class C + { + void M() + { + static string a(string s) => s; + a(a(null)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364807853")] - public async Task TestWithRecursiveInvokeMethod1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithNestedRecursiveInvokeMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Action [||]local = null; - local = () => local.Invoke(); - } + Func [||]a = null; + a = s => a.Invoke(a.Invoke(s)); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static void local() => local(); - } + static string a(string s) => a(a(s)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364807853")] - public async Task TestWithRecursiveInvokeMethod2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithDefaultParameter1() + { + await TestInRegularAndScript1Async( + """ + class C + { + delegate string MyDelegate(string arg = "hello"); - class C + void M() { - void M() - { - Action [||]local = null; - local = () => { local.Invoke(); } - } + MyDelegate [||]local = (s) => s; } - """, - """ - using System; + } + """, + """ + class C + { + delegate string MyDelegate(string arg = "hello"); - class C + void M() { - void M() - { - static void local() { local(); } - } + static string local(string s = "hello") => s; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364935495")] - public async Task TestWithNestedInvokeMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364655480")] + public async Task TestWithDefaultParameter2() + { + await TestInRegularAndScript1Async( + """ + class C + { + delegate string MyDelegate(string arg = "hello"); - class C + void M() { - void M() - { - Func [||]a = s => s; - a.Invoke(a.Invoke(null)); - } + MyDelegate [||]local = (string s) => s; } - """, - """ - using System; + } + """, + """ + class C + { + delegate string MyDelegate(string arg = "hello"); - class C + void M() { - void M() - { - static string a(string s) => s; - a(a(null)); - } + static string local(string s = "hello") => s; } - """); - } + } + """); + } - [Fact] - public async Task TestWithNestedRecursiveInvokeMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithDefaultParameter3() + { + await TestInRegularAndScript1Async( + """ + class C + { + delegate string MyDelegate(string arg = "hello"); - class C + void M() { - void M() - { - Func [||]a = null; - a = s => a.Invoke(a.Invoke(s)); - } + MyDelegate [||]local = delegate (string s) { return s; }; } - """, - """ - using System; + } + """, + """ + class C + { + delegate string MyDelegate(string arg = "hello"); - class C + void M() { - void M() - { - static string a(string s) => a(a(s)); - } + static string local(string s = "hello") { return s; } } - """); - } + } + """); + } - [Fact] - public async Task TestWithDefaultParameter1() - { - await TestInRegularAndScript1Async( - """ - class C - { - delegate string MyDelegate(string arg = "hello"); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364764542")] + public async Task TestWithUnmatchingParameterList1() + { + await TestInRegularAndScript1Async( + """ + using System; - void M() - { - MyDelegate [||]local = (s) => s; - } - } - """, - """ - class C + class C + { + void M() { - delegate string MyDelegate(string arg = "hello"); - - void M() - { - static string local(string s = "hello") => s; - } + Action [||]x = (a, b) => { }; } - """); - } + } + """, + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364655480")] - public async Task TestWithDefaultParameter2() - { - await TestInRegularAndScript1Async( - """ - class C + class C + { + void M() { - delegate string MyDelegate(string arg = "hello"); - - void M() - { - MyDelegate [||]local = (string s) => s; - } + static void x(object a, object b) { } } - """, - """ - class C - { - delegate string MyDelegate(string arg = "hello"); + } + """); + } - void M() - { - static string local(string s = "hello") => s; - } - } - """); - } + [Fact] + public async Task TestWithUnmatchingParameterList2() + { + await TestInRegularAndScript1Async( + """ + using System; - [Fact] - public async Task TestWithDefaultParameter3() - { - await TestInRegularAndScript1Async( - """ - class C + class C + { + void M() { - delegate string MyDelegate(string arg = "hello"); - - void M() - { - MyDelegate [||]local = delegate (string s) { return s; }; - } + Action [||]x = (string a, int b) => { }; } - """, - """ - class C - { - delegate string MyDelegate(string arg = "hello"); + } + """, + """ + using System; - void M() - { - static string local(string s = "hello") { return s; } - } + class C + { + void M() + { + static void x(string a, int b) { } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24760#issuecomment-364764542")] - public async Task TestWithUnmatchingParameterList1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithAsyncLambdaExpression() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - Action [||]x = (a, b) => { }; - } + Func [||]f = async () => await Task.Yield(); } - """, - """ - using System; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - static void x(object a, object b) { } - } + static async Task f() => await Task.Yield(); } - """); - } + } + """); + } - [Fact] - public async Task TestWithUnmatchingParameterList2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithAsyncAnonymousMethod() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - Action [||]x = (string a, int b) => { }; - } + Func> [||]f = async delegate () { return 0; }; } - """, - """ - using System; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - static void x(string a, int b) { } - } + static async Task f() { return 0; } } - """); - } + } + """); + } - [Fact] - public async Task TestWithAsyncLambdaExpression() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task TestWithParameterlessAnonymousMethod() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = async () => await Task.Yield(); - } + EventHandler [||]handler = delegate { }; + + E += handler; } - """, - """ - using System; - using System.Threading.Tasks; - class C + event EventHandler E; + } + """, + """ + using System; + + class C + { + void M() { - void M() - { - static async Task f() => await Task.Yield(); - } + static void handler(object sender, EventArgs e) { } + + E += handler; } - """); - } - [Fact] - public async Task TestWithAsyncAnonymousMethod() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Threading.Tasks; + event EventHandler E; + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24764")] + public async Task TestWithNamedArguments1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func> [||]f = async delegate () { return 0; }; - } + Action [||]x = (a1, a2, a3) => { }; + + x(arg1: null, 0, 0); + x.Invoke(arg1: null, 0, 0); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static async Task f() { return 0; } - } + static void x(string a1, int a2, int a3) { } + + x(a1: null, 0, 0); + x(a1: null, 0, 0); } - """); - } + } + """); + } - [Fact] - public async Task TestWithParameterlessAnonymousMethod() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24764")] + public async Task TestWithNamedArguments2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Action [||]x = (a1, a2, a3) => { - EventHandler [||]handler = delegate { }; - - E += handler; - } - - event EventHandler E; + x(null, arg3: 0, arg2: 0); + x.Invoke(null, arg3: 0, arg2: 0); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static void x(string a1, int a2, int a3) { - static void handler(object sender, EventArgs e) { } - - E += handler; + x(null, a3: 0, a2: 0); + x(null, a3: 0, a2: 0); } - - event EventHandler E; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24764")] - public async Task TestWithNamedArguments1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithNamedArgumentsAndBrokenCode1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Action [||]x = (a1, a2, a3) => { }; + Action [||]x = (int a1, string a2, string a3, a4) => { }; - x(arg1: null, 0, 0); - x.Invoke(arg1: null, 0, 0); - } + x(null, arg3: 0, arg2: 0, arg4: 0); + x.Invoke(null, arg3: 0, arg2: 0, arg4: 0); + x.Invoke(0, null, null, null, null, null); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static void x(string a1, int a2, int a3) { } + static void x(int a1, string a2, string a3, object a4) { } - x(a1: null, 0, 0); - x(a1: null, 0, 0); - } + x(null, a3: 0, a2: 0, arg4: 0); + x(null, a3: 0, a2: 0, arg4: 0); + x(0, null, null, null, null, null); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24764")] - public async Task TestWithNamedArguments2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithNamedArgumentsAndBrokenCode2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Action [||]x = (a1, a2) => { - Action [||]x = (a1, a2, a3) => - { - x(null, arg3: 0, arg2: 0); - x.Invoke(null, arg3: 0, arg2: 0); - }; - } + x(null, arg3: 0, arg2: 0); + x.Invoke(null, arg3: 0, arg2: 0); + x.Invoke(); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static void x(string a1, int a2) { - static void x(string a1, int a2, int a3) - { - x(null, a3: 0, a2: 0); - x(null, a3: 0, a2: 0); - } + x(null, arg3: 0, a2: 0); + x(null, arg3: 0, a2: 0); + x(); } } - """); - } + } + """); + } - [Fact] - public async Task TestWithNamedArgumentsAndBrokenCode1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithNamedAndDefaultArguments() + { + await TestInRegularAndScript1Async( + """ + class C + { + delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); - class C + void M() { - void M() + MyDelegate [||]x = null; + x = (a1, a2, a3) => { - Action [||]x = (int a1, string a2, string a3, a4) => { }; - - x(null, arg3: 0, arg2: 0, arg4: 0); - x.Invoke(null, arg3: 0, arg2: 0, arg4: 0); - x.Invoke(0, null, null, null, null, null); - } + x(null, arg3: 42); + return x.Invoke(null, arg3: 42); + }; } - """, - """ - using System; + } + """, + """ + class C + { + delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); - class C + void M() { - void M() + static string x(string a1, int a2 = 2, int a3 = 3) { - static void x(int a1, string a2, string a3, object a4) { } - - x(null, a3: 0, a2: 0, arg4: 0); - x(null, a3: 0, a2: 0, arg4: 0); - x(0, null, null, null, null, null); + x(null, a3: 42); + return x(null, a3: 42); } } - """); - } + } + """); + } - [Fact] - public async Task TestWithNamedArgumentsAndBrokenCode2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestWithNamedAndDefaultArgumentsAndNestedRecursiveInvocations_FixAll() + { + await TestInRegularAndScript1Async( + """ + class C + { + delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); - class C + void M() { - void M() + var x = (MyDelegate)delegate { - Action [||]x = (a1, a2) => + MyDelegate {|FixAllInDocument:a|} = null; + a = (string a1, int a2, int a3) => { - x(null, arg3: 0, arg2: 0); - x.Invoke(null, arg3: 0, arg2: 0); - x.Invoke(); + MyDelegate b = null; + b = (b1, b2, b3) => + b.Invoke(arg1: b(null), arg2: a(arg1: a.Invoke(null)).Length, arg3: 42) + + b(arg1: b.Invoke(null), arg3: a(arg1: a.Invoke(null)).Length, arg2: 42); + + return b(arg1: a1, b(arg1: a1).Length); }; - } + + return a(arg1: null); + }; + + x(arg1: null); } - """, - """ - using System; + } + """, + """ + class C + { + delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); - class C + void M() { - void M() + string x(string arg1, int arg2 = 2, int arg3 = 3) { - static void x(string a1, int a2) + string a(string a1, int a2 = 2, int a3 = 3) { - x(null, arg3: 0, a2: 0); - x(null, arg3: 0, a2: 0); - x(); + string b(string b1, int b2 = 2, int b3 = 3) => + b(b1: b(null), b2: a(a1: a(null)).Length, b3: 42) + + b(b1: b(null), b3: a(a1: a(null)).Length, b2: 42); + return b(b1: a1, b(b1: a1).Length); } - } - } - """); - } - - [Fact] - public async Task TestWithNamedAndDefaultArguments() - { - await TestInRegularAndScript1Async( - """ - class C - { - delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); - void M() - { - MyDelegate [||]x = null; - x = (a1, a2, a3) => - { - x(null, arg3: 42); - return x.Invoke(null, arg3: 42); - }; + return a(a1: null); } - } - """, - """ - class C - { - delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); - void M() - { - static string x(string a1, int a2 = 2, int a3 = 3) - { - x(null, a3: 42); - return x(null, a3: 42); - } - } + x(arg1: null); } - """); - } - - [Fact] - public async Task TestWithNamedAndDefaultArgumentsAndNestedRecursiveInvocations_FixAll() - { - await TestInRegularAndScript1Async( - """ - class C - { - delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); + } + """); + } - void M() - { - var x = (MyDelegate)delegate - { - MyDelegate {|FixAllInDocument:a|} = null; - a = (string a1, int a2, int a3) => - { - MyDelegate b = null; - b = (b1, b2, b3) => - b.Invoke(arg1: b(null), arg2: a(arg1: a.Invoke(null)).Length, arg3: 42) + - b(arg1: b.Invoke(null), arg3: a(arg1: a.Invoke(null)).Length, arg2: 42); - - return b(arg1: a1, b(arg1: a1).Length); - }; - - return a(arg1: null); - }; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine1() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = () => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel() { buildCancelled = true; } + } + } + """); + } - x(arg1: null); - } - } - """, - """ - class C - { - delegate string MyDelegate(string arg1, int arg2 = 2, int arg3 = 3); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine2() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = a => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - void M() - { - string x(string arg1, int arg2 = 2, int arg3 = 3) - { - string a(string a1, int a2 = 2, int a3 = 3) - { - string b(string b1, int b2 = 2, int b3 = 3) => - b(b1: b(null), b2: a(a1: a(null)).Length, b3: 42) + - b(b1: b(null), b3: a(a1: a(null)).Length, b2: 42); - return b(b1: a1, b(b1: a1).Length); - } - - return a(a1: null); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine2Async() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = async a => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + async void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - x(arg1: null); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine2MultiToken() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + Func [||]onUpdateSolutionCancel = a => { return null; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + static int[] onUpdateSolutionCancel(int a) { return null; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine1() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = () => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel() { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine2MultiTokenAsync() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Threading.Tasks; + class C + { + void Goo() + { + Func> [||]onUpdateSolutionCancel = async a => { return null; }; + } + } + """, + """ + using System; + using System.Threading.Tasks; + class C + { + void Goo() + { + static async Task onUpdateSolutionCancel(int a) { return null; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine2() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = a => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine3() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = (int a) => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine2Async() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = async a => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - async void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine4() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = delegate (int a) { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine2MultiToken() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - Func [||]onUpdateSolutionCancel = a => { return null; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - static int[] onUpdateSolutionCancel(int a) { return null; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSimpleInitialization_SingleLine4Async() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = async delegate (int a) { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + async void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine2MultiTokenAsync() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - Func> [||]onUpdateSolutionCancel = async a => { return null; }; - } - } - """, - """ - using System; - using System.Threading.Tasks; - class C - { - void Goo() - { - static async Task onUpdateSolutionCancel(int a) { return null; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestCastInitialization_SingleLine1() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + var [||]onUpdateSolutionCancel = (Action)(() => { buildCancelled = true; }); + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel() { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine3() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = (int a) => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestCastInitialization_SingleLine2() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + var [||]onUpdateSolutionCancel = (Action)(a => { buildCancelled = true; }); + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine4() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = delegate (int a) { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestCastInitialization_SingleLine2Async() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + var [||]onUpdateSolutionCancel = (Action)(async a => { buildCancelled = true; }); + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + async void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSimpleInitialization_SingleLine4Async() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = async delegate (int a) { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - async void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestCastInitialization_SingleLine3() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + var [||]onUpdateSolutionCancel = (Action)((int a) => { buildCancelled = true; }); + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestCastInitialization_SingleLine1() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - var [||]onUpdateSolutionCancel = (Action)(() => { buildCancelled = true; }); - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel() { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestCastInitialization_SingleLine4() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + var [||]onUpdateSolutionCancel = (Action)(delegate (int a) { buildCancelled = true; }); + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestCastInitialization_SingleLine2() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - var [||]onUpdateSolutionCancel = (Action)(a => { buildCancelled = true; }); - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestCastInitialization_SingleLine4Async() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + var [||]onUpdateSolutionCancel = (Action)(async delegate (int a) { buildCancelled = true; }); + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + async void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestCastInitialization_SingleLine2Async() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - var [||]onUpdateSolutionCancel = (Action)(async a => { buildCancelled = true; }); - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - async void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSplitInitialization_SingleLine1() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = null; + onUpdateSolutionCancel = () => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel() { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestCastInitialization_SingleLine3() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - var [||]onUpdateSolutionCancel = (Action)((int a) => { buildCancelled = true; }); - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSplitInitialization_SingleLine2() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = null; + onUpdateSolutionCancel = a => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestCastInitialization_SingleLine4() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - var [||]onUpdateSolutionCancel = (Action)(delegate (int a) { buildCancelled = true; }); - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSplitInitialization_SingleLine2Async() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = null; + onUpdateSolutionCancel = async a => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + async void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestCastInitialization_SingleLine4Async() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - var [||]onUpdateSolutionCancel = (Action)(async delegate (int a) { buildCancelled = true; }); - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - async void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSplitInitialization_SingleLine3() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = null; + onUpdateSolutionCancel = (int a) => { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSplitInitialization_SingleLine1() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = null; - onUpdateSolutionCancel = () => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel() { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSplitInitialization_SingleLine4() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = null; + onUpdateSolutionCancel = delegate (int a) { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSplitInitialization_SingleLine2() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = null; - onUpdateSolutionCancel = a => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] + public async Task TestSplitInitialization_SingleLine4Async() + { + await TestInRegularAndScript1Async( + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + Action [||]onUpdateSolutionCancel = null; + onUpdateSolutionCancel = async delegate (int a) { buildCancelled = true; }; + } + } + """, + """ + using System; + class C + { + void Goo() + { + var buildCancelled = false; + async void onUpdateSolutionCancel(int a) { buildCancelled = true; } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSplitInitialization_SingleLine2Async() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = null; - onUpdateSolutionCancel = async a => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - async void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] + public async Task TestNotAvailableIfTypeParameterChanged1() + { + await TestMissingAsync( + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSplitInitialization_SingleLine3() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = null; - onUpdateSolutionCancel = (int a) => { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + class Enclosing + { + delegate T MyDelegate(T t); + static void Callee(MyDelegate d) => d(default); - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSplitInitialization_SingleLine4() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = null; - onUpdateSolutionCancel = delegate (int a) { buildCancelled = true; }; - } - } - """, - """ - using System; - class C + public class Class { - void Goo() + public void Caller() { - var buildCancelled = false; - void onUpdateSolutionCancel(int a) { buildCancelled = true; } + MyDelegate [||]local = x => x; + Callee(local); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23872")] - public async Task TestSplitInitialization_SingleLine4Async() - { - await TestInRegularAndScript1Async( - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - Action [||]onUpdateSolutionCancel = null; - onUpdateSolutionCancel = async delegate (int a) { buildCancelled = true; }; - } - } - """, - """ - using System; - class C - { - void Goo() - { - var buildCancelled = false; - async void onUpdateSolutionCancel(int a) { buildCancelled = true; } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] + public async Task TestNotAvailableIfTypeParameterChanged2() + { + await TestMissingAsync( + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] - public async Task TestNotAvailableIfTypeParameterChanged1() - { - await TestMissingAsync( - """ - using System; + class Enclosing + { + delegate T MyDelegate(T t); + static void Callee(MyDelegate d) => d(default); - class Enclosing + public class Goo { - delegate T MyDelegate(T t); - static void Callee(MyDelegate d) => d(default); - - public class Class + public class Class { public void Caller() { @@ -3268,917 +3294,890 @@ public void Caller() } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] - public async Task TestNotAvailableIfTypeParameterChanged2() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] + public async Task TestNotAvailableIfTypeParameterChanged3() + { + await TestMissingAsync( + """ + public class Class + { + delegate T MyDelegate(T t); + static void Callee(MyDelegate d) => d(default); - class Enclosing + public void Caller() { - delegate T MyDelegate(T t); - static void Callee(MyDelegate d) => d(default); - - public class Goo + void Some(T t) { - public class Class - { - public void Caller() - { - MyDelegate [||]local = x => x; - Callee(local); - } - } + MyDelegate [||]local = x => x; + Callee(local); } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] - public async Task TestNotAvailableIfTypeParameterChanged3() - { - await TestMissingAsync( - """ - public class Class - { - delegate T MyDelegate(T t); - static void Callee(MyDelegate d) => d(default); + } + """); + } - public void Caller() - { - void Some(T t) - { - MyDelegate [||]local = x => x; - Callee(local); - } - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] + public async Task TestNotAvailableIfTypeParameterChanged4() + { + await TestMissingAsync( + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] - public async Task TestNotAvailableIfTypeParameterChanged4() - { - await TestMissingAsync( - """ - using System; + class Enclosing + { + delegate T MyDelegate(T t); + static void Callee(MyDelegate d) => d(default); - class Enclosing + public class Goo { - delegate T MyDelegate(T t); - static void Callee(MyDelegate d) => d(default); - - public class Goo + public class Class { - public class Class + public void Caller() { - public void Caller() - { - MyDelegate [||]local = x => x; - Callee(local); - } + MyDelegate [||]local = x => x; + Callee(local); } } } - """); - } - - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/27950")] - [WorkItem("https://github.com/dotnet/roslyn/issues/23149")] - public async Task TestAvailableIfTypeParameterNotChanged1() - { - await TestInRegularAndScript1Async( - """ - using System; - - class DelegateEnclosing - { - protected delegate T MyDelegate(T t); - } - - class Enclosing : DelegateEnclosing - { - static void Callee(MyDelegate d) => d(default); - - public void Caller() - { - MyDelegate [||]local = x => x; - Callee(local); - } - } - """, - """ - using System; - - class DelegateEnclosing - { - protected delegate T MyDelegate(T t); - } + } + """); + } - class Enclosing : DelegateEnclosing - { - static void Callee(MyDelegate d) => d(default); + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/27950")] + [WorkItem("https://github.com/dotnet/roslyn/issues/23149")] + public async Task TestAvailableIfTypeParameterNotChanged1() + { + await TestInRegularAndScript1Async( + """ + using System; - public void Caller() - { - static T local(T x) => x; - Callee(local); - } - } - """); - } + class DelegateEnclosing + { + protected delegate T MyDelegate(T t); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] - public async Task TestAvailableIfTypeParameterNotChanged2() - { - await TestInRegularAndScript1Async( - """ - using System; + class Enclosing : DelegateEnclosing + { + static void Callee(MyDelegate d) => d(default); - class DelegateEnclosing + public void Caller() { - protected delegate T MyDelegate(T t); + MyDelegate [||]local = x => x; + Callee(local); } + } + """, + """ + using System; - class Enclosing : DelegateEnclosing - { - static void Callee(MyDelegate d) => d(default); + class DelegateEnclosing + { + protected delegate T MyDelegate(T t); + } - public void Caller() - { - MyDelegate [||]local = x => x; - Callee(local); - } - } - """, - """ - using System; + class Enclosing : DelegateEnclosing + { + static void Callee(MyDelegate d) => d(default); - class DelegateEnclosing + public void Caller() { - protected delegate T MyDelegate(T t); + static T local(T x) => x; + Callee(local); } + } + """); + } - class Enclosing : DelegateEnclosing + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23149")] + public async Task TestAvailableIfTypeParameterNotChanged2() + { + await TestInRegularAndScript1Async( + """ + using System; + + class DelegateEnclosing + { + protected delegate T MyDelegate(T t); + } + + class Enclosing : DelegateEnclosing + { + static void Callee(MyDelegate d) => d(default); + + public void Caller() { - static void Callee(MyDelegate d) => d(default); + MyDelegate [||]local = x => x; + Callee(local); + } + } + """, + """ + using System; - public void Caller() - { - static U local(U x) => x; - Callee(local); - } + class DelegateEnclosing + { + protected delegate T MyDelegate(T t); + } + + class Enclosing : DelegateEnclosing + { + static void Callee(MyDelegate d) => d(default); + + public void Caller() + { + static U local(U x) => x; + Callee(local); } - """); - } + } + """); + } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56963")] - [WorkItem("https://github.com/dotnet/roslyn/issues/26526")] - public async Task TestAvailableWithCastIntroducedIfAssignedToVar() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/56963")] + [WorkItem("https://github.com/dotnet/roslyn/issues/26526")] + public async Task TestAvailableWithCastIntroducedIfAssignedToVar() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = () => null; + Func [||]f = () => null; - var f2 = f; - } + var f2 = f; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static string f() => null; + static string f() => null; - var f2 = (Func)f; - } + var f2 = (Func)f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26526")] - public async Task TestAvailableWithCastIntroducedForGenericTypeInference1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26526")] + public async Task TestAvailableWithCastIntroducedForGenericTypeInference1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = _ => null; + Func [||]f = _ => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static string f(int _) => null; + static string f(int _) => null; - Method((Func)f); - } + Method((Func)f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26526")] - public async Task TestAvailableWithCastIntroducedForGenericTypeInference2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26526")] + public async Task TestAvailableWithCastIntroducedForGenericTypeInference2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = _ => null; + Func [||]f = _ => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { + } - void Method(string o) - { - } + void Method(string o) + { } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static string f(int _) => null; + static string f(int _) => null; - Method((Func)f); - } + Method((Func)f); + } - void Method(Func o) - { - } + void Method(Func o) + { + } - void Method(string o) - { - } + void Method(string o) + { } - """); - } + } + """); + } - [Fact] - public async Task TestAvailableWithCastIntroducedForOverloadResolution() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestAvailableWithCastIntroducedForOverloadResolution() + { + await TestInRegularAndScript1Async( + """ + using System; - delegate string CustomDelegate(); + delegate string CustomDelegate(); - class C + class C + { + void M() { - void M() - { - Func [||]f = () => null; + Func [||]f = () => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { + } - void Method(CustomDelegate o) - { - } + void Method(CustomDelegate o) + { } - """, - """ - using System; + } + """, + """ + using System; - delegate string CustomDelegate(); + delegate string CustomDelegate(); - class C + class C + { + void M() { - void M() - { - static string f() => null; + static string f() => null; - Method((Func)f); - } + Method((Func)f); + } - void Method(Func o) - { - } + void Method(Func o) + { + } - void Method(CustomDelegate o) - { - } + void Method(CustomDelegate o) + { } - """); - } + } + """); + } - [Fact] - public async Task TestAvailableWithoutCastIfUnnecessaryForOverloadResolution() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestAvailableWithoutCastIfUnnecessaryForOverloadResolution() + { + await TestInRegularAndScript1Async( + """ + using System; - delegate string CustomDelegate(object arg); + delegate string CustomDelegate(object arg); - class C + class C + { + void M() { - void M() - { - Func [||]f = () => null; + Func [||]f = () => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { + } - void Method(CustomDelegate o) - { - } + void Method(CustomDelegate o) + { } - """, - """ - using System; + } + """, + """ + using System; - delegate string CustomDelegate(object arg); + delegate string CustomDelegate(object arg); - class C + class C + { + void M() { - void M() - { - static string f() => null; + static string f() => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { + } - void Method(CustomDelegate o) - { - } + void Method(CustomDelegate o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestNotAvailableWithInvalidDeclaration() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestNotAvailableWithInvalidDeclaration() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = () => null); + Func [||]f = () => null); - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestNotAvailableWithInvalidDeclaration2() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestNotAvailableWithInvalidDeclaration2() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f) = () => null; + Func [||]f) = () => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestNotAvailableWithInvalidDeclaration3() - { - await TestMissingAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestNotAvailableWithInvalidDeclaration3() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func) [||]f = () => null; + Func) [||]f = () => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestWithInvalidUnrelatedCode() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestWithInvalidUnrelatedCode() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = _ => null; + Func [||]f = _ => null; - Method(f); - } + Method(f); + } - void Method(Func o)) - { - } + void Method(Func o)) + { } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static string f(int _) => null; + static string f(int _) => null; - Method((Func)f); - } + Method((Func)f); + } - void Method(Func o)) - { - } + void Method(Func o)) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestWithInvalidUnrelatedCode2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestWithInvalidUnrelatedCode2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = _ => null; + Func [||]f = _ => null; - (Method(f); - } + (Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - static string f(int _) => null; + static string f(int _) => null; - (Method((Func)f); - } + (Method((Func)f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestWithObsoleteCode() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestWithObsoleteCode() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - Func [||]f = _ => S(); + Func [||]f = _ => S(); - Method(f); - } + Method(f); + } - [System.Obsolete] - string S() - { - return null; - } + [System.Obsolete] + string S() + { + return null; + } - void Method(Func o) - { - } + void Method(Func o) + { } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - string f(int _) => S(); + string f(int _) => S(); - Method((Func)f); - } + Method((Func)f); + } - [System.Obsolete] - string S() - { - return null; - } + [System.Obsolete] + string S() + { + return null; + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] - public async Task TestWithDeclarationWarning() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29793")] + public async Task TestWithDeclarationWarning() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() - { - #warning Declaration Warning - Func [||]f = _ => null; + #warning Declaration Warning + Func [||]f = _ => null; - Method(f); - } + Method(f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - #warning Declaration Warning - static string f(int _) => null; + #warning Declaration Warning + static string f(int _) => null; - Method((Func)f); - } + Method((Func)f); + } - void Method(Func o) - { - } + void Method(Func o) + { } - """); - } + } + """); + } - [Fact] - public async Task TestMakeStaticIfNoCaptures() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestMakeStaticIfNoCaptures() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + if (v <= 1) { - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + static int fibonacci(int v) { - static int fibonacci(int v) + if (v <= 1) { - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestDoNotMakeStaticIfCaptures() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestDoNotMakeStaticIfCaptures() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M() { - void M() + Func [||]fibonacci = v => { - Func [||]fibonacci = v => + M(); + if (v <= 1) { - M(); - if (v <= 1) - { - return 1; - } + return 1; + } - return fibonacci(v - 1, v - 2); - }; - } + return fibonacci(v - 1, v - 2); + }; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() + int fibonacci(int v) { - int fibonacci(int v) + M(); + if (v <= 1) { - M(); - if (v <= 1) - { - return 1; - } - - return fibonacci(v - 1, v - 2); + return 1; } + + return fibonacci(v - 1, v - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestWithAsyncLambdaExpression_MakeStatic() - { - await TestInRegularAndScript1Async( - """ - using System; - using System.Threading.Tasks; + [Fact] + public async Task TestWithAsyncLambdaExpression_MakeStatic() + { + await TestInRegularAndScript1Async( + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - Func [||]f = async () => await Task.Yield(); - } + Func [||]f = async () => await Task.Yield(); } - """, - """ - using System; - using System.Threading.Tasks; + } + """, + """ + using System; + using System.Threading.Tasks; - class C + class C + { + void M() { - void M() - { - static async Task f() => await Task.Yield(); - } + static async Task f() => await Task.Yield(); } - """); - } + } + """); + } - [Fact] - public async Task TestWithNullableParameterAndReturn() - { - await TestInRegularAndScript1Async( - """ - #nullable enable + [Fact] + public async Task TestWithNullableParameterAndReturn() + { + await TestInRegularAndScript1Async( + """ + #nullable enable - using System; + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Func [||]f = s => s; - } + Func [||]f = s => s; } - """, - """ - #nullable enable + } + """, + """ + #nullable enable - using System; + using System; - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - static string? f(string? s) => s; - } + static string? f(string? s) => s; } - """); - } + } + """); + } - [Fact] - public async Task TestWithDiscardParameters() - { - await TestInRegularAndScript1Async( - """ - class Program + [Fact] + public async Task TestWithDiscardParameters() + { + await TestInRegularAndScript1Async( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - System.Func [||]f = (_, _, a) => 1; - } + System.Func [||]f = (_, _, a) => 1; } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - static long f(int _, string _, int a) => 1; - } + static long f(int _, string _, int a) => 1; } - """); - } + } + """); + } - [Fact] - public async Task TestWithOptionalParameter() - { - await TestInRegularAndScript1Async( - """ - class Program + [Fact] + public async Task TestWithOptionalParameter() + { + await TestInRegularAndScript1Async( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + System.Func [||]fibonacci = (int n = 1) => { - System.Func [||]fibonacci = (int n = 1) => - { - return n <= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); - }; - } + return n <= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); + }; } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + static int fibonacci(int n = 1) { - static int fibonacci(int n = 1) - { - return n <= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); - } + return n <= 1 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); } } - """); - } + } + """); + } - [Fact] - public async Task TestWithParamsArray() - { - await TestInRegularAndScript1Async( - """ - class Program + [Fact] + public async Task TestWithParamsArray() + { + await TestInRegularAndScript1Async( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + System.Func [||]last = (params int[] xs) => { - System.Func [||]last = (params int[] xs) => - { - return x.Length == 1 ? xs[0] : last(xs[1..]); - }; - } + return x.Length == 1 ? xs[0] : last(xs[1..]); + }; } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + static int last(params int[] xs) { - static int last(params int[] xs) - { - return x.Length == 1 ? xs[0] : last(xs[1..]); - } + return x.Length == 1 ? xs[0] : last(xs[1..]); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68439")] - public async Task TestImplicitlyTypedLambdaCSharp10() - { - await TestInRegularAndScriptAsync( - """ - class Program - { - static void Main() - { - var [||]test = (int n) => n * 2; - } - } - """, - """ - class Program - { - static void Main() - { - static int test(int n) => n * 2; - } - } - """, - parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10)); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68439")] + public async Task TestImplicitlyTypedLambdaCSharp10() + { + await TestInRegularAndScriptAsync( + """ + class Program + { + static void Main() + { + var [||]test = (int n) => n * 2; + } + } + """, + """ + class Program + { + static void Main() + { + static int test(int n) => n * 2; + } + } + """, + parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68439")] - public async Task TestImplicitlyTypedLambdaCSharp9() - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68439")] + public async Task TestImplicitlyTypedLambdaCSharp9() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Main() { - static void Main() - { - var [||]test = (int n) => n * 2; - } + var [||]test = (int n) => n * 2; } - """, - new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9))); - } + } + """, + new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9))); } } diff --git a/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs b/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs index 7e34b08558e57..aa9353c212a0b 100644 --- a/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs +++ b/src/Analyzers/CSharp/Tests/UseNullPropagation/UseNullPropagationTests.cs @@ -11,2407 +11,2406 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseNullPropagation -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseNullPropagationDiagnosticAnalyzer, - CSharpUseNullPropagationCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseNullPropagation; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseNullPropagationDiagnosticAnalyzer, + CSharpUseNullPropagationCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseNullPropagation)] - public partial class UseNullPropagationTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseNullPropagation)] +public partial class UseNullPropagationTests +{ + private static async Task TestInRegularAndScript1Async(string testCode, string fixedCode, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary) { - private static async Task TestInRegularAndScript1Async(string testCode, string fixedCode, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary) - { - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - // code action is currently generating invalid trees. Specifically, it transforms `x.Y()` into `x.?Y()` - // by just rewriting `x.Y` into `x?.Y`. That is not correct. the RHS of the `?` should `.Y()` not - // `.Y`. - CodeActionValidationMode = CodeActionValidationMode.None, - LanguageVersion = LanguageVersion.CSharp9, - TestState = - { - OutputKind = outputKind, - }, - }.RunAsync(); - } - - private static async Task TestMissingInRegularAndScriptAsync(string testCode, LanguageVersion languageVersion = LanguageVersion.CSharp9) - { - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = testCode, + FixedCode = fixedCode, + // code action is currently generating invalid trees. Specifically, it transforms `x.Y()` into `x.?Y()` + // by just rewriting `x.Y` into `x?.Y`. That is not correct. the RHS of the `?` should `.Y()` not + // `.Y`. + CodeActionValidationMode = CodeActionValidationMode.None, + LanguageVersion = LanguageVersion.CSharp9, + TestState = { - TestCode = testCode, - FixedCode = testCode, - LanguageVersion = languageVersion, - }.RunAsync(); - } + OutputKind = outputKind, + }, + }.RunAsync(); + } - [Fact] - public async Task TestLeft_Equals() + private static async Task TestMissingInRegularAndScriptAsync(string testCode, LanguageVersion languageVersion = LanguageVersion.CSharp9) + { + await new VerifyCS.Test { - await TestInRegularAndScript1Async( - """ - using System; + TestCode = testCode, + FixedCode = testCode, + LanguageVersion = languageVersion, + }.RunAsync(); + } - class C + [Fact] + public async Task TestLeft_Equals() + { + await TestInRegularAndScript1Async( + """ + using System; + + class C + { + void M(object o) { - void M(object o) - { - var v = [|o == null ? null : o.ToString()|]; - } + var v = [|o == null ? null : o.ToString()|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestLeft_Equals_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestLeft_Equals_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - [|if|] (o != null) - o.ToString(); - } + [|if|] (o != null) + o.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?.ToString(); - } + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_WithBlock() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIfStatement_WithBlock() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) + [|if|] (o != null) { - [|if|] (o != null) - { - o.ToString(); - } + o.ToString(); } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?.ToString(); - } + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_NotWithElse() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestIfStatement_NotWithElse() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) + if (o != null) + o.ToString(); + else { - if (o != null) - o.ToString(); - else - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_NotWithMultipleStatements() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestIfStatement_NotWithMultipleStatements() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) + if (o != null) { - if (o != null) - { - o.ToString(); - o.ToString(); - } + o.ToString(); + o.ToString(); } } - """); - } + } + """); + } - [Fact] - public async Task TestLeft_Equals_IfStatement_TopLevel() - { - await TestInRegularAndScript1Async( - """ - using System; - - object o = null; - [|if|] (o != null) - o.ToString(); - """, - """ - using System; - - object o = null; - o?.ToString(); - """, OutputKind.ConsoleApplication); - } - - [Fact] - public async Task TestLeft_IsNull() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestLeft_Equals_IfStatement_TopLevel() + { + await TestInRegularAndScript1Async( + """ + using System; + + object o = null; + [|if|] (o != null) + o.ToString(); + """, + """ + using System; + + object o = null; + o?.ToString(); + """, OutputKind.ConsoleApplication); + } + + [Fact] + public async Task TestLeft_IsNull() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o is null ? null : o.ToString()|]; - } + var v = [|o is null ? null : o.ToString()|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestLeft_IsNotNull() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestLeft_IsNotNull() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o is not null ? o.ToString() : null|]; - } + var v = [|o is not null ? o.ToString() : null|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestLeft_IsNotNull_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestLeft_IsNotNull_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - [|if|] (o is not null) - o.ToString(); - } + [|if|] (o is not null) + o.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?.ToString(); - } + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnCSharp5() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestMissingOnCSharp5() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o == null ? null : o.ToString(); - } + var v = o == null ? null : o.ToString(); } - """, LanguageVersion.CSharp5); - } + } + """, LanguageVersion.CSharp5); + } - [Fact] - public async Task TestMissingOnCSharp5_IfStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestMissingOnCSharp5_IfStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - if (o != null) - o.ToString(); - } + if (o != null) + o.ToString(); } - """, LanguageVersion.CSharp5); - } + } + """, LanguageVersion.CSharp5); + } - [Fact] - public async Task TestRight_Equals() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestRight_Equals() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|null == o ? null : o.ToString()|]; - } + var v = [|null == o ? null : o.ToString()|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestRight_Equals_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestRight_Equals_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - [|if|] (null != o) - o.ToString(); - } + [|if|] (null != o) + o.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?.ToString(); - } + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestLeft_NotEquals() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestLeft_NotEquals() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o != null ? o.ToString() : null|]; - } + var v = [|o != null ? o.ToString() : null|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestWithNullableType() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestWithNullableType() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|c != null ? c.f : null|]; - } + int? x = [|c != null ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact] - public async Task TestWithNullableType_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestWithNullableType_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (c != null) - c.f?.ToString(); - } + [|if|] (c != null) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestWithNullableTypeAndObjectCast() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestWithNullableTypeAndObjectCast() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|(object)c != null ? c.f : null|]; - } + int? x = [|(object)c != null ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact] - public async Task TestWithNullableTypeAndObjectCast_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestWithNullableTypeAndObjectCast_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] ((object)c != null) - c.f?.ToString(); - } + [|if|] ((object)c != null) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestRight_NotEquals() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestRight_NotEquals() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|null != o ? o.ToString() : null|]; - } + var v = [|null != o ? o.ToString() : null|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIndexer() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIndexer() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o == null ? null : {|CS0021:o[0]|}|]; - } + var v = [|o == null ? null : {|CS0021:o[0]|}|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?{|CS0021:[0]|}; - } + var v = o?{|CS0021:[0]|}; } - """); - } + } + """); + } - [Fact] - public async Task TestIndexer_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIndexer_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - [|if|] (o != null) - {|CS0021:o[0]|}.ToString(); - } + [|if|] (o != null) + {|CS0021:o[0]|}.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?{|CS0021:[0]|}.ToString(); - } + o?{|CS0021:[0]|}.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestConditionalAccess() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestConditionalAccess() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o == null ? null : o.{|CS1061:B|}?.C|]; - } + var v = [|o == null ? null : o.{|CS1061:B|}?.C|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?{|CS1061:.B|}?.C; - } + var v = o?{|CS1061:.B|}?.C; } - """); - } + } + """); + } - [Fact] - public async Task TestConditionalAccess_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestConditionalAccess_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - [|if|](o != null) - o.{|CS1061:B|}?.C(); - } + [|if|](o != null) + o.{|CS1061:B|}?.C(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?{|CS1061:.B|}?.C(); - } + o?{|CS1061:.B|}?.C(); } - """); - } + } + """); + } - [Fact] - public async Task TestMemberAccess() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestMemberAccess() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o == null ? null : o.{|CS1061:B|}|]; - } + var v = [|o == null ? null : o.{|CS1061:B|}|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?{|CS1061:.B|}; - } + var v = o?{|CS1061:.B|}; } - """); - } + } + """); + } - [Fact] - public async Task TestMemberAccess_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestMemberAccess_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - [|if|] (o != null) - o.{|CS1061:B|}(); - } + [|if|] (o != null) + o.{|CS1061:B|}(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - o?{|CS1061:.B|}(); - } + o?{|CS1061:.B|}(); } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnSimpleMatch() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestMissingOnSimpleMatch() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o == null ? null : o; - } + var v = o == null ? null : o; } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnSimpleMatch_IfStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestMissingOnSimpleMatch_IfStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - if (o != null) - {|CS0201:o|}; - } + if (o != null) + {|CS0201:o|}; } - """); - } + } + """); + } - [Fact] - public async Task TestParenthesizedCondition() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestParenthesizedCondition() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|(o == null) ? null : o.ToString()|]; - } + var v = [|(o == null) ? null : o.ToString()|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v1 = [|o == null ? null : o.ToString()|]; - var v2 = [|o != null ? o.ToString() : null|]; - } + var v1 = [|o == null ? null : o.ToString()|]; + var v2 = [|o != null ? o.ToString() : null|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v1 = o?.ToString(); - var v2 = o?.ToString(); - } + var v1 = o?.ToString(); + var v2 = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestFixAll2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o1, object o2) { - void M(object o1, object o2) - { - var v1 = [|o1 == null ? null : o1.{|CS1501:ToString|}([|o2 == null ? null : o2.ToString()|])|]; - } + var v1 = [|o1 == null ? null : o1.{|CS1501:ToString|}([|o2 == null ? null : o2.ToString()|])|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o1, object o2) { - void M(object o1, object o2) - { - var v1 = o1?{|CS1501:.ToString|}(o2?.ToString()); - } + var v1 = o1?{|CS1501:.ToString|}(o2?.ToString()); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15505")] - public async Task TestOtherValueIsNotNull1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15505")] + public async Task TestOtherValueIsNotNull1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = {|CS0173:o == null ? 0 : o.ToString()|}; - } + var v = {|CS0173:o == null ? 0 : o.ToString()|}; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15505")] - public async Task TestOtherValueIsNotNull2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15505")] + public async Task TestOtherValueIsNotNull2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = {|CS0173:o != null ? o.ToString() : 0|}; - } + var v = {|CS0173:o != null ? o.ToString() : 0|}; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16287")] - public async Task TestMethodGroup() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16287")] + public async Task TestMethodGroup() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class D + class D + { + void Goo() { - void Goo() - { - var c = new C(); - Action a = c != null ? c.M : (Action)null; - } + var c = new C(); + Action a = c != null ? c.M : (Action)null; } - class C { public void M(string s) { } } - """); - } + } + class C { public void M(string s) { } } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] - public async Task TestInExpressionTree() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] + public async Task TestInExpressionTree() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; - class Program + class Program + { + void Main(string s) { - void Main(string s) - { - Method(t => s != null ? s.ToString() : null); // works - } - - public void Method(Expression> functor) - { - } + Method(t => s != null ? s.ToString() : null); // works } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33992")] - public async Task TestInExpressionTree2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Linq; - class C + public void Method(Expression> functor) { - void Main() - { - _ = from item in Enumerable.Empty<(int? x, int? y)?>().AsQueryable() - select item == null ? null : item.Value.x; - } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33992")] - public async Task TestInExpressionTree3() - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Linq; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33992")] + public async Task TestInExpressionTree2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Linq; - class C + class C + { + void Main() { - void Main() - { - _ = from item in Enumerable.Empty<(int? x, int? y)?>().AsQueryable() - where (item == null ? null : item.Value.x) > 0 - select item; - } + _ = from item in Enumerable.Empty<(int? x, int? y)?>().AsQueryable() + select item == null ? null : item.Value.x; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] - [WorkItem("https://github.com/dotnet/roslyn/issues/33992")] - public async Task TestInExpressionTree4() - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Linq; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33992")] + public async Task TestInExpressionTree3() + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Linq; - class C + class C + { + void Main() { - void Main() - { - _ = from item in Enumerable.Empty<(int? x, int? y)?>().AsQueryable() - let x = item == null ? null : item.Value.x - select x; - } + _ = from item in Enumerable.Empty<(int? x, int? y)?>().AsQueryable() + where (item == null ? null : item.Value.x) > 0 + select item; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19774")] - public async Task TestNullableMemberAccess() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17623")] + [WorkItem("https://github.com/dotnet/roslyn/issues/33992")] + public async Task TestInExpressionTree4() + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Linq; - class C + class C + { + void Main() { - void Main(DateTime? toDate) - { - var v = [|toDate == null ? null : toDate.Value.ToString("yyyy/MM/ dd")|]; - } + _ = from item in Enumerable.Empty<(int? x, int? y)?>().AsQueryable() + let x = item == null ? null : item.Value.x + select x; } - """, + } + """); + } - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19774")] + public async Task TestNullableMemberAccess() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Main(DateTime? toDate) { - void Main(DateTime? toDate) - { - var v = toDate?.ToString("yyyy/MM/ dd"); - } + var v = [|toDate == null ? null : toDate.Value.ToString("yyyy/MM/ dd")|]; } - """); - } + } + """, - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19774")] - public async Task TestNullableMemberAccess_IfStatement() - { - await TestInRegularAndScript1Async( - """ - using System; + """ + using System; - class C + class C + { + void Main(DateTime? toDate) { - void Main(DateTime? toDate) - { - [|if|] (toDate != null) - toDate.Value.ToString("yyyy/MM/ dd"); - } + var v = toDate?.ToString("yyyy/MM/ dd"); } - """, + } + """); + } - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19774")] + public async Task TestNullableMemberAccess_IfStatement() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void Main(DateTime? toDate) { - void Main(DateTime? toDate) - { - toDate?.ToString("yyyy/MM/ dd"); - } + [|if|] (toDate != null) + toDate.Value.ToString("yyyy/MM/ dd"); } - """); - } + } + """, - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19774")] - public async Task TestNullableElementAccess() - { - await TestInRegularAndScript1Async( - """ - using System; + """ + using System; - struct S + class C + { + void Main(DateTime? toDate) { - public string this[int i] => ""; + toDate?.ToString("yyyy/MM/ dd"); } + } + """); + } - class C - { - void Main(S? s) - { - var x = [|s == null ? null : s.Value[0]|]; - } - } - """, + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19774")] + public async Task TestNullableElementAccess() + { + await TestInRegularAndScript1Async( + """ + using System; - """ - using System; + struct S + { + public string this[int i] => ""; + } - struct S + class C + { + void Main(S? s) { - public string this[int i] => ""; + var x = [|s == null ? null : s.Value[0]|]; } + } + """, + + """ + using System; - class C + struct S + { + public string this[int i] => ""; + } + + class C + { + void Main(S? s) { - void Main(S? s) - { - var x = s?[0]; - } + var x = s?[0]; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsNull() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsNull() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|c is null ? null : c.f|]; - } + int? x = [|c is null ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsNotNull() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsNotNull() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|c is not null ? c.f : null|]; - } + int? x = [|c is not null ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsNotNull_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsNotNull_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (c is not null) - c.f?.ToString(); - } + [|if|] (c is not null) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c is C ? null : c.f; - } + int? x = c is C ? null : c.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsType_IfStatement1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsType_IfStatement1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - if (c is C) - c.f?.ToString(); - } + if (c is C) + c.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsType_IfStatement2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsType_IfStatement2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - if (c is C d) - c.f?.ToString(); - } + if (c is C d) + c.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndIsType_IfStatement3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndIsType_IfStatement3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - if (c is not C) - c.f?.ToString(); - } + if (c is not C) + c.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestIsOtherConstant() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestIsOtherConstant() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - int? x = s is "" ? null : (int?)s.Length; - } + int? x = s is "" ? null : (int?)s.Length; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEquals1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEquals1() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|ReferenceEquals(c, null) ? null : c.f|]; - } + int? x = [|ReferenceEquals(c, null) ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEquals1_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEquals1_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (!ReferenceEquals(c, null)) - c.f?.ToString(); - } + [|if|] (!ReferenceEquals(c, null)) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEquals2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEquals2() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|ReferenceEquals(null, c) ? null : c.f|]; - } + int? x = [|ReferenceEquals(null, c) ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEquals2_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEquals2_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (!ReferenceEquals(null, c)) - c.f?.ToString(); - } + [|if|] (!ReferenceEquals(null, c)) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsOtherValue1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsOtherValue1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = ReferenceEquals(c, other) ? null : c.f; - } + int? x = ReferenceEquals(c, other) ? null : c.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsOtherValue1_IfStatement1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsOtherValue1_IfStatement1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - if (ReferenceEquals(c, other)) - c.f?.ToString(); - } + if (ReferenceEquals(c, other)) + c.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsOtherValue1_IfStatement2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsOtherValue1_IfStatement2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - if (!ReferenceEquals(c, other)) - c.f?.ToString(); - } + if (!ReferenceEquals(c, other)) + c.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsOtherValue2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsOtherValue2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = ReferenceEquals(other, c) ? null : c.f; - } + int? x = ReferenceEquals(other, c) ? null : c.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsWithObject1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsWithObject1() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|object.ReferenceEquals(c, null) ? null : c.f|]; - } + int? x = [|object.ReferenceEquals(c, null) ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsWithObject1_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsWithObject1_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (!object.ReferenceEquals(c, null)) - c.f?.ToString(); - } + [|if|] (!object.ReferenceEquals(c, null)) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsWithObject2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsWithObject2() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|object.ReferenceEquals(null, c) ? null : c.f|]; - } + int? x = [|object.ReferenceEquals(null, c) ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsWithObject2_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsWithObject2_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (!object.ReferenceEquals(null, c)) - c.f?.ToString(); - } + [|if|] (!object.ReferenceEquals(null, c)) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsOtherValueWithObject1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsOtherValueWithObject1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = object.ReferenceEquals(c, other) ? null : c.f; - } + int? x = object.ReferenceEquals(c, other) ? null : c.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndReferenceEqualsOtherValueWithObject2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndReferenceEqualsOtherValueWithObject2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = object.ReferenceEquals(other, c) ? null : c.f; - } + int? x = object.ReferenceEquals(other, c) ? null : c.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndNotIsNull() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndNotIsNull() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!(c is null) ? c.f : null|]; - } + int? x = [|!(c is null) ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndNotIsNotNull() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndNotIsNotNull() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!(c is not null) ? null : c.f|]; - } + int? x = [|!(c is not null) ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndNotIsType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndNotIsType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = !(c is C) ? c.f : null; - } + int? x = !(c is C) ? c.f : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndNotIsOtherConstant() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndNotIsOtherConstant() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(string s) { - void M(string s) - { - int? x = !(s is "") ? (int?)s.Length : null; - } + int? x = !(s is "") ? (int?)s.Length : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEquals1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEquals1() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!ReferenceEquals(c, null) ? c.f : null|]; - } + int? x = [|!ReferenceEquals(c, null) ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEquals2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEquals2() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!ReferenceEquals(null, c) ? c.f : null|]; - } + int? x = [|!ReferenceEquals(null, c) ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValue1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValue1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = !ReferenceEquals(c, other) ? c.f : null; - } + int? x = !ReferenceEquals(c, other) ? c.f : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValue2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValue2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = !ReferenceEquals(other, c) ? c.f : null; - } + int? x = !ReferenceEquals(other, c) ? c.f : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsWithObject1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsWithObject1() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!object.ReferenceEquals(c, null) ? c.f : null|]; - } + int? x = [|!object.ReferenceEquals(c, null) ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsWithObject2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsWithObject2() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!object.ReferenceEquals(null, c) ? c.f : null|]; - } + int? x = [|!object.ReferenceEquals(null, c) ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValueWithObject1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValueWithObject1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = !object.ReferenceEquals(c, other) ? c.f : null; - } + int? x = !object.ReferenceEquals(c, other) ? c.f : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValueWithObject2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestWithNullableTypeAndLogicalNotReferenceEqualsOtherValueWithObject2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = !object.ReferenceEquals(other, c) ? c.f : null; - } + int? x = !object.ReferenceEquals(other, c) ? c.f : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestEqualsWithLogicalNot() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestEqualsWithLogicalNot() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!(c == null) ? c.f : null|]; - } + int? x = [|!(c == null) ? c.f : null|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestEqualsWithLogicalNot_IfStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestEqualsWithLogicalNot_IfStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - [|if|] (!(c == null)) - c.f?.ToString(); - } + [|if|] (!(c == null)) + c.f?.ToString(); } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - c?.f?.ToString(); - } + c?.f?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestNotEqualsWithLogicalNot() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestNotEqualsWithLogicalNot() + { + await TestInRegularAndScript1Async( + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = [|!(c != null) ? null : c.f|]; - } + int? x = [|!(c != null) ? null : c.f|]; } - """, - """ - class C + } + """, + """ + class C + { + public int? f; + void M(C c) { - public int? f; - void M(C c) - { - int? x = c?.f; - } + int? x = c?.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestEqualsOtherValueWithLogicalNot() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestEqualsOtherValueWithLogicalNot() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = !(c == other) ? c.f : null; - } + int? x = !(c == other) ? c.f : null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] - public async Task TestNotEqualsOtherValueWithLogicalNot() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23043")] + public async Task TestNotEqualsOtherValueWithLogicalNot() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public int? f; + void M(C c, C other) { - public int? f; - void M(C c, C other) - { - int? x = !(c != other) ? null : c.f; - } + int? x = !(c != other) ? null : c.f; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] - public async Task TestParenthesizedExpression() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] + public async Task TestParenthesizedExpression() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|(o == null) ? null : (o.ToString())|]; - } + var v = [|(o == null) ? null : (o.ToString())|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = (o?.ToString()); - } + var v = (o?.ToString()); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] - public async Task TestReversedParenthesizedExpression() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] + public async Task TestReversedParenthesizedExpression() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|(o != null) ? (o.ToString()) : null|]; - } + var v = [|(o != null) ? (o.ToString()) : null|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = (o?.ToString()); - } + var v = (o?.ToString()); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] - public async Task TestParenthesizedNull() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] + public async Task TestParenthesizedNull() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o == null ? (null) : o.ToString()|]; - } + var v = [|o == null ? (null) : o.ToString()|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] - public async Task TestReversedParenthesizedNull() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49517")] + public async Task TestReversedParenthesizedNull() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = [|o != null ? o.ToString() : (null)|]; - } + var v = [|o != null ? o.ToString() : (null)|]; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - var v = o?.ToString(); - } + var v = o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_Trivia1() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIfStatement_Trivia1() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before - [|if|] (o != null) - o.ToString(); - } + // Before + [|if|] (o != null) + o.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before - o?.ToString(); - } + // Before + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_Trivia2() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIfStatement_Trivia2() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before1 - [|if|] (o != null) - // Before2 - o.ToString(); - } + // Before1 + [|if|] (o != null) + // Before2 + o.ToString(); } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before1 - // Before2 - o?.ToString(); - } + // Before1 + // Before2 + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_Trivia3() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIfStatement_Trivia3() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) + // Before1 + [|if|] (o != null) { - // Before1 - [|if|] (o != null) - { - // Before2 - o.ToString(); - } + // Before2 + o.ToString(); } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before1 - // Before2 - o?.ToString(); - } + // Before1 + // Before2 + o?.ToString(); } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_Trivia4() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIfStatement_Trivia4() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) + // Before1 + [|if|] (o != null) { - // Before1 - [|if|] (o != null) - { - // Before2 - o.ToString(); // After - } + // Before2 + o.ToString(); // After } } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before1 - // Before2 - o?.ToString(); // After - } + // Before1 + // Before2 + o?.ToString(); // After } - """); - } + } + """); + } - [Fact] - public async Task TestIfStatement_Trivia5() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact] + public async Task TestIfStatement_Trivia5() + { + await TestInRegularAndScript1Async( + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) + // Before1 + [|if|] (o != null) { - // Before1 - [|if|] (o != null) - { - // Before2 - o.ToString(); - } // After - } + // Before2 + o.ToString(); + } // After } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(object o) { - void M(object o) - { - // Before1 - // Before2 - o?.ToString(); // After - } + // Before1 + // Before2 + o?.ToString(); // After } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnPointer_IfStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotOnPointer_IfStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + unsafe void M(int* i) { - unsafe void M(int* i) - { - if (i != null) - i->ToString(); - } + if (i != null) + i->ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63557")] - public async Task TestNotWithColorColorStaticCase() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63557")] + public async Task TestNotWithColorColorStaticCase() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class D - { - public static void StaticMethod(D d) { } - public void InstanceMethod(D d) { } - } + class D + { + public static void StaticMethod(D d) { } + public void InstanceMethod(D d) { } + } - public class C - { - D D { get; } + public class C + { + D D { get; } - public void Test() + public void Test() + { + if (D != null) { - if (D != null) - { - D.StaticMethod(D); - } + D.StaticMethod(D); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63557")] - public async Task TestWithColorColorInstanceCase() - { - await TestInRegularAndScript1Async( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/63557")] + public async Task TestWithColorColorInstanceCase() + { + await TestInRegularAndScript1Async( + """ + using System; - class D - { - public static void Method(D d) { } - public void InstanceMethod(D d) { } - } + class D + { + public static void Method(D d) { } + public void InstanceMethod(D d) { } + } - public class C - { - D D { get; } + public class C + { + D D { get; } - public void Test() + public void Test() + { + [|if|] (D != null) { - [|if|] (D != null) - { - D.InstanceMethod(D); - } + D.InstanceMethod(D); } } - """, - """ - using System; + } + """, + """ + using System; - class D - { - public static void Method(D d) { } - public void InstanceMethod(D d) { } - } + class D + { + public static void Method(D d) { } + public void InstanceMethod(D d) { } + } - public class C - { - D D { get; } + public class C + { + D D { get; } - public void Test() - { - D?.InstanceMethod(D); - } + public void Test() + { + D?.InstanceMethod(D); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53860")] - public async Task TestWithMethodGroupReference() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53860")] + public async Task TestWithMethodGroupReference() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class C - { - Action M(List p) => p is null ? null : p.Add; - } - """); - } + class C + { + Action M(List p) => p is null ? null : p.Add; + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] - public async Task TestElseIfStatement1() - { - await TestInRegularAndScript1Async(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] + public async Task TestElseIfStatement1() + { + await TestInRegularAndScript1Async(""" + class C + { + void M(string s) { - void M(string s) + if (true) + { + } + else [|if|] (s != null) { - if (true) - { - } - else [|if|] (s != null) - { - s.ToString(); - } + s.ToString(); } } - """, """ - class C + } + """, """ + class C + { + void M(string s) { - void M(string s) + if (true) + { + } + else { - if (true) - { - } - else - { - s?.ToString(); - } + s?.ToString(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] - public async Task TestElseIfStatement2() - { - await TestInRegularAndScript1Async(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] + public async Task TestElseIfStatement2() + { + await TestInRegularAndScript1Async(""" + class C + { + void M(string s) { - void M(string s) + if (true) { - if (true) - { - } - else [|if|] (s != null) - s.ToString(); } + else [|if|] (s != null) + s.ToString(); } - """, """ - class C + } + """, """ + class C + { + void M(string s) { - void M(string s) + if (true) { - if (true) - { - } - else - s?.ToString(); } + else + s?.ToString(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] - public async Task TestElseIfStatement_Trivia() - { - await TestInRegularAndScript1Async(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] + public async Task TestElseIfStatement_Trivia() + { + await TestInRegularAndScript1Async(""" + class C + { + void M(string s) { - void M(string s) + if (true) { - if (true) - { - } - else [|if|] (s != null) - { - // comment - s.ToString(); - } + } + else [|if|] (s != null) + { + // comment + s.ToString(); } } - """, """ - class C + } + """, """ + class C + { + void M(string s) { - void M(string s) + if (true) + { + } + else { - if (true) - { - } - else - { - // comment - s?.ToString(); - } + // comment + s?.ToString(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] - public async Task TestElseIfStatement_KeepBracePlacementStyle() - { - await TestInRegularAndScript1Async(""" - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66036")] + public async Task TestElseIfStatement_KeepBracePlacementStyle() + { + await TestInRegularAndScript1Async(""" + class C + { + void M(string s) { - void M(string s) + if (true) { - if (true) - { - } - else [|if|] (s != null) { - s.ToString(); - } + } + else [|if|] (s != null) { + s.ToString(); } } - """, """ - class C + } + """, """ + class C + { + void M(string s) { - void M(string s) + if (true) { - if (true) - { - } - else { - s?.ToString(); - } + } + else { + s?.ToString(); } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseObjectInitializer/UseObjectInitializerTests.cs b/src/Analyzers/CSharp/Tests/UseObjectInitializer/UseObjectInitializerTests.cs index 6450541ea6d43..8a81aa0efa2b9 100644 --- a/src/Analyzers/CSharp/Tests/UseObjectInitializer/UseObjectInitializerTests.cs +++ b/src/Analyzers/CSharp/Tests/UseObjectInitializer/UseObjectInitializerTests.cs @@ -11,1119 +11,1118 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseObjectInitializer -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseObjectInitializerDiagnosticAnalyzer, - CSharpUseObjectInitializerCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseObjectInitializer; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseObjectInitializerDiagnosticAnalyzer, + CSharpUseObjectInitializerCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseObjectInitializer)] - public partial class UseObjectInitializerTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseObjectInitializer)] +public partial class UseObjectInitializerTests +{ + private static async Task TestInRegularAndScriptAsync(string testCode, string fixedCode, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary) { - private static async Task TestInRegularAndScriptAsync(string testCode, string fixedCode, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary) + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = testCode, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp12, - TestState = { OutputKind = outputKind } - }.RunAsync(); - } + TestCode = testCode, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp12, + TestState = { OutputKind = outputKind } + }.RunAsync(); + } - private static async Task TestMissingInRegularAndScriptAsync(string testCode, LanguageVersion? languageVersion = null) + private static async Task TestMissingInRegularAndScriptAsync(string testCode, LanguageVersion? languageVersion = null) + { + var test = new VerifyCS.Test { - var test = new VerifyCS.Test - { - TestCode = testCode, - FixedCode = testCode, - }; + TestCode = testCode, + FixedCode = testCode, + }; - if (languageVersion != null) - test.LanguageVersion = languageVersion.Value; + if (languageVersion != null) + test.LanguageVersion = languageVersion.Value; - await test.RunAsync(); - } + await test.RunAsync(); + } - [Fact] - public async Task TestOnVariableDeclarator() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestOnVariableDeclarator() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + + void M() { - int i; + var c = [|new|] C(); + [|c.|]i = 1; + } + } + """, + """ + class C + { + int i; - void M() + void M() + { + var c = new C { - var c = [|new|] C(); - [|c.|]i = 1; - } + i = 1 + }; } - """, - """ - class C + } + """); + } + + [Fact] + public async Task TestNotForField1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C c = new C(); + } + """); + } + + [Fact] + public async Task TestNotForField2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C c = new C() { }; + } + """); + } + + [Fact] + public async Task TestNotForField3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C c = new C { }; + } + """); + } + + [Fact] + public async Task TestNotForField4() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int P; + C c = new C() { P = 1 }; + } + """); + } + + [Fact] + public async Task TestNotForField5() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int P; + C c = new C { P = 1 }; + } + """); + } + + [Fact] + public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue1Async() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + + void M() { - int i; + var c = [|new|] C(); + [|c.|]i = 1; + c.i = c.i + 1; + } + } + """, + """ + class C + { + int i; - void M() + void M() + { + var c = new C { - var c = new C - { - i = 1 - }; - } + i = 1 + }; + c.i = c.i + 1; } - """); - } + } + """); + } - [Fact] - public async Task TestNotForField1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue2Async() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int i; + + void M() { - C c = new C(); + var c = new C(); + c.i = c.i + 1; } - """); - } + } + """); + } - [Fact] - public async Task TestNotForField2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue3Async() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + + void M() { - C c = new C() { }; + C c; + c = [|new|] C(); + [|c.|]i = 1; + c.i = c.i + 1; } - """); - } + } + """, + """ + class C + { + int i; - [Fact] - public async Task TestNotForField3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M() { - C c = new C { }; + C c; + c = new C + { + i = 1 + }; + c.i = c.i + 1; } - """); - } + } + """); + } - [Fact] - public async Task TestNotForField4() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue4Async() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int i; + + void M() { - int P; - C c = new C() { P = 1 }; + C c; + c = new C(); + c.i = c.i + 1; } - """); - } + } + """); + } - [Fact] - public async Task TestNotForField5() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestOnAssignmentExpression() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + + void M() { - int P; - C c = new C { P = 1 }; + C c = null; + c = [|new|] C(); + [|c.|]i = 1; } - """); - } + } + """, + """ + class C + { + int i; - [Fact] - public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue1Async() - { - await TestInRegularAndScriptAsync( - """ - class C + void M() { - int i; - - void M() + C c = null; + c = new C { - var c = [|new|] C(); - [|c.|]i = 1; - c.i = c.i + 1; - } + i = 1 + }; } - """, - """ - class C - { - int i; + } + """); + } - void M() - { - var c = new C - { - i = 1 - }; - c.i = c.i + 1; - } - } - """); - } + [Fact] + public async Task TestStopOnDuplicateMember() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; - [Fact] - public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue2Async() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M() { - int i; - - void M() - { - var c = new C(); - c.i = c.i + 1; - } + var c = [|new|] C(); + [|c.|]i = 1; + c.i = 2; } - """); - } + } + """, + """ + class C + { + int i; - [Fact] - public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue3Async() - { - await TestInRegularAndScriptAsync( - """ - class C + void M() { - int i; - - void M() + var c = new C { - C c; - c = [|new|] C(); - [|c.|]i = 1; - c.i = c.i + 1; - } + i = 1 + }; + c.i = 2; } - """, - """ - class C - { - int i; + } + """); + } - void M() - { - C c; - c = new C - { - i = 1 - }; - c.i = c.i + 1; - } - } - """); - } + [Fact] + public async Task TestComplexInitializer() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - [Fact] - public async Task TestDoNotUpdateAssignmentThatReferencesInitializedValue4Async() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M(C[] array) { - int i; - - void M() - { - C c; - c = new C(); - c.i = c.i + 1; - } + array[0] = [|new|] C(); + [|array[0].|]i = 1; + [|array[0].|]j = 2; } - """); - } + } + """, + """ + class C + { + int i; + int j; - [Fact] - public async Task TestOnAssignmentExpression() - { - await TestInRegularAndScriptAsync( - """ - class C + void M(C[] array) { - int i; - - void M() + array[0] = new C { - C c = null; - c = [|new|] C(); - [|c.|]i = 1; - } + i = 1, + j = 2 + }; } - """, - """ - class C - { - int i; + } + """); + } - void M() - { - C c = null; - c = new C - { - i = 1 - }; - } - } - """); - } + [Fact] + public async Task TestNotOnCompoundAssignment() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - [Fact] - public async Task TestStopOnDuplicateMember() - { - await TestInRegularAndScriptAsync( - """ - class C + void M() { - int i; - - void M() - { - var c = [|new|] C(); - [|c.|]i = 1; - c.i = 2; - } + var c = [|new|] C(); + [|c.|]i = 1; + c.j += 1; } - """, - """ - class C - { - int i; + } + """, + """ + class C + { + int i; + int j; - void M() + void M() + { + var c = new C { - var c = new C - { - i = 1 - }; - c.i = 2; - } + i = 1 + }; + c.j += 1; } - """); - } + } + """); + } - [Fact] - public async Task TestComplexInitializer() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int i; - int j; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39146")] + public async Task TestWithExistingInitializer() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - void M(C[] array) - { - array[0] = [|new|] C(); - [|array[0].|]i = 1; - [|array[0].|]j = 2; - } - } - """, - """ - class C + void M() { - int i; - int j; - - void M(C[] array) - { - array[0] = new C - { - i = 1, - j = 2 - }; - } + var c = [|new|] C() { i = 1 }; + [|c.|]j = 1; } - """); - } + } + """, + """ + class C + { + int i; + int j; - [Fact] - public async Task TestNotOnCompoundAssignment() - { - await TestInRegularAndScriptAsync( - """ - class C + void M() { - int i; - int j; - - void M() + var c = [||]new C { - var c = [|new|] C(); - [|c.|]i = 1; - c.j += 1; - } + i = 1, + j = 1 + }; } - """, - """ - class C - { - int i; - int j; + } + """); + } - void M() - { - var c = new C - { - i = 1 - }; - c.j += 1; - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39146")] + public async Task TestWithExistingInitializerComma() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39146")] - public async Task TestWithExistingInitializer() - { - await TestInRegularAndScriptAsync( - """ - class C + void M() { - int i; - int j; - - void M() + var c = [|new|] C() { - var c = [|new|] C() { i = 1 }; - [|c.|]j = 1; - } + i = 1, + }; + [|c.|]j = 1; } - """, - """ - class C - { - int i; - int j; + } + """, + """ + class C + { + int i; + int j; - void M() + void M() + { + var c = [||]new C { - var c = [||]new C - { - i = 1, - j = 1 - }; - } + i = 1, + j = 1 + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39146")] - public async Task TestWithExistingInitializerComma() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int i; - int j; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39146")] + public async Task TestWithExistingInitializerNotIfAlreadyInitialized() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - void M() - { - var c = [|new|] C() - { - i = 1, - }; - [|c.|]j = 1; - } - } - """, - """ - class C + void M() { - int i; - int j; - - void M() + var c = [|new|] C() { - var c = [||]new C - { - i = 1, - j = 1 - }; - } + i = 1, + }; + [|c.|]j = 1; + c.i = 2; } - """); - } + } + """, + """ + class C + { + int i; + int j; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39146")] - public async Task TestWithExistingInitializerNotIfAlreadyInitialized() - { - await TestInRegularAndScriptAsync( - """ - class C + void M() { - int i; - int j; - - void M() + var c = [||]new C { - var c = [|new|] C() - { - i = 1, - }; - [|c.|]j = 1; - c.i = 2; - } + i = 1, + j = 1 + }; + c.i = 2; } - """, - """ - class C - { - int i; - int j; + } + """); + } - void M() - { - var c = [||]new C - { - i = 1, - j = 1 - }; - c.i = 2; - } - } - """); - } + [Fact] + public async Task TestMissingBeforeCSharp3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - [Fact] - public async Task TestMissingBeforeCSharp3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + void M() { - int i; - int j; - - void M() - { - C c = new C(); - c.j = 1; - } + C c = new C(); + c.j = 1; } - """, LanguageVersion.CSharp2); - } + } + """, LanguageVersion.CSharp2); + } - [Fact] - public async Task TestFixAllInDocument1() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int i; - int j; + [Fact] + public async Task TestFixAllInDocument1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - public C() { } - public C(System.Action a) { } + public C() { } + public C(System.Action a) { } - void M() - { - var v = [|new|] C(() => { - var v2 = [|new|] C(); - [|v2.|]i = 1; - }); - [|v.|]j = 2; - } - } - """, - """ - class C + void M() { - int i; - int j; + var v = [|new|] C(() => { + var v2 = [|new|] C(); + [|v2.|]i = 1; + }); + [|v.|]j = 2; + } + } + """, + """ + class C + { + int i; + int j; - public C() { } - public C(System.Action a) { } + public C() { } + public C(System.Action a) { } - void M() + void M() + { + var v = new C(() => { - var v = new C(() => + var v2 = new C { - var v2 = new C - { - i = 1 - }; - }) - { - j = 2 + i = 1 }; - } + }) + { + j = 2 + }; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAllInDocument2() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int i; - System.Action j; + [Fact] + public async Task TestFixAllInDocument2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + System.Action j; - void M() - { - var v = [|new|] C(); - [|v.|]j = () => { - var v2 = [|new|] C(); - [|v2.|]i = 1; - }; - } - } - """, - """ - class C + void M() { - int i; - System.Action j; + var v = [|new|] C(); + [|v.|]j = () => { + var v2 = [|new|] C(); + [|v2.|]i = 1; + }; + } + } + """, + """ + class C + { + int i; + System.Action j; - void M() + void M() + { + var v = new C { - var v = new C + j = () => { - j = () => + var v2 = new C { - var v2 = new C - { - i = 1 - }; - } - }; - } + i = 1 + }; + } + }; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAllInDocument3() - { - await TestInRegularAndScriptAsync( - """ - class C - { - int i; - int j; + [Fact] + public async Task TestFixAllInDocument3() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; - void M(C[] array) - { - array[0] = [|new|] C(); - [|array[0].|]i = 1; - [|array[0].|]j = 2; - array[1] = [|new|] C(); - [|array[1].|]i = 3; - [|array[1].|]j = 4; - } - } - """, - """ - class C + void M(C[] array) { - int i; - int j; + array[0] = [|new|] C(); + [|array[0].|]i = 1; + [|array[0].|]j = 2; + array[1] = [|new|] C(); + [|array[1].|]i = 3; + [|array[1].|]j = 4; + } + } + """, + """ + class C + { + int i; + int j; - void M(C[] array) + void M(C[] array) + { + array[0] = new C { - array[0] = new C - { - i = 1, - j = 2 - }; - array[1] = new C - { - i = 3, - j = 4 - }; - } + i = 1, + j = 2 + }; + array[1] = new C + { + i = 3, + j = 4 + }; } - """); - } - - [Fact] - public async Task TestTrivia1() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """); + } + + [Fact] + public async Task TestTrivia1() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; + void M() { - int i; - int j; - void M() - { - var c = [|new|] C(); - [|c.|]i = 1; // Goo - [|c.|]j = 2; // Bar - } + var c = [|new|] C(); + [|c.|]i = 1; // Goo + [|c.|]j = 2; // Bar } - """, - """ - class C + } + """, + """ + class C + { + int i; + int j; + void M() { - int i; - int j; - void M() + var c = new C { - var c = new C - { - i = 1, // Goo - j = 2 // Bar - }; - } + i = 1, // Goo + j = 2 // Bar + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46670")] - public async Task TestTriviaRemoveLeadingBlankLinesForFirstProperty() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46670")] + public async Task TestTriviaRemoveLeadingBlankLinesForFirstProperty() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; + int j; + void M() { - int i; - int j; - void M() - { - var c = [|new|] C(); + var c = [|new|] C(); - //Goo - [|c.|]i = 1; + //Goo + [|c.|]i = 1; - //Bar - [|c.|]j = 2; - } + //Bar + [|c.|]j = 2; } - """, - """ - class C + } + """, + """ + class C + { + int i; + int j; + void M() { - int i; - int j; - void M() + var c = new C { - var c = new C - { - //Goo - i = 1, + //Goo + i = 1, - //Bar - j = 2 - }; - } + //Bar + j = 2 + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15459")] - public async Task TestMissingInNonTopLevelObjectInitializer() - { - await TestMissingInRegularAndScriptAsync( - """ - class C { - int a; - C Add(int x) { - var c = Add(new int()); - c.a = 1; - return c; - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15459")] + public async Task TestMissingInNonTopLevelObjectInitializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class C { + int a; + C Add(int x) { + var c = Add(new int()); + c.a = 1; + return c; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17853")] - public async Task TestMissingForDynamic() - { - await TestMissingInRegularAndScriptAsync( - """ - using System.Dynamic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17853")] + public async Task TestMissingForDynamic() + { + await TestMissingInRegularAndScriptAsync( + """ + using System.Dynamic; - class C + class C + { + void Goo() { - void Goo() - { - dynamic body = new ExpandoObject(); - body.content = new ExpandoObject(); - } + dynamic body = new ExpandoObject(); + body.content = new ExpandoObject(); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17953")] - public async Task TestMissingAcrossPreprocessorDirective() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Goo + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17953")] + public async Task TestMissingAcrossPreprocessorDirective() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Goo + { + public void M() { - public void M() - { - var goo = new Goo(); - #if true - goo.Value = ""; - #endif - } - - public string Value { get; set; } + var goo = new Goo(); + #if true + goo.Value = ""; + #endif } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17953")] - public async Task TestAvailableInsidePreprocessorDirective() - { - await TestInRegularAndScriptAsync( - """ - public class Goo - { - public void M() - { - #if true - var goo = [|new|] Goo(); - [|goo.|]Value = ""; - #endif - } + public string Value { get; set; } + } + """); + } - public string Value { get; set; } - } - """, - """ - public class Goo + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17953")] + public async Task TestAvailableInsidePreprocessorDirective() + { + await TestInRegularAndScriptAsync( + """ + public class Goo + { + public void M() { - public void M() - { - #if true - var goo = new Goo - { - Value = "" - }; - #endif - } - - public string Value { get; set; } + #if true + var goo = [|new|] Goo(); + [|goo.|]Value = ""; + #endif } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19253")] - public async Task TestKeepBlankLinesAfter() - { - await TestInRegularAndScriptAsync( - """ - class Goo + public string Value { get; set; } + } + """, + """ + public class Goo + { + public void M() { - public int Bar { get; set; } + #if true + var goo = new Goo + { + Value = "" + }; + #endif } - class MyClass - { - public void Main() - { - var goo = [|new|] Goo(); - [|goo.|]Bar = 1; + public string Value { get; set; } + } + """); + } - int horse = 1; - } - } - """, - """ - class Goo + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19253")] + public async Task TestKeepBlankLinesAfter() + { + await TestInRegularAndScriptAsync( + """ + class Goo + { + public int Bar { get; set; } + } + + class MyClass + { + public void Main() { - public int Bar { get; set; } + var goo = [|new|] Goo(); + [|goo.|]Bar = 1; + + int horse = 1; } + } + """, + """ + class Goo + { + public int Bar { get; set; } + } - class MyClass + class MyClass + { + public void Main() { - public void Main() + var goo = new Goo { - var goo = new Goo - { - Bar = 1 - }; + Bar = 1 + }; - int horse = 1; - } + int horse = 1; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23368")] - public async Task TestWithExplicitImplementedInterfaceMembers1() - { - await TestMissingInRegularAndScriptAsync( - """ - interface IExample { - string Name { get; set; } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23368")] + public async Task TestWithExplicitImplementedInterfaceMembers1() + { + await TestMissingInRegularAndScriptAsync( + """ + interface IExample { + string Name { get; set; } + } - class C : IExample { - string IExample.Name { get; set; } - } + class C : IExample { + string IExample.Name { get; set; } + } - class MyClass + class MyClass + { + public void Main() { - public void Main() - { - IExample e = new C(); - e.Name = string.Empty; - } + IExample e = new C(); + e.Name = string.Empty; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23368")] - public async Task TestWithExplicitImplementedInterfaceMembers2() - { - await TestMissingInRegularAndScriptAsync( - """ - interface IExample { - string Name { get; set; } - string LastName { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23368")] + public async Task TestWithExplicitImplementedInterfaceMembers2() + { + await TestMissingInRegularAndScriptAsync( + """ + interface IExample { + string Name { get; set; } + string LastName { get; set; } + } + + class C : IExample { + string IExample.Name { get; set; } + public string LastName { get; set; } + } + + class MyClass + { + public void Main() + { + IExample e = new C(); + e.Name = string.Empty; + e.LastName = string.Empty; } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23368")] + public async Task TestWithExplicitImplementedInterfaceMembers3() + { + await TestInRegularAndScriptAsync( + """ + interface IExample { + string Name { get; set; } + string LastName { get; set; } + } + + class C : IExample { + string IExample.Name { get; set; } + public string LastName { get; set; } + } - class C : IExample { - string IExample.Name { get; set; } - public string LastName { get; set; } + class MyClass + { + public void Main() + { + IExample e = [|new|] C(); + [|e.|]LastName = string.Empty; + e.Name = string.Empty; } + } + """, + """ + interface IExample { + string Name { get; set; } + string LastName { get; set; } + } + + class C : IExample { + string IExample.Name { get; set; } + public string LastName { get; set; } + } - class MyClass + class MyClass + { + public void Main() { - public void Main() + IExample e = new C { - IExample e = new C(); - e.Name = string.Empty; - e.LastName = string.Empty; - } + LastName = string.Empty + }; + e.Name = string.Empty; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23368")] - public async Task TestWithExplicitImplementedInterfaceMembers3() - { - await TestInRegularAndScriptAsync( - """ - interface IExample { - string Name { get; set; } - string LastName { get; set; } - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37675")] + public async Task TestDoNotOfferForUsingDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + class C : System.IDisposable + { + int i; - class C : IExample { - string IExample.Name { get; set; } - public string LastName { get; set; } + void M() + { + using var c = new C(); + c.i = 1; } - class MyClass + public void Dispose() { - public void Main() - { - IExample e = [|new|] C(); - [|e.|]LastName = string.Empty; - e.Name = string.Empty; - } - } - """, - """ - interface IExample { - string Name { get; set; } - string LastName { get; set; } } + } + """); + } + + [Fact] + public async Task TestImplicitObject() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int i; - class C : IExample { - string IExample.Name { get; set; } - public string LastName { get; set; } + void M() + { + C c = [|new|](); + [|c.|]i = 1; } + } + """, + """ + class C + { + int i; - class MyClass + void M() { - public void Main() + C c = new() { - IExample e = new C - { - LastName = string.Empty - }; - e.Name = string.Empty; - } + i = 1 + }; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37675")] - public async Task TestDoNotOfferForUsingDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - class C : System.IDisposable - { - int i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61066")] + public async Task TestInTopLevelStatements() + { + await TestInRegularAndScriptAsync( + """ + MyClass cl = [|new|](); + [|cl.|]MyProperty = 5; - void M() - { - using var c = new C(); - c.i = 1; - } + class MyClass + { + public int MyProperty { get; set; } + } + """, + """ + MyClass cl = new() + { + MyProperty = 5 + }; - public void Dispose() - { - } - } - """); - } + class MyClass + { + public int MyProperty { get; set; } + } + """, OutputKind.ConsoleApplication); + } + + [Theory] + [InlineData(8.0)] + [InlineData(9.0)] + [WorkItem("https://github.com/dotnet/roslyn/issues/72094")] + public async Task TestWithConflictingSeverityConfigurationEntries(double analysisLevel) + { + var expectFix = analysisLevel >= 9.0; - [Fact] - public async Task TestImplicitObject() + string testCode, fixedCode; + if (expectFix) { - await TestInRegularAndScriptAsync( + testCode = """ class C { int i; - + void M() { - C c = [|new|](); - [|c.|]i = 1; + var c = [|new|] C(); + c.i = 1; } } - """, + """; + + fixedCode = """ class C { int i; - + void M() { - C c = new() + var c = new C { i = 1 }; } } - """); + """; } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/61066")] - public async Task TestInTopLevelStatements() + else { - await TestInRegularAndScriptAsync( - """ - MyClass cl = [|new|](); - [|cl.|]MyProperty = 5; - - class MyClass - { - public int MyProperty { get; set; } - } - """, + testCode = """ - MyClass cl = new() - { - MyProperty = 5 - }; - - class MyClass + class C { - public int MyProperty { get; set; } - } - """, OutputKind.ConsoleApplication); - } - - [Theory] - [InlineData(8.0)] - [InlineData(9.0)] - [WorkItem("https://github.com/dotnet/roslyn/issues/72094")] - public async Task TestWithConflictingSeverityConfigurationEntries(double analysisLevel) - { - var expectFix = analysisLevel >= 9.0; - - string testCode, fixedCode; - if (expectFix) - { - testCode = - """ - class C - { - int i; - - void M() - { - var c = [|new|] C(); - c.i = 1; - } - } - """; - - fixedCode = - """ - class C - { - int i; - - void M() - { - var c = new C - { - i = 1 - }; - } - } - """; - } - else - { - testCode = - """ - class C + int i; + + void M() { - int i; - - void M() - { - var c = new C(); - c.i = 1; - } + var c = new C(); + c.i = 1; } - """; - fixedCode = testCode; - } + } + """; + fixedCode = testCode; + } - var globalConfig = - $""" - is_global = true + var globalConfig = + $""" + is_global = true - dotnet_style_object_initializer = true:suggestion - dotnet_diagnostic.IDE0017.severity = none + dotnet_style_object_initializer = true:suggestion + dotnet_diagnostic.IDE0017.severity = none - build_property.EffectiveAnalysisLevelStyle = {analysisLevel} - """; + build_property.EffectiveAnalysisLevelStyle = {analysisLevel} + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestState = { - TestState = + Sources = { testCode }, + AnalyzerConfigFiles = { - Sources = { testCode }, - AnalyzerConfigFiles = - { - ("/.globalconfig", globalConfig), - } - }, - FixedState = { Sources = { fixedCode } }, - LanguageVersion = LanguageVersion.CSharp12, - }.RunAsync(); - } + ("/.globalconfig", globalConfig), + } + }, + FixedState = { Sources = { fixedCode } }, + LanguageVersion = LanguageVersion.CSharp12, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndMemberAccessTests.cs b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndMemberAccessTests.cs index 0325df093e917..a8abf3c3d92cc 100644 --- a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndMemberAccessTests.cs +++ b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndMemberAccessTests.cs @@ -11,825 +11,853 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpAsAndMemberAccessDiagnosticAnalyzer, - CSharpAsAndMemberAccessCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpAsAndMemberAccessDiagnosticAnalyzer, + CSharpAsAndMemberAccessCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternMatchingForAsAndMemberAccess)] - public partial class CSharpAsAndMemberAccessTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternMatchingForAsAndMemberAccess)] +public partial class CSharpAsAndMemberAccessTests +{ + [Fact] + public async Task TestCoreCase() { - [Fact] - public async Task TestCoreCase() + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - void M(object o) - { - if (([|o as string|])?.Length == 0) - { - } - } - } - """, - FixedCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + if (([|o as string|])?.Length == 0) { - if (o is string { Length: 0 }) - { - } } } - """, - }.RunAsync(); - } - - [Fact] - public async Task TestNotInCSharp7() - { - var test = """ + } + """, + FixedCode = """ class C { void M(object o) { - if ((o as string)?.Length == 0) + if (o is string { Length: 0 }) { } } } - """; - await new VerifyCS.Test + """, + }.RunAsync(); + } + + [Fact] + public async Task TestNotInCSharp7() + { + var test = """ + class C { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithNonConstant() - { - var test = """ - class C + void M(object o) { - void M(object o, int length) + if ((o as string)?.Length == 0) { - if ((o as string)?.Length == length) - { - } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithoutTest() + } + """; + await new VerifyCS.Test { - var test = """ - class C + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithNonConstant() + { + var test = """ + class C + { + void M(object o, int length) { - void M(object o, int length) + if ((o as string)?.Length == length) { - var v = (o as string)?.Length; } } - """; - await new VerifyCS.Test + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithoutTest() + { + var test = """ + class C { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } - - [Fact] - public async Task TestNotWithNonMemberBinding1() + void M(object o, int length) + { + var v = (o as string)?.Length; + } + } + """; + await new VerifyCS.Test { - var test = """ - class C + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } + + [Fact] + public async Task TestNotWithNonMemberBinding1() + { + var test = """ + class C + { + C[] X; + int Length; + + void M(object o, int length) { - C[] X; - int Length; + if ((o as C)?.X[0].Length == 0) + { + } + } + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp7, + }.RunAsync(); + } - void M(object o, int length) + [Fact] + public async Task TestNotEqualsConstant_CSharp8() + { + var test = """ + class C + { + void M(object o) + { + if ((o as string)?.Length != 0) { - if ((o as C)?.X[0].Length == 0) - { - } } } - """; - await new VerifyCS.Test + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsConstant_CSharp9() + { + var test = """ + class C { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp7, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsConstant_CSharp8() + void M(object o) + { + if ((o as string)?.Length != 0) + { + } + } + } + """; + await new VerifyCS.Test { - var test = """ - class C + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_ValueType_CSharp8() + { + var test = """ + class C + { + void M(object o) { - void M(object o) + if ((o as string)?.Length != null) { - if ((o as string)?.Length != 0) - { - } } } - """; - await new VerifyCS.Test + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_ValueType_CSharp9() + { + var test = """ + class C { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsConstant_CSharp9() + void M(object o) + { + if ((o as string)?.Length != null) + { + } + } + } + """; + await new VerifyCS.Test { - var test = """ - class C + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_ValueType2_CSharp9() + { + var test = """ + class C + { + C X; + int Length; + + void M(object o) { - void M(object o) + if ((o as C)?.X.Length != null) { - if ((o as string)?.Length != 0) - { - } } } - """; - await new VerifyCS.Test + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_ReferenceType_CSharp8() + { + var test = """ + class C { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_ValueType_CSharp8() + string X; + + void M(object o) + { + if ((o as C)?.X != null) + { + } + } + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_ReferenceType_CSharp9() + { + await new VerifyCS.Test { - var test = """ + TestCode = """ class C { + string X; + void M(object o) { - if ((o as string)?.Length != null) + if (([|o as C|])?.X != null) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_ValueType_CSharp9() - { - var test = """ + """, + FixedCode = """ class C { + string X; + void M(object o) { - if ((o as string)?.Length != null) + if (o is C { X: not null }) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_ValueType2_CSharp9() + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_ReferenceType_CSharp10() + { + await new VerifyCS.Test { - var test = """ + TestCode = """ class C { - C X; - int Length; - + C Y; + string X; + void M(object o) { - if ((o as C)?.X.Length != null) + if (([|o as C|])?.Y.X != null) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_ReferenceType_CSharp8() - { - var test = """ + """, + FixedCode = """ class C { + C Y; string X; void M(object o) { - if ((o as C)?.X != null) + if (o is C { Y.X: not null }) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_ReferenceType_CSharp9() - { - await new VerifyCS.Test + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_NullableType_CSharp8() + { + var test = """ + class C { - TestCode = """ - class C - { - string X; - - void M(object o) - { - if (([|o as C|])?.X != null) - { - } - } - } - """, - FixedCode = """ - class C - { - string X; + int? X; - void M(object o) - { - if (o is C { X: not null }) - { - } - } + void M(object o) + { + if ((o as C)?.X != null) + { } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_ReferenceType_CSharp10() + } + } + """; + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestNotEqualsNull_NullableType2_CSharp8() + { + var test = """ + class C { - TestCode = """ - class C - { - C Y; - string X; - - void M(object o) - { - if (([|o as C|])?.Y.X != null) - { - } - } - } - """, - FixedCode = """ - class C - { - C Y; - string X; + int? X; - void M(object o) - { - if (o is C { Y.X: not null }) - { - } - } + void M(object o) + { + if ((o as C)?.X != null) + { } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - [Fact] - public async Task TestNotEqualsNull_NullableType_CSharp8() + [Fact] + public async Task TestNotEqualsNull_NullableType_CSharp10() + { + await new VerifyCS.Test { - var test = """ + TestCode = """ class C { + C Y; int? X; - + void M(object o) { - if ((o as C)?.X != null) + if (([|o as C|])?.Y.X != null) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_NullableType2_CSharp8() - { - var test = """ + """, + FixedCode = """ class C { + C Y; int? X; void M(object o) { - if ((o as C)?.X != null) + if (o is C { Y.X: not null }) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } - - [Fact] - public async Task TestNotEqualsNull_NullableType_CSharp10() + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } + + [Fact] + public async Task TestGreaterThan() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - C Y; - int? X; - - void M(object o) + if (([|o as string|])?.Length > 0) { - if (([|o as C|])?.Y.X != null) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - C Y; - int? X; - - void M(object o) + if (o is string { Length: > 0 }) { - if (o is C { Y.X: not null }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestGreaterThan() + [Fact] + public async Task TestGreaterThanEquals() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + if (([|o as string|])?.Length >= 0) { - if (([|o as string|])?.Length > 0) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + if (o is string { Length: >= 0 }) { - if (o is string { Length: > 0 }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestGreaterThanEquals() + [Fact] + public async Task TestLessThan() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + int Goo; + + void M(object o) { - void M(object o) + if (([|o as C|])?.Goo < 0) { - if (([|o as string|])?.Length >= 0) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + int Goo; + + void M(object o) { - void M(object o) + if (o is C { Goo: < 0 }) { - if (o is string { Length: >= 0 }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestLessThan() + [Fact] + public async Task TestLessThanEquals() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - int Goo; - - void M(object o) + if (([|o as string|])?.Length <= 0) { - if (([|o as C|])?.Goo < 0) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - int Goo; - - void M(object o) + if (o is string { Length: <= 0 }) { - if (o is C { Goo: < 0 }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestLessThanEquals() + [Fact] + public async Task TestIsConstantPattern1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + if (([|o as string|])?.Length is 0) { - if (([|o as string|])?.Length <= 0) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + if (o is string { Length: 0 }) { - if (o is string { Length: <= 0 }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact] - public async Task TestIsConstantPattern1() - { - await new VerifyCS.Test + [Fact] + public async Task TestIsNotConstantPattern() + { + var test = """ + class C { - TestCode = """ - class C + void M(object o) + { + if ((o as string)?.Length is not 0) { - void M(object o) - { - if (([|o as string|])?.Length is 0) - { - } - } } - """, - FixedCode = """ - class C + } + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestIsNullPattern() + { + var test = """ + class C + { + void M(object o) + { + if ((o as string)?.Length is null) { - void M(object o) - { - if (o is string { Length: 0 }) - { - } - } } - """, - }.RunAsync(); - } - - [Fact] - public async Task TestIsNotConstantPattern() + } + } + """; + await new VerifyCS.Test { - var test = """ - class C + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestIsNotNullPattern_ValueType() + { + var test = """ + class C + { + void M(object o) { - void M(object o) + if ((o as string)?.Length is not null) { - if ((o as string)?.Length is not 0) - { - } } } - """; - await new VerifyCS.Test + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestIsNotNullPattern_ValueType2() + { + var test = """ + class C { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestIsNullPattern() + C X; + int Length; + + void M(object o) + { + if ((o as C)?.X.Length is not null) + { + } + } + } + """; + await new VerifyCS.Test + { + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestIsNotNullPattern_ReferenceType() + { + await new VerifyCS.Test { - var test = """ + TestCode = """ class C { + string X; + void M(object o) { - if ((o as string)?.Length is null) + if (([|o as C|])?.X is not null) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestIsNotNullPattern_ValueType() - { - var test = """ + """, + FixedCode = """ class C { + string X; + void M(object o) { - if ((o as string)?.Length is not null) + if (o is C { X: not null }) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestIsNotNullPattern_ValueType2() + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestIsNotNullPattern_ReferenceType_CSharp10() + { + await new VerifyCS.Test { - var test = """ + TestCode = """ class C { - C X; - int Length; + C Y; + string X; void M(object o) { - if ((o as C)?.X.Length is not null) + if (([|o as C|])?.Y.X is not null) { } } } - """; - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestIsNotNullPattern_ReferenceType() - { - await new VerifyCS.Test - { - TestCode = """ - class C - { - string X; + """, + FixedCode = """ + class C + { + C Y; + string X; - void M(object o) - { - if (([|o as C|])?.X is not null) - { - } - } - } - """, - FixedCode = """ - class C + void M(object o) { - string X; - - void M(object o) + if (o is C { Y.X: not null }) { - if (o is C { X: not null }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } - [Fact] - public async Task TestIsNotNullPattern_ReferenceType_CSharp10() + [Fact] + public async Task TestIsNotNullPattern_NullableValueType() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - C Y; - string X; + TestCode = """ + class C + { + int? X; - void M(object o) + void M(object o) + { + if (([|o as C|])?.X is not null) { - if (([|o as C|])?.Y.X is not null) - { - } } } - """, - FixedCode = """ - class C - { - C Y; - string X; + } + """, + FixedCode = """ + class C + { + int? X; - void M(object o) + void M(object o) + { + if (o is C { X: not null }) { - if (o is C { Y.X: not null }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact] - public async Task TestIsNotNullPattern_NullableValueType() + [Fact] + public async Task TestIsNotNullPattern_NullableValueType_CSharp10() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C - { - int? X; + TestCode = """ + class C + { + int? X; + C Y; - void M(object o) + void M(object o) + { + if (([|o as C|])?.Y.X is not null) { - if (([|o as C|])?.X is not null) - { - } } } - """, - FixedCode = """ - class C - { - int? X; + } + """, + FixedCode = """ + class C + { + int? X; + C Y; - void M(object o) + void M(object o) + { + if (o is C { Y.X: not null }) { - if (o is C { X: not null }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } - [Fact] - public async Task TestIsNotNullPattern_NullableValueType_CSharp10() - { - await new VerifyCS.Test + [Fact] + public async Task TestMemberAccess1_CSharp9() + { + var test = """ + class C { - TestCode = """ - class C - { - int? X; - C Y; + C X; + int Length; - void M(object o) - { - if (([|o as C|])?.Y.X is not null) - { - } - } - } - """, - FixedCode = """ - class C + void M(object o) + { + if ((o as C)?.X.Length == 0) { - int? X; - C Y; - - void M(object o) - { - if (o is C { Y.X: not null }) - { - } - } } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + } + """; - [Fact] - public async Task TestMemberAccess1_CSharp9() + await new VerifyCS.Test { - var test = """ + TestCode = test, + FixedCode = test, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } + + [Fact] + public async Task TestMemberAccess1_CSharp10() + { + await new VerifyCS.Test + { + TestCode = """ class C { C X; @@ -837,340 +865,311 @@ class C void M(object o) { - if ((o as C)?.X.Length == 0) + if (([|o as C|])?.X.Length == 0) { } } } - """; - - await new VerifyCS.Test - { - TestCode = test, - FixedCode = test, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } - - [Fact] - public async Task TestMemberAccess1_CSharp10() - { - await new VerifyCS.Test - { - TestCode = """ - class C - { - C X; - int Length; + """, + FixedCode = """ + class C + { + C X; + int Length; - void M(object o) - { - if (([|o as C|])?.X.Length == 0) - { - } - } - } - """, - FixedCode = """ - class C + void M(object o) { - C X; - int Length; - - void M(object o) + if (o is C { X.Length: 0 }) { - if (o is C { X.Length: 0 }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp10, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + }.RunAsync(); + } - [Fact] - public async Task TestParenthesizedParent() + [Fact] + public async Task TestParenthesizedParent() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + if ((([|o as string|])?.Length == 0) || true) { - if ((([|o as string|])?.Length == 0) || true) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + if (o is string { Length: 0 } || true) { - if (o is string { Length: 0 } || true) - { - } } } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact] - public async Task TestBinaryParent() + [Fact] + public async Task TestBinaryParent() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - class C + TestCode = """ + class C + { + void M(object o) { - void M(object o) + if (([|o as string|])?.Length == 0 && true) { - if (([|o as string|])?.Length == 0 && true) - { - } } } - """, - FixedCode = """ - class C + } + """, + FixedCode = """ + class C + { + void M(object o) { - void M(object o) + if (o is string { Length: 0 } && true) { - if (o is string { Length: 0 } && true) - { - } } } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsTypePattern() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsTypePattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (([|o as Type|])?.Name is string s) { - if (([|o as Type|])?.Name is string s) - { - } } } - """, - FixedCode = """ - using System; - class C + } + """, + FixedCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (o is Type { Name: string s }) { - if (o is Type { Name: string s }) - { - } } } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsNotTypePattern() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsNotTypePattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if ((o as Type)?.Name is not string s) { - if ((o as Type)?.Name is not string s) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsVarPattern() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsVarPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (([|o as Type|])?.Name is var s) { - if (([|o as Type|])?.Name is var s) - { - } } } - """, - FixedCode = """ - using System; - class C + } + """, + FixedCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (o is Type { Name: var s }) { - if (o is Type { Name: var s }) - { - } } } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsNotVarPattern() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsNotVarPattern() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if ({|CS8518:(o as Type)?.Name is not var s|}) { - if ({|CS8518:(o as Type)?.Name is not var s|}) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsRecursivePattern1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsRecursivePattern1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (([|o as Type|])?.Name is { }) { - if (([|o as Type|])?.Name is { }) - { - } } } - """, - FixedCode = """ - using System; - class C + } + """, + FixedCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (o is Type { Name: { } }) { - if (o is Type { Name: { } }) - { - } } } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsRecursivePattern2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsRecursivePattern2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (([|o as Type|])?.Name is { } s) { - if (([|o as Type|])?.Name is { } s) - { - } } } - """, - FixedCode = """ - using System; - class C + } + """, + FixedCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (o is Type { Name: { } s }) { - if (o is Type { Name: { } s }) - { - } } } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsNotRecursivePattern1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsNotRecursivePattern1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (([|o as Type|])?.Name is not { }) { - if (([|o as Type|])?.Name is not { }) - { - } } } - """, - FixedCode = """ - using System; - class C + } + """, + FixedCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if (o is Type { Name: not { } }) { - if (o is Type { Name: not { } }) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] - public async Task TestIsNotRecursivePattern2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67010")] + public async Task TestIsNotRecursivePattern2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; - class C + TestCode = """ + using System; + class C + { + void M(object o) { - void M(object o) + if ((o as Type)?.Name is not { } s) { - if ((o as Type)?.Name is not { } s) - { - } } } - """, - LanguageVersion = LanguageVersion.CSharp9, - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp9, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests.cs b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests.cs index 0b0f4e0e26c42..e564a53218da3 100644 --- a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests.cs +++ b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests.cs @@ -13,2130 +13,2129 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] +public partial class CSharpAsAndNullCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] - public partial class CSharpAsAndNullCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor - { - public CSharpAsAndNullCheckTests(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpAsAndNullCheckDiagnosticAnalyzer(), new CSharpAsAndNullCheckCodeFixProvider()); - - [Theory] - [InlineData("x != null", "o is string x")] - [InlineData("null != x", "o is string x")] - [InlineData("(object)x != null", "o is string x")] - [InlineData("null != (object)x", "o is string x")] - [InlineData("x is object", "o is string x")] - [InlineData("x == null", "!(o is string x)")] - [InlineData("null == x", "!(o is string x)")] - [InlineData("(object)x == null", "!(o is string x)")] - [InlineData("null == (object)x", "!(o is string x)")] - [InlineData("x is null", "!(o is string x)")] - [InlineData("(x = o as string) != null", "o is string x")] - [InlineData("null != (x = o as string)", "o is string x")] - [InlineData("(x = o as string) is object", "o is string x")] - [InlineData("(x = o as string) == null", "!(o is string x)")] - [InlineData("null == (x = o as string)", "!(o is string x)")] - [InlineData("(x = o as string) is null", "!(o is string x)")] - [InlineData("x == null", "o is not string x", LanguageVersion.CSharp9)] - public async Task InlineTypeCheck1(string input, string output, LanguageVersion version = LanguageVersion.CSharp8) - { - await TestStatement($"if ({input}) {{ }}", $"if ({output}) {{ }}", version); - await TestStatement($"var y = {input};", $"var y = {output};", version); - await TestStatement($"return {input};", $"return {output};", version); - } - - [Theory] - [InlineData("(x = o as string) != null", "o is string x")] - [InlineData("null != (x = o as string)", "o is string x")] - [InlineData("(x = o as string) is object", "o is string x")] - [InlineData("(x = o as string) == null", "!(o is string x)")] - [InlineData("null == (x = o as string)", "!(o is string x)")] - public async Task InlineTypeCheck2(string input, string output) - => await TestStatement($"while ({input}) {{ }}", $"while ({output}) {{ }}"); - - private async Task TestStatement(string input, string output, LanguageVersion version = LanguageVersion.CSharp8) - { - await TestInRegularAndScript1Async( - $$""" - class C - { - void M(object o) - { - [|var|] x = o as string; - {{input}} - } - } - """, - $$""" - class C - { - void M(object o) - { - {{output}} - } - } - """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(version))); - } - - [Fact] - public async Task TestMissingInCSharp6() - { - await TestMissingAsync( - """ - class C - { - void M() - { - [|var|] x = o as string; - if (x != null) - { - } + public CSharpAsAndNullCheckTests(ITestOutputHelper logger) + : base(logger) + { + } + + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpAsAndNullCheckDiagnosticAnalyzer(), new CSharpAsAndNullCheckCodeFixProvider()); + + [Theory] + [InlineData("x != null", "o is string x")] + [InlineData("null != x", "o is string x")] + [InlineData("(object)x != null", "o is string x")] + [InlineData("null != (object)x", "o is string x")] + [InlineData("x is object", "o is string x")] + [InlineData("x == null", "!(o is string x)")] + [InlineData("null == x", "!(o is string x)")] + [InlineData("(object)x == null", "!(o is string x)")] + [InlineData("null == (object)x", "!(o is string x)")] + [InlineData("x is null", "!(o is string x)")] + [InlineData("(x = o as string) != null", "o is string x")] + [InlineData("null != (x = o as string)", "o is string x")] + [InlineData("(x = o as string) is object", "o is string x")] + [InlineData("(x = o as string) == null", "!(o is string x)")] + [InlineData("null == (x = o as string)", "!(o is string x)")] + [InlineData("(x = o as string) is null", "!(o is string x)")] + [InlineData("x == null", "o is not string x", LanguageVersion.CSharp9)] + public async Task InlineTypeCheck1(string input, string output, LanguageVersion version = LanguageVersion.CSharp8) + { + await TestStatement($"if ({input}) {{ }}", $"if ({output}) {{ }}", version); + await TestStatement($"var y = {input};", $"var y = {output};", version); + await TestStatement($"return {input};", $"return {output};", version); + } + + [Theory] + [InlineData("(x = o as string) != null", "o is string x")] + [InlineData("null != (x = o as string)", "o is string x")] + [InlineData("(x = o as string) is object", "o is string x")] + [InlineData("(x = o as string) == null", "!(o is string x)")] + [InlineData("null == (x = o as string)", "!(o is string x)")] + public async Task InlineTypeCheck2(string input, string output) + => await TestStatement($"while ({input}) {{ }}", $"while ({output}) {{ }}"); + + private async Task TestStatement(string input, string output, LanguageVersion version = LanguageVersion.CSharp8) + { + await TestInRegularAndScript1Async( + $$""" + class C + { + void M(object o) + { + [|var|] x = o as string; + {{input}} + } + } + """, + $$""" + class C + { + void M(object o) + { + {{output}} + } + } + """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(version))); + } + + [Fact] + public async Task TestMissingInCSharp6() + { + await TestMissingAsync( + """ + class C + { + void M() + { + [|var|] x = o as string; + if (x != null) + { } } - """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task TestMissingInWrongName() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingInWrongName() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|var|] y = o as string; + if (x != null) { - [|var|] y = o as string; - if (x != null) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestInSwitchSection() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestInSwitchSection() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + switch (o) { - switch (o) - { - default: - [|var|] x = o as string; - if (x != null) - { - } - } + default: + [|var|] x = o as string; + if (x != null) + { + } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + switch (o) { - switch (o) - { - default: - if (o is string x) - { - } - } + default: + if (o is string x) + { + } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] - public async Task TestRemoveNewLinesInSwitchStatement() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] + public async Task TestRemoveNewLinesInSwitchStatement() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + switch (o) { - switch (o) - { - default: - [|var|] x = o as string; + default: + [|var|] x = o as string; - //a comment - if (x != null) - { - } - } + //a comment + if (x != null) + { + } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + switch (o) { - switch (o) - { - default: - //a comment - if (o is string x) - { - } - } + default: + //a comment + if (o is string x) + { + } } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnNonDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingOnNonDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|y|] = o as string; + if (x != null) { - [|y|] = o as string; - if (x != null) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25237")] - public async Task TestMissingOnReturnStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25237")] + public async Task TestMissingOnReturnStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() - { - [|return;|] - } + [|return;|] } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnIsExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingOnIsExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|var|] x = o is string; + if (x != null) { - [|var|] x = o is string; - if (x != null) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckComplexExpression1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckComplexExpression1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = (o ? z : w) as string; + if (x != null) { - [|var|] x = (o ? z : w) as string; - if (x != null) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if ((o ? z : w) is string x) { - if ((o ? z : w) is string x) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestInlineTypeCheckWithElse() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestInlineTypeCheckWithElse() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (null != x) + { + } + else { - [|var|] x = o as string; - if (null != x) - { - } - else - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (o is string x) + { + } + else { - if (o is string x) - { - } - else - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + // prefix comment + [|var|] x = o as string; + if (x != null) { - // prefix comment - [|var|] x = o as string; - if (x != null) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix comment + if (o is string x) { - // prefix comment - if (o is string x) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; // suffix comment + if (x != null) { - [|var|] x = o as string; // suffix comment - if (x != null) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // suffix comment + if (o is string x) { - // suffix comment - if (o is string x) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + // prefix comment + [|var|] x = o as string; // suffix comment + if (x != null) { - // prefix comment - [|var|] x = o as string; // suffix comment - if (x != null) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix comment + // suffix comment + if (o is string x) { - // prefix comment - // suffix comment - if (o is string x) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] - public async Task TestRemoveNewLines() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] + public async Task TestRemoveNewLines() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - [|var|] x = o as string; + [|var|] x = o as string; - //suffix comment - if (x != null) - { - } + //suffix comment + if (x != null) + { } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + //suffix comment + if (o is string x) { - //suffix comment - if (o is string x) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] - public async Task TestRemoveNewLinesWhereBlankLineIsNotEmpty() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] + public async Task TestRemoveNewLinesWhereBlankLineIsNotEmpty() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - [|var|] x = o as string; + [|var|] x = o as string; - //suffix comment - if (x != null) - { - } + //suffix comment + if (x != null) + { } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + //suffix comment + if (o is string x) { - //suffix comment - if (o is string x) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] - public async Task TestRemoveNewLines2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] + public async Task TestRemoveNewLines2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() - { - int a = 0; - [|var|] x = o as string; + int a = 0; + [|var|] x = o as string; - //suffix comment - if (x != null) - { - } + //suffix comment + if (x != null) + { } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() - { - int a = 0; + int a = 0; - //suffix comment - if (o is string x) - { - } + //suffix comment + if (o is string x) + { } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckComplexCondition1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckComplexCondition1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (x != null ? 0 : 1) { - [|var|] x = o as string; - if (x != null ? 0 : 1) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (o is string x ? 0 : 1) { - if (o is string x ? 0 : 1) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckComplexCondition2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckComplexCondition2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if ((x != null)) { - [|var|] x = o as string; - if ((x != null)) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if ((o is string x)) { - if ((o is string x)) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckComplexCondition3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckComplexCondition3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (x != null && x.Length > 0) { - [|var|] x = o as string; - if (x != null && x.Length > 0) - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (o is string x && x.Length > 0) { - if (o is string x && x.Length > 0) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestDefiniteAssignment1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestDefiniteAssignment1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (x != null && x.Length > 0) + { + } + else if (x != null) { - [|var|] x = o as string; - if (x != null && x.Length > 0) - { - } - else if (x != null) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestDefiniteAssignment2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestDefiniteAssignment2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (x != null && x.Length > 0) { - [|var|] x = o as string; - if (x != null && x.Length > 0) - { - } - - Console.WriteLine(x); } + + Console.WriteLine(x); } - """); - } + } + """); + } - [Fact] - public async Task TestDefiniteAssignment3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestDefiniteAssignment3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (x != null && x.Length > 0) { - [|var|] x = o as string; - if (x != null && x.Length > 0) - { - } - - x = null; - Console.WriteLine(x); } + + x = null; + Console.WriteLine(x); } - """, + } + """, - """ - class C + """ + class C + { + void M() { - void M() + if (o is string x && x.Length > 0) { - if (o is string x && x.Length > 0) - { - } - - x = null; - Console.WriteLine(x); } + + x = null; + Console.WriteLine(x); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21097")] - public async Task TestDefiniteAssignment4() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21097")] + public async Task TestDefiniteAssignment4() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - void M(object o) + [|var|] s = o as string; + if (s != null) { - [|var|] s = o as string; - if (s != null) - { - } - else - { - if (o is int?) - s = null; - s.ToString(); - } + } + else + { + if (o is int?) + s = null; + s.ToString(); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24286")] - public async Task TestDefiniteAssignment5() - { - await TestMissingInRegularAndScriptAsync( - """ - public class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24286")] + public async Task TestDefiniteAssignment5() + { + await TestMissingInRegularAndScriptAsync( + """ + public class Test + { + public void TestIt(object o1, object o2) { - public void TestIt(object o1, object o2) + [|var|] test = o1 as Test; + if (test != null || o2 != null) { - [|var|] test = o1 as Test; - if (test != null || o2 != null) - { - var o3 = test ?? o2; - } + var o3 = test ?? o2; } } - """); - } + } + """); + } - [Fact] - public async Task TestDefiniteAssignment6() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - string Use(string x) => x; + [Fact] + public async Task TestDefiniteAssignment6() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + string Use(string x) => x; - void M() + void M() + { + [|var|] x = o as string; + if (x != null && x.Length > 0) { - [|var|] x = o as string; - if (x != null && x.Length > 0) - { - } - - Console.WriteLine(x = Use(x)); } + + Console.WriteLine(x = Use(x)); } - """); - } + } + """); + } - [Fact] - public async Task TestDefiniteAssignment7() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestDefiniteAssignment7() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + [|var|] x = o as string; + if (x != null && x.Length > 0) { - [|var|] x = o as string; - if (x != null && x.Length > 0) - { - } - - Console.WriteLine(x); - x = "writeAfter"; } + + Console.WriteLine(x); + x = "writeAfter"; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28821")] - public async Task TestDefiniteAssignment8() - { - await TestMissingInRegularAndScriptAsync( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28821")] + public async Task TestDefiniteAssignment8() + { + await TestMissingInRegularAndScriptAsync( + """ + class Program + { + static void Goo(System.Activator bar) { - static void Goo(System.Activator bar) + } + + static void Main(string[] args) + { + var a = new object(); + [|var|] b = a as System.Activator; + if ((b == null) && false) { } - - static void Main(string[] args) + else { - var a = new object(); - [|var|] b = a as System.Activator; - if ((b == null) && false) - { - } - else - { - Goo(b); - } + Goo(b); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28866")] - public async Task TestWrittenExpressionBeforeNullCheck() - { - await TestMissingInRegularAndScriptAsync( - """ - class Goo - { - object Data { get; set; } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28866")] + public async Task TestWrittenExpressionBeforeNullCheck() + { + await TestMissingInRegularAndScriptAsync( + """ + class Goo + { + object Data { get; set; } - void DoGoo() - { - [|var|] oldData = this.Data as string; + void DoGoo() + { + [|var|] oldData = this.Data as string; - Data = null; + Data = null; - if (oldData != null) - { - // Do something - } + if (oldData != null) + { + // Do something } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15957")] - public async Task TestTrivia1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15957")] + public async Task TestTrivia1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object y) { - void M(object y) + if (y != null) { - if (y != null) - { - } + } - [|var|] x = o as string; - if (x != null) - { - } + [|var|] x = o as string; + if (x != null) + { } } - """, - """ - class C + } + """, + """ + class C + { + void M(object y) { - void M(object y) + if (y != null) { - if (y != null) - { - } + } - if (o is string x) - { - } + if (o is string x) + { } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17129")] - public async Task TestTrivia2() - { - await TestInRegularAndScript1Async( - """ - using System; - namespace N + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17129")] + public async Task TestTrivia2() + { + await TestInRegularAndScript1Async( + """ + using System; + namespace N + { + class Program { - class Program + public static void Main() { - public static void Main() + object o = null; + int i = 0; + [|var|] s = o as string; + if (s != null && i == 0 && i == 1 && + i == 2 && i == 3 && + i == 4 && i == 5) { - object o = null; - int i = 0; - [|var|] s = o as string; - if (s != null && i == 0 && i == 1 && - i == 2 && i == 3 && - i == 4 && i == 5) - { - Console.WriteLine(); - } + Console.WriteLine(); } } } - """, - """ - using System; - namespace N + } + """, + """ + using System; + namespace N + { + class Program { - class Program + public static void Main() { - public static void Main() + object o = null; + int i = 0; + if (o is string s && i == 0 && i == 1 && + i == 2 && i == 3 && + i == 4 && i == 5) { - object o = null; - int i = 0; - if (o is string s && i == 0 && i == 1 && - i == 2 && i == 3 && - i == 4 && i == 5) - { - Console.WriteLine(); - } + Console.WriteLine(); } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17122")] - public async Task TestMissingOnNullableType() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - namespace N + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17122")] + public async Task TestMissingOnNullableType() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + namespace N + { + class Program { - class Program + public static void Main() { - public static void Main() - { - object o = null; - [|var|] i = o as int?; - if (i != null) - Console.WriteLine(i); - } + object o = null; + [|var|] i = o as int?; + if (i != null) + Console.WriteLine(i); } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18053")] - public async Task TestMissingWhenTypesDoNotMatch() - { - await TestMissingInRegularAndScriptAsync( - """ - class SyntaxNode - { - public SyntaxNode Parent; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18053")] + public async Task TestMissingWhenTypesDoNotMatch() + { + await TestMissingInRegularAndScriptAsync( + """ + class SyntaxNode + { + public SyntaxNode Parent; + } - class BaseParameterListSyntax : SyntaxNode - { - } + class BaseParameterListSyntax : SyntaxNode + { + } - class ParameterSyntax : SyntaxNode - { + class ParameterSyntax : SyntaxNode + { - } + } - public static class C + public static class C + { + static void M(ParameterSyntax parameter) { - static void M(ParameterSyntax parameter) - { - [|SyntaxNode|] parent = parameter.Parent as BaseParameterListSyntax; - - if (parent != null) - { - parent = parent.Parent; - } - } - } - """); - } + [|SyntaxNode|] parent = parameter.Parent as BaseParameterListSyntax; - [Fact] - public async Task TestMissingOnWhileNoInline() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - void M(object o) + if (parent != null) { - [|string|] x = o as string; - while (x != null) - { - } + parent = parent.Parent; } } - """); - } + } + """); + } - [Fact] - public async Task TestWhileDefiniteAssignment1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingOnWhileNoInline() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - void M(object o) + [|string|] x = o as string; + while (x != null) { - [|string|] x; - while ((x = o as string) != null) - { - } - - var readAfterWhile = x; } } - """); - } + } + """); + } - [Fact] - public async Task TestWhileDefiniteAssignment2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWhileDefiniteAssignment1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - void M(object o) + [|string|] x; + while ((x = o as string) != null) { - [|string|] x; - while ((x = o as string) != null) - { - } - - x = "writeAfterWhile"; } + + var readAfterWhile = x; } - """); - } + } + """); + } - [Fact] - public async Task TestWhileDefiniteAssignment3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWhileDefiniteAssignment2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - void M(object o) + [|string|] x; + while ((x = o as string) != null) { - [|string|] x; - x = "writeBeforeWhile"; - while ((x = o as string) != null) - { - } } + + x = "writeAfterWhile"; } - """); - } + } + """); + } - [Fact] - public async Task TestWhileDefiniteAssignment4() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestWhileDefiniteAssignment3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - void M(object o) + [|string|] x; + x = "writeBeforeWhile"; + while ((x = o as string) != null) { - [|string|] x = null; - var readBeforeWhile = x; - while ((x = o as string) != null) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23504")] - public async Task DoNotChangeOriginalFormatting1() - { - await TestInRegularAndScript1Async( - """ - class Program + [Fact] + public async Task TestWhileDefiniteAssignment4() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - static void Main(string[] args) + [|string|] x = null; + var readBeforeWhile = x; + while ((x = o as string) != null) { - object obj = "test"; - - [|var|] str = obj as string; - var title = str != null - ? str - : "; } } - """, - """ - class Program - { - static void Main(string[] args) - { - object obj = "test"; + } + """); + } - var title = obj is string str - ? str - : "; - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23504")] + public async Task DoNotChangeOriginalFormatting1() + { + await TestInRegularAndScript1Async( + """ + class Program + { + static void Main(string[] args) + { + object obj = "test"; + + [|var|] str = obj as string; + var title = str != null + ? str + : "; + } + } + """, + """ + class Program + { + static void Main(string[] args) + { + object obj = "test"; + + var title = obj is string str + ? str + : "; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23504")] - public async Task DoNotChangeOriginalFormatting2() - { - await TestInRegularAndScript1Async( - """ - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23504")] + public async Task DoNotChangeOriginalFormatting2() + { + await TestInRegularAndScript1Async( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - object obj = "test"; + object obj = "test"; - [|var|] str = obj as string; - var title = str != null ? str : "; - } + [|var|] str = obj as string; + var title = str != null ? str : "; } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - object obj = "test"; + object obj = "test"; - var title = obj is string str ? str : "; - } + var title = obj is string str ? str : "; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21172")] - public async Task TestMissingWithDynamic() - { - await TestMissingAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21172")] + public async Task TestMissingWithDynamic() + { + await TestMissingAsync( + """ + class C + { + void M(object o) { - void M(object o) - { - [|var|] x = o as dynamic; - if (x != null) - { - } + [|var|] x = o as dynamic; + if (x != null) + { } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21551")] - public async Task TestOverloadedUserOperator() - { - await TestMissingAsync( - """ - class C - { - public static void Main() - { - object o = new C(); - [|var|] c = o as C; - if (c != null) - System.Console.WriteLine(); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21551")] + public async Task TestOverloadedUserOperator() + { + await TestMissingAsync( + """ + class C + { + public static void Main() + { + object o = new C(); + [|var|] c = o as C; + if (c != null) + System.Console.WriteLine(); + } + + public static bool operator ==(C c1, C c2) => false; + public static bool operator !=(C c1, C c2) => false; + } + """); + } - public static bool operator ==(C c1, C c2) => false; - public static bool operator !=(C c1, C c2) => false; - } - """); - } + [Fact] + public async Task TestNegativeDefiniteAssignment1() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M(object o) + { + [|var|] x = o as string; + if (x == null) return null; + return x; + } + } + """, + """ + class C + { + string M(object o) + { + if (!(o is string x)) return null; + return x; + } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestNegativeDefiniteAssignment1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestNegativeDefiniteAssignment2() + { + await TestInRegularAndScript1Async( + """ + class C + { + string M(object o, bool b) { - string M(object o) + [|var|] x = o as string; + if (((object)x == null) || b) + { + return null; + } + else { - [|var|] x = o as string; - if (x == null) return null; return x; } } - """, - """ - class C + } + """, + """ + class C + { + string M(object o, bool b) { - string M(object o) + if ((!(o is string x)) || b) + { + return null; + } + else { - if (!(o is string x)) return null; return x; } } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestNegativeDefiniteAssignment2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25993")] + public async Task TestEmbeddedStatement1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) { - string M(object o, bool b) + var fe = e as C; + [|var|] ae = e as C; + if (fe != null) { - [|var|] x = o as string; - if (((object)x == null) || b) - { - return null; - } - else - { - return x; - } + M(fe); // fe is used } - } - """, - """ - class C - { - string M(object o, bool b) + else if (ae != null) { - if ((!(o is string x)) || b) - { - return null; - } - else - { - return x; - } + M(ae); // ae is used } } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25993")] - public async Task TestEmbeddedStatement1() - { - await TestInRegularAndScript1Async( - """ - class C + } + """, + """ + class C + { + void M(object e) { - void M(object e) + var fe = e as C; + if (fe != null) { - var fe = e as C; - [|var|] ae = e as C; - if (fe != null) - { - M(fe); // fe is used - } - else if (ae != null) - { - M(ae); // ae is used - } + M(fe); // fe is used } - } - """, - """ - class C - { - void M(object e) + else if (e is C ae) { - var fe = e as C; - if (fe != null) - { - M(fe); // fe is used - } - else if (e is C ae) - { - M(ae); // ae is used - } + M(ae); // ae is used } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25993")] - public async Task TestEmbeddedStatement2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25993")] + public async Task TestEmbeddedStatement2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + var fe = e as C; + [|var|] ae = e as C; + if (fe != null) { - var fe = e as C; - [|var|] ae = e as C; - if (fe != null) - { - M(ae); // ae is used - } - else if (ae != null) - { - M(ae); // ae is used - } + M(ae); // ae is used + } + else if (ae != null) + { + M(ae); // ae is used } } - """); - } + } + """); + } - [Fact] - public async Task TestUseBeforeDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestUseBeforeDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + [|var|] c = e as C; { - [|var|] c = e as C; { - { - var x1 = c; + var x1 = c; - if (c != null) - { + if (c != null) + { - } } } } - } - """); - } - [Fact] - public async Task TestPossiblyUnassigned() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + } + """); + } + + [Fact] + public async Task TestPossiblyUnassigned() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + [|var|] c = e as C; { - [|var|] c = e as C; { + if (c != null) { - if (c != null) - { - - } - var x2 = c; } - // out of scope - var x3 = c; + var x2 = c; } + + // out of scope + var x3 = c; } } - """); - } + } + """); + } - [Fact] - public async Task TestOutOfScope() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestOutOfScope() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + [|var|] c = e as C; { - [|var|] c = e as C; { + if (c != null) { - if (c != null) - { - } } - - // out of scope - var x3 = c; } + + // out of scope + var x3 = c; } } - """); - } + } + """); + } - [Fact] - public async Task TestDeclarationOnOuterBlock() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestDeclarationOnOuterBlock() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) { - void M(object e) + [|var|] c = e as C; { - [|var|] c = e as C; { + if (c != null) { - if (c != null) - { - } } } } } - """, - """ - class C + } + """, + """ + class C + { + void M(object e) { - void M(object e) { { + if (e is C c) { - if (e is C c) - { - } } } } } - """); - } + } + """); + } - [Fact] - public async Task TestConditionalExpression() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(object e) - { - [|var|] c = e as C; - M(c != null ? c : null); - } - } - """, - """ - class C - { - void M(object e) - { - M(e is C c ? c : null); - } - } - """); - } + [Fact] + public async Task TestConditionalExpression() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) + { + [|var|] c = e as C; + M(c != null ? c : null); + } + } + """, + """ + class C + { + void M(object e) + { + M(e is C c ? c : null); + } + } + """); + } - [Fact] - public async Task TestConditionalExpression_OppositeBranch() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestConditionalExpression_OppositeBranch() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) - { - [|var|] c = e as C; - M(c != null ? c : null, c); - } + [|var|] c = e as C; + M(c != null ? c : null, c); } - """); - } + } + """); + } - [Fact] - public async Task TestForStatement_NoInlineTypeCheck() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestForStatement_NoInlineTypeCheck() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) - { - [|var|] c = e as C; - for (;(c)!=null;) {} - } + [|var|] c = e as C; + for (;(c)!=null;) {} } - """); - } + } + """); + } - [Fact] - public async Task TestForStatement_InlineTypeCheck() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(object e) - { - [|C|] c; - for (; !((c = e as C)==null);) { } - } - } - """, - """ - class C - { - void M(object e) - { - for (; !(!(e is C c));) { } - } - } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + [Fact] + public async Task TestForStatement_InlineTypeCheck() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) + { + [|C|] c; + for (; !((c = e as C)==null);) { } + } + } + """, + """ + class C + { + void M(object e) + { + for (; !(!(e is C c));) { } + } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestForStatement_InScope() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestForStatement_InScope() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) { - void M(object e) + [|C|] c = null; + for (; !((c = e as C)==null);) { - [|C|] c = null; - for (; !((c = e as C)==null);) - { - M(c); - } + M(c); } } - """, - """ - class C + } + """, + """ + class C + { + void M(object e) { - void M(object e) + for (; !(!(e is C c));) { - for (; !(!(e is C c));) - { - M(c); - } + M(c); } } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestForStatement_NotAssignedBeforeAccess() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestForStatement_NotAssignedBeforeAccess() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + [|C|] c = null; + for (; ((c = e as C)==null);) { - [|C|] c = null; - for (; ((c = e as C)==null);) - { - if (b) c = null; - M(c); - } + if (b) c = null; + M(c); } } - """); - } + } + """); + } - [Fact] - public async Task TestForStatement_AssignedBeforeAccess() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestForStatement_AssignedBeforeAccess() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e, bool b) { - void M(object e, bool b) + [|C|] c = null; + for (; (c = e as C)==null;) { - [|C|] c = null; - for (; (c = e as C)==null;) - { - if (b) c = null; - else c = null; - M(c); - } + if (b) c = null; + else c = null; + M(c); } } - """, - """ - class C + } + """, + """ + class C + { + void M(object e, bool b) { - void M(object e, bool b) + for (; !(e is C c);) { - for (; !(e is C c);) - { - if (b) c = null; - else c = null; - M(c); - } + if (b) c = null; + else c = null; + M(c); } } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestForStatement_MultipleDeclarators() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestForStatement_MultipleDeclarators() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) { - void M(object e) + [|C|] c = null, x = null; + for (; !((c = e as C)==null);) { - [|C|] c = null, x = null; - for (; !((c = e as C)==null);) - { - M(c); - } + M(c); } } - """, - """ - class C + } + """, + """ + class C + { + void M(object e) { - void M(object e) + C x = null; + for (; !(!(e is C c));) { - C x = null; - for (; !(!(e is C c));) - { - M(c); - } + M(c); } } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestForStatement_UseBeforeDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestForStatement_UseBeforeDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + [|C|] c = null, x = c; + for (; !((c = e as C)==null);) { - [|C|] c = null, x = c; - for (; !((c = e as C)==null);) - { - M(c); - } + M(c); } } - """); - } + } + """); + } - [Fact] - public async Task TestForStatement_Initializer() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestForStatement_Initializer() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object e) { - void M(object e) + [|C|] c; + for (var i = !((c = e as C)==null); i != null; ) { - [|C|] c; - for (var i = !((c = e as C)==null); i != null; ) - { - M(c); - } + M(c); } } - """); - } + } + """); + } - [Fact] - public async Task TestLocalFunction() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(object e) - { - [||]var c = e as C; - C F() => c == null ? null : c; - } - } - """, - """ - class C - { - void M(object e) - { - C F() => !(e is C c) ? null : c; - } - } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + [Fact] + public async Task TestLocalFunction() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) + { + [||]var c = e as C; + C F() => c == null ? null : c; + } + } + """, + """ + class C + { + void M(object e) + { + C F() => !(e is C c) ? null : c; + } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestLocalFunction_UseOutOfScope() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - C M(object e) - { - [||]var c = e as C; - C F() => c == null ? null : c; - return c; - } - } - """); - } + [Fact] + public async Task TestLocalFunction_UseOutOfScope() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M(object e) + { + [||]var c = e as C; + C F() => c == null ? null : c; + return c; + } + } + """); + } - [Fact] - public async Task TestExpressionLambda() - { - await TestInRegularAndScript1Async( - """ - class C - { - void M(object e) - { - [||]var c = e as C; - System.Func f = () => c == null ? null : c; - } - } - """, - """ - class C - { - void M(object e) - { - System.Func f = () => !(e is C c) ? null : c; - } - } - """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); - } + [Fact] + public async Task TestExpressionLambda() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M(object e) + { + [||]var c = e as C; + System.Func f = () => c == null ? null : c; + } + } + """, + """ + class C + { + void M(object e) + { + System.Func f = () => !(e is C c) ? null : c; + } + } + """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); + } - [Fact] - public async Task TestExpressionLambda_UseOutOfScope() - { - await TestMissingInRegularAndScriptAsync( - """ - class C - { - C M(object e) - { - [||]var c = e as C; - System.Func f = () => c == null ? null : c; - return c; - } - } - """); - } + [Fact] + public async Task TestExpressionLambda_UseOutOfScope() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + C M(object e) + { + [||]var c = e as C; + System.Func f = () => c == null ? null : c; + return c; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31388")] - public async Task TestUseBetweenAssignmentAndIfCondition() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31388")] + public async Task TestUseBetweenAssignmentAndIfCondition() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M(object o) { - void M(object o) + [|var|] c = o as C; + M2(c != null); + if (c == null) { - [|var|] c = o as C; - M2(c != null); - if (c == null) - { - return; - } + return; } - - void M2(bool b) { } } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40007")] - public async Task TestSpaceAfterGenericType() - { - await TestInRegularAndScript1Async( - """ - #nullable enable + void M2(bool b) { } + } + """); + } - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40007")] + public async Task TestSpaceAfterGenericType() + { + await TestInRegularAndScript1Async( + """ + #nullable enable - class Program + using System.Collections.Generic; + + class Program + { + static void Goo(object items) { - static void Goo(object items) + [|var|] itemsAsDictionary = items as IDictionary; + SortedDictionary? dictionary = null; + if (itemsAsDictionary != null) { - [|var|] itemsAsDictionary = items as IDictionary; - SortedDictionary? dictionary = null; - if (itemsAsDictionary != null) - { - dictionary = new SortedDictionary(); - } - return dictionary; + dictionary = new SortedDictionary(); } + return dictionary; } - """, - """ - #nullable enable + } + """, + """ + #nullable enable - using System.Collections.Generic; + using System.Collections.Generic; - class Program + class Program + { + static void Goo(object items) { - static void Goo(object items) + SortedDictionary? dictionary = null; + if (items is IDictionary itemsAsDictionary) { - SortedDictionary? dictionary = null; - if (items is IDictionary itemsAsDictionary) - { - dictionary = new SortedDictionary(); - } - return dictionary; + dictionary = new SortedDictionary(); } + return dictionary; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45596")] - public async Task TestMissingInUsingDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45596")] + public async Task TestMissingInUsingDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + using [|var|] x = o as IDisposable; + if (x != null) { - using [|var|] x = o as IDisposable; - if (x != null) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45596")] - public async Task TestMissingInUsingStatement() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45596")] + public async Task TestMissingInUsingStatement() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + using ([|var|] x = o as IDisposable) { - using ([|var|] x = o as IDisposable) + if (x != null) { - if (x != null) - { - } } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37398")] - public async Task TestPrecedingDirectiveTrivia() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37398")] + public async Task TestPrecedingDirectiveTrivia() + { + await TestInRegularAndScript1Async( + """ + class C + { + public static void M(object o) { - public static void M(object o) - { - #if DEBUG - Console.WriteLine("in debug"); - #endif + #if DEBUG + Console.WriteLine("in debug"); + #endif - [|string|] s = o as string; - if (s != null) - { + [|string|] s = o as string; + if (s != null) + { - } } } - """, - """ - class C + } + """, + """ + class C + { + public static void M(object o) { - public static void M(object o) - { - #if DEBUG - Console.WriteLine("in debug"); - #endif + #if DEBUG + Console.WriteLine("in debug"); + #endif - if (o is string s) - { + if (o is string s) + { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40006")] - public async Task TestArrayOfNullables() - { - await TestInRegularAndScript1Async( - """ - #nullable enable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40006")] + public async Task TestArrayOfNullables() + { + await TestInRegularAndScript1Async( + """ + #nullable enable - class Program + class Program + { + static void Set(object obj, object? item) { - static void Set(object obj, object? item) + [|object?[]?|] arr = obj as object[]; + if (arr != null) { - [|object?[]?|] arr = obj as object[]; - if (arr != null) - { - arr[0] = item; - } + arr[0] = item; } } - """, - """ - #nullable enable + } + """, + """ + #nullable enable - class Program + class Program + { + static void Set(object obj, object? item) { - static void Set(object obj, object? item) + if (obj is object?[] arr) { - if (obj is object?[] arr) - { - arr[0] = item; - } + arr[0] = item; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55782")] - public async Task TestLocalReferencedAcrossScopes1() - { - var code = """ - using System.Transactions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55782")] + public async Task TestLocalReferencedAcrossScopes1() + { + var code = """ + using System.Transactions; - class BaseObject { } - class ObjectFactory + class BaseObject { } + class ObjectFactory + { + internal static BaseObject CreateObject(int x) { - internal static BaseObject CreateObject(int x) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } - struct Repro + struct Repro + { + static int Main(string[] args) { - static int Main(string[] args) - { - int x = 0; - [|BaseObject|] obj; + int x = 0; + [|BaseObject|] obj; - var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; - using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) + var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; + using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) + { + try { - try - { - if ((obj = ObjectFactory.CreateObject(x) as BaseObject) == null) - { - return -1; - } - // uses of obj in the transaction - } - catch (TransactionAbortedException) + if ((obj = ObjectFactory.CreateObject(x) as BaseObject) == null) { return -1; } + // uses of obj in the transaction + } + catch (TransactionAbortedException) + { + return -1; } - - // local used here. - Console.WriteLine(obj); - return 0; } + + // local used here. + Console.WriteLine(obj); + return 0; } - """; + } + """; - await TestMissingInRegularAndScriptAsync(code); - } + await TestMissingInRegularAndScriptAsync(code); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55782")] - public async Task TestLocalReferencedAcrossScopes2() - { - await TestInRegularAndScript1Async(""" - using System.Transactions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55782")] + public async Task TestLocalReferencedAcrossScopes2() + { + await TestInRegularAndScript1Async(""" + using System.Transactions; - class BaseObject { } - class ObjectFactory + class BaseObject { } + class ObjectFactory + { + internal static BaseObject CreateObject(int x) { - internal static BaseObject CreateObject(int x) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } - struct Repro + struct Repro + { + static int Main(string[] args) { - static int Main(string[] args) - { - int x = 0; - [|BaseObject|] obj; + int x = 0; + [|BaseObject|] obj; - var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; - using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) + var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; + using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) + { + try { - try - { - if ((obj = ObjectFactory.CreateObject(x) as BaseObject) == null) - { - return -1; - } - // uses of obj in the transaction - } - catch (TransactionAbortedException) + if ((obj = ObjectFactory.CreateObject(x) as BaseObject) == null) { return -1; } + // uses of obj in the transaction + } + catch (TransactionAbortedException) + { + return -1; } - - // not used - return 0; } + + // not used + return 0; } - """, - """ - using System.Transactions; + } + """, + """ + using System.Transactions; - class BaseObject { } - class ObjectFactory + class BaseObject { } + class ObjectFactory + { + internal static BaseObject CreateObject(int x) { - internal static BaseObject CreateObject(int x) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } + } - struct Repro + struct Repro + { + static int Main(string[] args) { - static int Main(string[] args) - { - int x = 0; + int x = 0; - var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; - using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) + var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; + using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) + { + try { - try - { - if (ObjectFactory.CreateObject(x) is not BaseObject obj) - { - return -1; - } - // uses of obj in the transaction - } - catch (TransactionAbortedException) + if (ObjectFactory.CreateObject(x) is not BaseObject obj) { return -1; } + // uses of obj in the transaction + } + catch (TransactionAbortedException) + { + return -1; } - - // not used - return 0; } + + // not used + return 0; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] - public async Task TestNullableWhenWrittenTo1() - { - await TestInRegularAndScript1Async(""" - #nullable enable - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] + public async Task TestNullableWhenWrittenTo1() + { + await TestInRegularAndScript1Async(""" + #nullable enable + using System; - class Program + class Program + { + static void Goo(object o1, object o2) { - static void Goo(object o1, object o2) + [|string?|] s = o1 as string; + if (s == null) { - [|string?|] s = o1 as string; - if (s == null) - { - } } } - """, - """ - #nullable enable - using System; - - class Program + } + """, + """ + #nullable enable + using System; + + class Program + { + static void Goo(object o1, object o2) { - static void Goo(object o1, object o2) + if (o1 is not string s) { - if (o1 is not string s) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] - public async Task TestNullableWhenWrittenTo2() - { - await TestInRegularAndScript1Async(""" - #nullable enable - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] + public async Task TestNullableWhenWrittenTo2() + { + await TestInRegularAndScript1Async(""" + #nullable enable + using System; - class Program + class Program + { + static void Goo(object o1, object o2) { - static void Goo(object o1, object o2) + [|string?|] s = o1 as string; + if (s == null) { - [|string?|] s = o1 as string; - if (s == null) - { - s = ""; - } + s = ""; } } - """, - """ - #nullable enable - using System; - - class Program + } + """, + """ + #nullable enable + using System; + + class Program + { + static void Goo(object o1, object o2) { - static void Goo(object o1, object o2) + if (o1 is not string s) { - if (o1 is not string s) - { - s = ""; - } + s = ""; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] - public async Task TestNullableWhenWrittenTo3() - { - await TestMissingInRegularAndScriptAsync(""" - #nullable enable - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] + public async Task TestNullableWhenWrittenTo3() + { + await TestMissingInRegularAndScriptAsync(""" + #nullable enable + using System; - class Program + class Program + { + static void Goo(object o1, object o2) { - static void Goo(object o1, object o2) + [|string?|] s = o1 as string; + if (s == null) { - [|string?|] s = o1 as string; - if (s == null) - { - s = o2 as string; - } + s = o2 as string; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] - public async Task TestNullableWhenWrittenTo4() - { - await TestMissingInRegularAndScriptAsync(""" - #nullable enable - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] + public async Task TestNullableWhenWrittenTo4() + { + await TestMissingInRegularAndScriptAsync(""" + #nullable enable + using System; - class Program + class Program + { + static void Goo(object o1, object o2) { - static void Goo(object o1, object o2) + [|string?|] s = o1 as string; + if (s == null) { - [|string?|] s = o1 as string; - if (s == null) - { - s = null; - } + s = null; } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests_FixAllTests.cs index 78dcb4aac0d66..ff04e9213b3eb 100644 --- a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests_FixAllTests.cs @@ -10,162 +10,138 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] +public partial class CSharpAsAndNullCheckTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] - public partial class CSharpAsAndNullCheckTests + [Fact] + public async Task FixAllInDocument1() { - [Fact] - public async Task FixAllInDocument1() - { - await TestInRegularAndScriptAsync( - """ - class C + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + string a; + {|FixAllInDocument:var|} x = o as string; + if (x != null) { - string a; - {|FixAllInDocument:var|} x = o as string; - if (x != null) - { - } + } - var y = o as string; - if (y != null) - { - } + var y = o as string; + if (y != null) + { + } - if ((a = o as string) == null) - { - } + if ((a = o as string) == null) + { + } - var c = o as string; - var d = c != null ? 1 : 0; + var c = o as string; + var d = c != null ? 1 : 0; - var e = o as string; - return e != null ? 1 : 0; - } + var e = o as string; + return e != null ? 1 : 0; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() + if (o is string x) { - if (o is string x) - { - } + } - if (o is string y) - { - } + if (o is string y) + { + } - if (!(o is string a)) - { - } + if (!(o is string a)) + { + } - var d = o is string c ? 1 : 0; + var d = o is string c ? 1 : 0; - return o is string e ? 1 : 0; - } + return o is string e ? 1 : 0; } - """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); - } - - [Fact] - public async Task FixAllInDocument1_CSharp9() - { - await TestInRegularAndScriptAsync( - """ - class C + } + """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); + } + + [Fact] + public async Task FixAllInDocument1_CSharp9() + { + await TestInRegularAndScriptAsync( + """ + class C + { + int M() { - int M() + string a; + {|FixAllInDocument:var|} x = o as string; + if (x != null) { - string a; - {|FixAllInDocument:var|} x = o as string; - if (x != null) - { - } + } - var y = o as string; - if (y != null) - { - } + var y = o as string; + if (y != null) + { + } - if ((a = o as string) == null) - { - } + if ((a = o as string) == null) + { + } - var c = o as string; - var d = c != null ? 1 : 0; + var c = o as string; + var d = c != null ? 1 : 0; - var e = o as string; - return e != null ? 1 : 0; - } + var e = o as string; + return e != null ? 1 : 0; } - """, - """ - class C + } + """, + """ + class C + { + int M() { - int M() + if (o is string x) { - if (o is string x) - { - } - - if (o is string y) - { - } - - if (o is not string a) - { - } - - var d = o is string c ? 1 : 0; + } - return o is string e ? 1 : 0; + if (o is string y) + { } - } - """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); - } - - [Fact] - public async Task FixAllInDocument2() - { - await TestInRegularAndScriptAsync( - """ - class Symbol - { - public ContainingSymbol { get; } - void M(object o, bool b0, bool b1) + if (o is not string a) { - {|FixAllInDocument:var|} symbol = o as Symbol; - if (symbol != null) - { - while ((object)symbol != null && b1) - { - symbol = symbol.ContainingSymbol as Symbol; - } + } - if ((object)symbol == null || b2) - { - throw null; - } + var d = o is string c ? 1 : 0; - var use = symbol; - } - } + return o is string e ? 1 : 0; } - """, - """ - class Symbol - { - public ContainingSymbol { get; } + } + """, parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } - void M(object o, bool b0, bool b1) - { - if (o is Symbol symbol) + [Fact] + public async Task FixAllInDocument2() + { + await TestInRegularAndScriptAsync( + """ + class Symbol + { + public ContainingSymbol { get; } + + void M(object o, bool b0, bool b1) + { + {|FixAllInDocument:var|} symbol = o as Symbol; + if (symbol != null) { while ((object)symbol != null && b1) { @@ -180,109 +156,132 @@ void M(object o, bool b0, bool b1) var use = symbol; } } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26679")] - public async Task FixAllInDocument3() - { - await TestInRegularAndScriptAsync( - """ - class Test + } + """, + """ + class Symbol + { + public ContainingSymbol { get; } + + void M(object o, bool b0, bool b1) { - void M() + if (o is Symbol symbol) + { + while ((object)symbol != null && b1) { - {|FixAllInDocument:IMethodSymbol|} methodSymbol; - IPropertySymbol propertySymbol; - IEventSymbol eventSymbol; - bool isImplementingExplicitly; + symbol = symbol.ContainingSymbol as Symbol; + } - // Only methods, properties and events can implement an interface member - if ((methodSymbol = memberSymbol as IMethodSymbol) != null) - { - // Check if the member is implementing an interface explicitly - isImplementingExplicitly = methodSymbol.ExplicitInterfaceImplementations.Any(); - } - else if ((propertySymbol = memberSymbol as IPropertySymbol) != null) - { - // Check if the member is implementing an interface explicitly - isImplementingExplicitly = propertySymbol.ExplicitInterfaceImplementations.Any(); - } - else if ((eventSymbol = memberSymbol as IEventSymbol) != null) - { - // Check if the member is implementing an interface explicitly - isImplementingExplicitly = eventSymbol.ExplicitInterfaceImplementations.Any(); - } - else - { - return false; - } + if ((object)symbol == null || b2) + { + throw null; } + + var use = symbol; } - """, - """ - class Test + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26679")] + public async Task FixAllInDocument3() + { + await TestInRegularAndScriptAsync( + """ + class Test + { + void M() { - void M() - { - bool isImplementingExplicitly; + {|FixAllInDocument:IMethodSymbol|} methodSymbol; + IPropertySymbol propertySymbol; + IEventSymbol eventSymbol; + bool isImplementingExplicitly; - // Only methods, properties and events can implement an interface member - if (memberSymbol is IMethodSymbol methodSymbol) - { - // Check if the member is implementing an interface explicitly - isImplementingExplicitly = methodSymbol.ExplicitInterfaceImplementations.Any(); - } - else if (memberSymbol is IPropertySymbol propertySymbol) - { - // Check if the member is implementing an interface explicitly - isImplementingExplicitly = propertySymbol.ExplicitInterfaceImplementations.Any(); - } - else if (memberSymbol is IEventSymbol eventSymbol) - { - // Check if the member is implementing an interface explicitly - isImplementingExplicitly = eventSymbol.ExplicitInterfaceImplementations.Any(); - } - else - { - return false; - } + // Only methods, properties and events can implement an interface member + if ((methodSymbol = memberSymbol as IMethodSymbol) != null) + { + // Check if the member is implementing an interface explicitly + isImplementingExplicitly = methodSymbol.ExplicitInterfaceImplementations.Any(); + } + else if ((propertySymbol = memberSymbol as IPropertySymbol) != null) + { + // Check if the member is implementing an interface explicitly + isImplementingExplicitly = propertySymbol.ExplicitInterfaceImplementations.Any(); + } + else if ((eventSymbol = memberSymbol as IEventSymbol) != null) + { + // Check if the member is implementing an interface explicitly + isImplementingExplicitly = eventSymbol.ExplicitInterfaceImplementations.Any(); + } + else + { + return false; } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26680")] - public async Task FixAllInDocument4() - { - await TestInRegularAndScriptAsync( - """ - class Test + } + """, + """ + class Test + { + void M() { - void M() + bool isImplementingExplicitly; + + // Only methods, properties and events can implement an interface member + if (memberSymbol is IMethodSymbol methodSymbol) + { + // Check if the member is implementing an interface explicitly + isImplementingExplicitly = methodSymbol.ExplicitInterfaceImplementations.Any(); + } + else if (memberSymbol is IPropertySymbol propertySymbol) + { + // Check if the member is implementing an interface explicitly + isImplementingExplicitly = propertySymbol.ExplicitInterfaceImplementations.Any(); + } + else if (memberSymbol is IEventSymbol eventSymbol) + { + // Check if the member is implementing an interface explicitly + isImplementingExplicitly = eventSymbol.ExplicitInterfaceImplementations.Any(); + } + else { - {|FixAllInDocument:var|} firstTextPartSyntax = summaryElement.Content[0] as XmlTextSyntax; - var classReferencePart = summaryElement.Content[1] as XmlEmptyElementSyntax; - var secondTextPartSyntax = summaryElement.Content[2] as XmlTextSyntax; + return false; + } + } + } + """); + } - if (firstTextPartSyntax != null && classReferencePart != null && secondTextPartSyntax != null) - { - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/26680")] + public async Task FixAllInDocument4() + { + await TestInRegularAndScriptAsync( + """ + class Test + { + void M() + { + {|FixAllInDocument:var|} firstTextPartSyntax = summaryElement.Content[0] as XmlTextSyntax; + var classReferencePart = summaryElement.Content[1] as XmlEmptyElementSyntax; + var secondTextPartSyntax = summaryElement.Content[2] as XmlTextSyntax; + + if (firstTextPartSyntax != null && classReferencePart != null && secondTextPartSyntax != null) + { } } - """, - """ - class Test + } + """, + """ + class Test + { + void M() { - void M() + if (summaryElement.Content[0] is XmlTextSyntax firstTextPartSyntax && summaryElement.Content[1] is XmlEmptyElementSyntax classReferencePart && summaryElement.Content[2] is XmlTextSyntax secondTextPartSyntax) { - if (summaryElement.Content[0] is XmlTextSyntax firstTextPartSyntax && summaryElement.Content[1] is XmlEmptyElementSyntax classReferencePart && summaryElement.Content[2] is XmlTextSyntax secondTextPartSyntax) - { - } } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests.cs index 1370405055fb5..442e067e35881 100644 --- a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests.cs @@ -17,778 +17,777 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] +public partial class CSharpIsAndCastCheckDiagnosticAnalyzerTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] - public partial class CSharpIsAndCastCheckDiagnosticAnalyzerTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public CSharpIsAndCastCheckDiagnosticAnalyzerTests(ITestOutputHelper logger) + : base(logger) { - public CSharpIsAndCastCheckDiagnosticAnalyzerTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpIsAndCastCheckDiagnosticAnalyzer(), new CSharpIsAndCastCheckCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpIsAndCastCheckDiagnosticAnalyzer(), new CSharpIsAndCastCheckCodeFixProvider()); - [Fact] - public async Task InlineTypeCheck1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheck1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)x; - } + [|var|] v = (string)x; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (x is string v) { - if (x is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInCSharp6() - { - await TestMissingAsync( - """ - class C + [Fact] + public async Task TestMissingInCSharp6() + { + await TestMissingAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)x; - } + [|var|] v = (string)x; } } - """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task TestMissingInWrongName() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingInWrongName() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)y; - } + [|var|] v = (string)y; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingInWrongType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingInWrongType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (bool)x; - } + [|var|] v = (bool)x; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnMultiVar() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingOnMultiVar() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - var [|v|] = (string)x, v1 = "; - } + var [|v|] = (string)x, v1 = "; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnNonDeclaration() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingOnNonDeclaration() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|v|] = (string)x; - } + [|v|] = (string)x; } } - """); - } + } + """); + } - [Fact] - public async Task TestMissingOnAsExpression() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task TestMissingOnAsExpression() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x as string) { - if (x as string) - { - [|var|] v = (string)x; - } + [|var|] v = (string)x; } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckComplexExpression1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckComplexExpression1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if ((x ? y : z) is string) { - if ((x ? y : z) is string) - { - [|var|] v = (string)(x ? y : z); - } + [|var|] v = (string)(x ? y : z); } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if ((x ? y : z) is string v) { - if ((x ? y : z) is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestInlineTypeCheckWithElse() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestInlineTypeCheckWithElse() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) + { + [|var|] v = (string)x; + } + else { - if (x is string) - { - [|var|] v = (string)x; - } - else - { - } } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (x is string v) + { + } + else { - if (x is string v) - { - } - else - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - // prefix comment - [|var|] v = (string)x; - } - } + // prefix comment + [|var|] v = (string)x; + } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix comment + if (x is string v) { - // prefix comment - if (x is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)x; // suffix comment - } - } + [|var|] v = (string)x; // suffix comment + } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // suffix comment + if (x is string v) { - // suffix comment - if (x is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task TestComments3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task TestComments3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - // prefix comment - [|var|] v = (string)x; // suffix comment - } - } + // prefix comment + [|var|] v = (string)x; // suffix comment + } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + // prefix comment + // suffix comment + if (x is string v) { - // prefix comment - // suffix comment - if (x is string v) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17126")] - public async Task TestComments4() - { - await TestInRegularAndScript1Async( - """ - using System; - namespace N { - class Program { - public static void Main() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17126")] + public async Task TestComments4() + { + await TestInRegularAndScript1Async( + """ + using System; + namespace N { + class Program { + public static void Main() + { + object o = null; + if (o is int) + Console.WriteLine(); + else if (o is string) { - object o = null; - if (o is int) - Console.WriteLine(); - else if (o is string) - { - // some comment - [|var|] s = (string)o; - Console.WriteLine(s); - } + // some comment + [|var|] s = (string)o; + Console.WriteLine(s); } } } - """, - """ - using System; - namespace N { - class Program { - public static void Main() + } + """, + """ + using System; + namespace N { + class Program { + public static void Main() + { + object o = null; + if (o is int) + Console.WriteLine(); + else if (o is string s) // some comment { - object o = null; - if (o is int) - Console.WriteLine(); - else if (o is string s) // some comment - { - Console.WriteLine(s); - } + Console.WriteLine(s); } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckParenthesized1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckParenthesized1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if ((x) is string) { - if ((x) is string) - { - [|var|] v = (string)x; - } + [|var|] v = (string)x; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if ((x) is string v) { - if ((x) is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckParenthesized2() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckParenthesized2() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)(x); - } + [|var|] v = (string)(x); } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (x is string v) { - if (x is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckParenthesized3() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckParenthesized3() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = ((string)x); - } + [|var|] v = ((string)x); } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (x is string v) { - if (x is string v) - { - } } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckScopeConflict1() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task InlineTypeCheckScopeConflict1() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)x; - } - else - { - var v = 1; - } + [|var|] v = (string)x; + } + else + { + var v = 1; } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckScopeConflict2() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task InlineTypeCheckScopeConflict2() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)x; - } + [|var|] v = (string)x; + } - if (true) - { - var v = 1; - } + if (true) + { + var v = 1; } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckScopeConflict3() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task InlineTypeCheckScopeConflict3() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - var v = (string)x; - } + var v = (string)x; + } - if (x is bool) - { - [|var|] v = (bool)x; - } + if (x is bool) + { + [|var|] v = (bool)x; } } - """); - } + } + """); + } - [Fact] - public async Task InlineTypeCheckScopeNonConflict1() - { - await TestInRegularAndScript1Async( - """ - class C + [Fact] + public async Task InlineTypeCheckScopeNonConflict1() + { + await TestInRegularAndScript1Async( + """ + class C + { + void M() { - void M() { + if (x is string) { - if (x is string) - { - [|var|] v = ((string)x); - } + [|var|] v = ((string)x); } + } - { - var v = 1; - } + { + var v = 1; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() { + if (x is string v) { - if (x is string v) - { - } } + } - { - var v = 1; - } + { + var v = 1; } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18053")] - public async Task TestMissingWhenTypesDoNotMatch() - { - await TestMissingInRegularAndScriptAsync( - """ - class SyntaxNode - { - public SyntaxNode Parent; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18053")] + public async Task TestMissingWhenTypesDoNotMatch() + { + await TestMissingInRegularAndScriptAsync( + """ + class SyntaxNode + { + public SyntaxNode Parent; + } - class BaseParameterListSyntax : SyntaxNode - { - } + class BaseParameterListSyntax : SyntaxNode + { + } - class ParameterSyntax : SyntaxNode - { + class ParameterSyntax : SyntaxNode + { - } + } - public static class C + public static class C + { + static void N(ParameterSyntax parameter) { - static void N(ParameterSyntax parameter) + if (parameter.Parent is BaseParameterListSyntax) { - if (parameter.Parent is BaseParameterListSyntax) - { - [|SyntaxNode|] parent = (BaseParameterListSyntax)parameter.Parent; - parent = parent.Parent; - } + [|SyntaxNode|] parent = (BaseParameterListSyntax)parameter.Parent; + parent = parent.Parent; } } - """); - } + } + """); + } - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/429612")] - public async Task TestMissingWithNullableType() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/429612")] + public async Task TestMissingWithNullableType() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public object Convert(object value) { - public object Convert(object value) + if (value is bool?) { - if (value is bool?) - { - [|bool?|] tmp = (bool?)value; - } - - return null; + [|bool?|] tmp = (bool?)value; } + + return null; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21172")] - public async Task TestMissingWithDynamic() - { - await TestMissingInRegularAndScriptAsync( - """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21172")] + public async Task TestMissingWithDynamic() + { + await TestMissingInRegularAndScriptAsync( + """ + class C + { + public object Convert(object value) { - public object Convert(object value) + if (value is dynamic) { - if (value is dynamic) - { - [|dynamic|] tmp = (dynamic)value; - } - - return null; + [|dynamic|] tmp = (dynamic)value; } + + return null; } - """); - } + } + """); + } - [Fact] - public async Task TestSeverity() - { - var source = + [Fact] + public async Task TestSeverity() + { + var source = - """ - class C + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - [|var|] v = (string)x; - } - } + [|var|] v = (string)x; + } } - """; - var warningOption = new CodeStyleOption2(true, NotificationOption2.Warning); - var options = Option(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck, warningOption); - var testParameters = new TestParameters(options: options, parseOptions: TestOptions.Regular8); + } + """; + var warningOption = new CodeStyleOption2(true, NotificationOption2.Warning); + var options = Option(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck, warningOption); + var testParameters = new TestParameters(options: options, parseOptions: TestOptions.Regular8); - using var workspace = CreateWorkspaceFromOptions(source, testParameters); - var diag = (await GetDiagnosticsAsync(workspace, testParameters)).Single(); - Assert.Equal(DiagnosticSeverity.Warning, diag.Severity); - Assert.Equal(IDEDiagnosticIds.InlineIsTypeCheckId, diag.Id); - } + using var workspace = CreateWorkspaceFromOptions(source, testParameters); + var diag = (await GetDiagnosticsAsync(workspace, testParameters)).Single(); + Assert.Equal(DiagnosticSeverity.Warning, diag.Severity); + Assert.Equal(IDEDiagnosticIds.InlineIsTypeCheckId, diag.Id); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24287")] - public async Task TestWithVariableDesignation1() - { - await TestInRegularAndScriptAsync( - """ - public class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24287")] + public async Task TestWithVariableDesignation1() + { + await TestInRegularAndScriptAsync( + """ + public class Test + { + public void TestIt(object o) { - public void TestIt(object o) + if (o is int) + { + [|var|] value = (int)o; + } + else if (o is Guid value1) { - if (o is int) - { - [|var|] value = (int)o; - } - else if (o is Guid value1) - { - } } } - """, - """ - public class Test + } + """, + """ + public class Test + { + public void TestIt(object o) { - public void TestIt(object o) + if (o is int value) + { + } + else if (o is Guid value1) { - if (o is int value) - { - } - else if (o is Guid value1) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24287")] - public async Task TestWithVariableDesignation2() - { - await TestMissingAsync( - """ - public class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24287")] + public async Task TestWithVariableDesignation2() + { + await TestMissingAsync( + """ + public class Test + { + public void TestIt(object o) { - public void TestIt(object o) + if (o is int) + { + [|var|] value = (int)o; + } + else if (o is Guid value) { - if (o is int) - { - [|var|] value = (int)o; - } - else if (o is Guid value) - { - } } } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24287")] - public async Task TestWithVariableDesignation3() - { - await TestMissingAsync( - """ - public class Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24287")] + public async Task TestWithVariableDesignation3() + { + await TestMissingAsync( + """ + public class Test + { + public void TestIt(object o) { - public void TestIt(object o) + if (o is int) { - if (o is int) - { - [|var|] value = (int)o; - } - else if (TryGetValue(o, out var value)) - } + [|var|] value = (int)o; } - - private bool TryGetValue(object o, out string result) - { - result = ""; - return true; + else if (TryGetValue(o, out var value)) } } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42462")] - public async Task TestWithLocalInsideTryBlock() - { - await TestInRegularAndScript1Async( - """ - class Program + private bool TryGetValue(object o, out string result) { - static void Main(string[] args) - { - object value = null; + result = ""; + return true; + } + } + """); + } - if (value is string) + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42462")] + public async Task TestWithLocalInsideTryBlock() + { + await TestInRegularAndScript1Async( + """ + class Program + { + static void Main(string[] args) + { + object value = null; + + if (value is string) + { + try { - try - { - [|var|] stringValue = (string)value; - } - finally - { - - } + [|var|] stringValue = (string)value; + } + finally + { + } } } - """, - """ - class Program + } + """, + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - object value = null; + object value = null; - if (value is string stringValue) + if (value is string stringValue) + { + try + { + } + finally { - try - { - } - finally - { - } } } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests_FixAllTests.cs index a2cf105574655..8c921bfce0b0f 100644 --- a/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzerTests_FixAllTests.cs @@ -8,85 +8,84 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching; + +[Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] +public partial class CSharpIsAndCastCheckDiagnosticAnalyzerTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] - public partial class CSharpIsAndCastCheckDiagnosticAnalyzerTests + [Fact] + public async Task FixAllInDocument1() { - [Fact] - public async Task FixAllInDocument1() - { - await TestInRegularAndScriptAsync( - """ - class C + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - {|FixAllInDocument:var|} v1 = (string)x; - } + {|FixAllInDocument:var|} v1 = (string)x; + } - if (x is bool) - { - var v2 = (bool)x; - } + if (x is bool) + { + var v2 = (bool)x; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (x is string v1) { - if (x is string v1) - { - } + } - if (x is bool v2) - { - } + if (x is bool v2) + { } } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument2() - { - await TestInRegularAndScriptAsync( - """ - class C + [Fact] + public async Task FixAllInDocument2() + { + await TestInRegularAndScriptAsync( + """ + class C + { + void M() { - void M() + if (x is string) { - if (x is string) - { - var v1 = (string)x; - } + var v1 = (string)x; + } - if (x is bool) - { - {|FixAllInDocument:var|} v2 = (bool)x; - } + if (x is bool) + { + {|FixAllInDocument:var|} v2 = (bool)x; } } - """, - """ - class C + } + """, + """ + class C + { + void M() { - void M() + if (x is string v1) { - if (x is string v1) - { - } + } - if (x is bool v2) - { - } + if (x is bool v2) + { } } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs b/src/Analyzers/CSharp/Tests/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs index a3cd8089d4f7b..283de4f8afb13 100644 --- a/src/Analyzers/CSharp/Tests/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs +++ b/src/Analyzers/CSharp/Tests/UseSimpleUsingStatement/UseSimpleUsingStatementTests.cs @@ -17,31 +17,102 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseSimpleUsingStatement +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseSimpleUsingStatement; + +using VerifyCS = CSharpCodeFixVerifier< + UseSimpleUsingStatementDiagnosticAnalyzer, + UseSimpleUsingStatementCodeFixProvider>; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] +public class UseSimpleUsingStatementTests { - using VerifyCS = CSharpCodeFixVerifier< - UseSimpleUsingStatementDiagnosticAnalyzer, - UseSimpleUsingStatementCodeFixProvider>; + [Fact] + public async Task TestAboveCSharp8() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void M() + { + [|using|] (var a = {|CS0103:b|}) + { + } + } + } + """, """ + using System; + + class C + { + void M() + { + using var a = {|CS0103:b|}; + } + } + """); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsUseSimpleUsingStatement)] - public class UseSimpleUsingStatementTests + [Fact] + public async Task TestWithOptionOff() { - [Fact] - public async Task TestAboveCSharp8() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System; class C { void M() { - [|using|] (var a = {|CS0103:b|}) + using (var a = {|CS0103:b|}) { } } } - """, """ + """, + Options = + { + { CSharpCodeStyleOptions.PreferSimpleUsingStatement, CodeStyleOption2.FalseWithSilentEnforcement } + } + }.RunAsync(); + } + + [Fact] + public async Task TestMultiDeclaration() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void M() + { + [|using|] ({|CS0819:var a = {|CS0103:b|}, c = {|CS0103:d|}|}) + { + } + } + } + """, """ + using System; + + class C + { + void M() + { + using {|CS0819:var a = {|CS0103:b|}, c = {|CS0103:d|}|}; + } + } + """); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingIfOnSimpleUsingStatement() + { + await new VerifyCS.Test + { + TestCode = """ using System; class C @@ -51,611 +122,576 @@ void M() using var a = {|CS0103:b|}; } } - """); - } + """ + }.RunAsync(); + } - [Fact] - public async Task TestWithOptionOff() + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingPriorToCSharp8() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - using System; + TestCode = """ + using System; - class C + class C + { + void M() { - void M() + using (var a = {|CS0103:b|}) { - using (var a = {|CS0103:b|}) - { - } } } - """, - Options = - { - { CSharpCodeStyleOptions.PreferSimpleUsingStatement, CodeStyleOption2.FalseWithSilentEnforcement } } - }.RunAsync(); - } + """, + LanguageVersion = LanguageVersion.CSharp7_2 + }.RunAsync(); + } - [Fact] - public async Task TestMultiDeclaration() + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingIfExpressionUsing() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System; class C { void M() { - [|using|] ({|CS0819:var a = {|CS0103:b|}, c = {|CS0103:d|}|}) + using ({|CS0103:a|}) { } } } - """, """ + """ + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestMissingIfCodeFollows() + { + await new VerifyCS.Test + { + TestCode = """ using System; class C { void M() { - using {|CS0819:var a = {|CS0103:b|}, c = {|CS0103:d|}|}; + using (var a = {|CS0103:b|}) + { + } + Console.WriteLine(); } } - """); - } + """ + }.RunAsync(); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingIfOnSimpleUsingStatement() - { - await new VerifyCS.Test - { - TestCode = """ - using System; + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestAsyncUsing() + { + // not actually legal code. + await VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Threading.Tasks; - class C + class C + { + void M() + { + {|CS0103:async|} {|CS1002:[|using|]|} (var a = {|CS0103:b|}) { - void M() - { - using var a = {|CS0103:b|}; - } } - """ - }.RunAsync(); - } + } + } + """, """ + using System; + using System.Threading.Tasks; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingPriorToCSharp8() - { - await new VerifyCS.Test + class C { - TestCode = """ - using System; + void M() + { + {|CS0103:async|} {|CS1002:using|} var a = {|CS0103:b|}; + } + } + """); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] + public async Task TestAwaitUsing() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Threading.Tasks; - class C + class C + { + void M() + { + {|CS4033:await|} [|using|] (var a = {|CS0103:b|}) { - void M() - { - using (var a = {|CS0103:b|}) - { - } - } } - """, - LanguageVersion = LanguageVersion.CSharp7_2 - }.RunAsync(); - } + } + } + """, """ + using System; + using System.Threading.Tasks; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingIfExpressionUsing() - { - await new VerifyCS.Test + class C { - TestCode = """ - using System; + void M() + { + {|CS4033:await|} using var a = {|CS0103:b|}; + } + } + """); + } + + [Fact] + public async Task TestWithBlockBodyWithContents() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() + { + [|using|] (var a = {|CS0103:b|}) { - void M() - { - using ({|CS0103:a|}) - { - } - } + Console.WriteLine(a); } - """ - }.RunAsync(); - } + } + } + """, """ + using System; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestMissingIfCodeFollows() - { - await new VerifyCS.Test + class C + { + void M() + { + using var a = {|CS0103:b|}; + Console.WriteLine(a); + } + } + """); + } + + [Fact] + public async Task TestWithNonBlockBody() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void M() + { + [|using|] (var a = {|CS0103:b|}) + Console.WriteLine(a); + } + } + """, """ + using System; + + class C { - TestCode = """ - using System; + void M() + { + using var a = {|CS0103:b|}; + Console.WriteLine(a); + } + } + """); + } + + [Fact] + public async Task TestMultiUsing() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() + { + [|using|] (var a = {|CS0103:b|}) + using (var c = {|CS0103:d|}) { - void M() - { - using (var a = {|CS0103:b|}) - { - } - Console.WriteLine(); - } + Console.WriteLine(a); } - """ - }.RunAsync(); - } + } + } + """, """ + using System; - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestAsyncUsing() - { - // not actually legal code. - await VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Threading.Tasks; + class C + { + void M() + { + using var a = {|CS0103:b|}; + using var c = {|CS0103:d|}; + Console.WriteLine(a); + } + } + """); + } - class C + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void M() { - void M() + [|using|] (var a = {|CS0103:b|}) { - {|CS0103:async|} {|CS1002:[|using|]|} (var a = {|CS0103:b|}) + [|using|] (var c = {|CS0103:d|}) { + Console.WriteLine(a); } } } - """, """ - using System; - using System.Threading.Tasks; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - {|CS0103:async|} {|CS1002:using|} var a = {|CS0103:b|}; - } + using var a = {|CS0103:b|}; + using var c = {|CS0103:d|}; + Console.WriteLine(a); } - """); - } + } + """); + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)] - public async Task TestAwaitUsing() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Threading.Tasks; + [Fact] + public async Task TestFixAll2() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() + [|using|] (var a = {|CS0103:b|}) + using (var c = {|CS0103:d|}) { - {|CS4033:await|} [|using|] (var a = {|CS0103:b|}) + [|using|] (var e = {|CS0103:f|}) + using (var g = {|CS0103:h|}) { + Console.WriteLine(a); } } } - """, """ - using System; - using System.Threading.Tasks; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - {|CS4033:await|} using var a = {|CS0103:b|}; - } + using var a = {|CS0103:b|}; + using var c = {|CS0103:d|}; + using var e = {|CS0103:f|}; + using var g = {|CS0103:h|}; + Console.WriteLine(a); } - """); - } + } + """); + } - [Fact] - public async Task TestWithBlockBodyWithContents() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact] + public async Task TestFixAll3() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() + [|using|] (var a = {|CS0103:b|}) + using (var c = {|CS0103:d|}) { - [|using|] (var a = {|CS0103:b|}) + using ({|CS0103:e|}) + using ({|CS0103:f|}) { Console.WriteLine(a); } } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() + using var a = {|CS0103:b|}; + using var c = {|CS0103:d|}; + using ({|CS0103:e|}) + using ({|CS0103:f|}) { - using var a = {|CS0103:b|}; Console.WriteLine(a); } } - """); - } + } + """); + } - [Fact] - public async Task TestWithNonBlockBody() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact] + public async Task TestFixAll4() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - [|using|] (var a = {|CS0103:b|}) - Console.WriteLine(a); - } + using (var a = {|CS0103:b|}) { } + [|using|] (var c = {|CS0103:d|}) { } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - Console.WriteLine(a); - } + using (var a = {|CS0103:b|}) { } + using var c = {|CS0103:d|}; } - """); - } + } + """); + } - [Fact] - public async Task TestMultiUsing() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact] + public async Task TestWithFollowingReturn() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() + [|using|] (var a = {|CS0103:b|}) { - [|using|] (var a = {|CS0103:b|}) - using (var c = {|CS0103:d|}) - { - Console.WriteLine(a); - } } + return; } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - using var c = {|CS0103:d|}; - Console.WriteLine(a); - } + using var a = {|CS0103:b|}; + return; } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact] + public async Task TestWithFollowingBreak() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() + switch (0) { - [|using|] (var a = {|CS0103:b|}) - { - [|using|] (var c = {|CS0103:d|}) + case 0: { - Console.WriteLine(a); + [|using|] (var a = {|CS0103:b|}) + { + } + break; } - } } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() + switch (0) { - using var a = {|CS0103:b|}; - using var c = {|CS0103:d|}; - Console.WriteLine(a); + case 0: + { + using var a = {|CS0103:b|}; + break; + } } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll2() + [Fact] + public async Task TestMissingInSwitchSection() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System; class C { void M() { - [|using|] (var a = {|CS0103:b|}) - using (var c = {|CS0103:d|}) + switch (0) { - [|using|] (var e = {|CS0103:f|}) - using (var g = {|CS0103:h|}) - { - Console.WriteLine(a); - } + case 0: + using (var a = {|CS0103:b|}) + { + } + break; } } } - """, """ + """ + }.RunAsync(); + } + + [Fact] + public async Task TestMissingWithJumpInsideToOutside() + { + await new VerifyCS.Test + { + TestCode = """ using System; class C { void M() { - using var a = {|CS0103:b|}; - using var c = {|CS0103:d|}; - using var e = {|CS0103:f|}; - using var g = {|CS0103:h|}; - Console.WriteLine(a); + label: + using (var a = {|CS0103:b|}) + { + goto label; + } } } - """); - } + """ + }.RunAsync(); + } - [Fact] - public async Task TestFixAll3() + [Fact] + public async Task TestMissingWithJumpBeforeToAfter() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System; class C { void M() { - [|using|] (var a = {|CS0103:b|}) - using (var c = {|CS0103:d|}) { - using ({|CS0103:e|}) - using ({|CS0103:f|}) + goto label; + using (var a = {|CS0103:b|}) { - Console.WriteLine(a); } } + label:; } } - """, """ - using System; + """ + }.RunAsync(); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestCollision1() + { + await new VerifyCS.Test + { + TestCode = """ + using System.IO; + + class Program { - void M() + static void Main() { - using var a = {|CS0103:b|}; - using var c = {|CS0103:d|}; - using ({|CS0103:e|}) - using ({|CS0103:f|}) + using (Stream stream = File.OpenRead("test")) { - Console.WriteLine(a); } - } - } - """); - } - - [Fact] - public async Task TestFixAll4() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - - class C - { - void M() - { - using (var a = {|CS0103:b|}) { } - [|using|] (var c = {|CS0103:d|}) { } - } - } - """, """ - using System; - - class C - { - void M() - { - using (var a = {|CS0103:b|}) { } - using var c = {|CS0103:d|}; - } - } - """); - } - - [Fact] - public async Task TestWithFollowingReturn() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - - class C - { - void M() - { - [|using|] (var a = {|CS0103:b|}) + using (Stream stream = File.OpenRead("test")) { } - return; - } - } - """, """ - using System; - - class C - { - void M() - { - using var a = {|CS0103:b|}; - return; } } - """); - } + """ + }.RunAsync(); + } - [Fact] - public async Task TestWithFollowingBreak() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestNoCollision1() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; - class C + class Program + { + static void Main() { - void M() + using (Stream stream = File.OpenRead("test")) { - switch (0) - { - case 0: - { - [|using|] (var a = {|CS0103:b|}) - { - } - break; - } - } } - } - """, """ - using System; - - class C - { - void M() + [|using|] (Stream stream1 = File.OpenRead("test")) { - switch (0) - { - case 0: - { - using var a = {|CS0103:b|}; - break; - } - } } } - """); - } - - [Fact] - public async Task TestMissingInSwitchSection() - { - await new VerifyCS.Test - { - TestCode = """ - using System; - - class C - { - void M() - { - switch (0) - { - case 0: - using (var a = {|CS0103:b|}) - { - } - break; - } - } - } - """ - }.RunAsync(); - } - - [Fact] - public async Task TestMissingWithJumpInsideToOutside() - { - await new VerifyCS.Test - { - TestCode = """ - using System; - - class C - { - void M() - { - label: - using (var a = {|CS0103:b|}) - { - goto label; - } - } - } - """ - }.RunAsync(); - } + } + """, """ + using System.IO; - [Fact] - public async Task TestMissingWithJumpBeforeToAfter() - { - await new VerifyCS.Test + class Program { - TestCode = """ - using System; - - class C - { - void M() - { - { - goto label; - using (var a = {|CS0103:b|}) - { - } - } - label:; - } - } - """ - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestCollision1() - { - await new VerifyCS.Test - { - TestCode = """ - using System.IO; - - class Program + static void Main() + { + using (Stream stream = File.OpenRead("test")) { - static void Main() - { - using (Stream stream = File.OpenRead("test")) - { - } - using (Stream stream = File.OpenRead("test")) - { - } - } } - """ - }.RunAsync(); - } + using Stream stream1 = File.OpenRead("test"); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestNoCollision1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestCollision2() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.IO; class Program @@ -665,117 +701,58 @@ static void Main() using (Stream stream = File.OpenRead("test")) { } - [|using|] (Stream stream1 = File.OpenRead("test")) + using (Stream stream1 = File.OpenRead("test")) { + Stream stream; } } } - """, """ - using System.IO; + """ + }.RunAsync(); + } - class Program - { - static void Main() - { - using (Stream stream = File.OpenRead("test")) - { - } - using Stream stream1 = File.OpenRead("test"); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestNoCollision2() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestCollision2() - { - await new VerifyCS.Test + class Program { - TestCode = """ - using System.IO; - - class Program - { - static void Main() - { - using (Stream stream = File.OpenRead("test")) - { - } - using (Stream stream1 = File.OpenRead("test")) - { - Stream stream; - } - } - } - """ - }.RunAsync(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestNoCollision2() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.IO; - - class Program + static void Main() { - static void Main() + using (Stream stream = File.OpenRead("test")) { - using (Stream stream = File.OpenRead("test")) - { - } - [|using|] (Stream stream1 = File.OpenRead("test")) - { - Stream stream2; - } } - } - """, """ - using System.IO; - - class Program - { - static void Main() + [|using|] (Stream stream1 = File.OpenRead("test")) { - using (Stream stream = File.OpenRead("test")) - { - } - using Stream stream1 = File.OpenRead("test"); Stream stream2; } } - """); - } + } + """, """ + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestCollision3() - { - await new VerifyCS.Test + class Program { - TestCode = """ - using System.IO; - - class Program + static void Main() + { + using (Stream stream = File.OpenRead("test")) { - static void Main() - { - using (Stream stream = File.OpenRead("test")) - { - } - using (Stream stream1 = File.OpenRead("test")) - { - {|CS0103:Goo|}(out var stream); - } - } } - """ - }.RunAsync(); - } + using Stream stream1 = File.OpenRead("test"); + Stream stream2; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestNoCollision3() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestCollision3() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.IO; class Program @@ -785,56 +762,58 @@ static void Main() using (Stream stream = File.OpenRead("test")) { } - [|using|] (Stream stream1 = File.OpenRead("test")) + using (Stream stream1 = File.OpenRead("test")) { - {|CS0103:Goo|}(out var stream2); + {|CS0103:Goo|}(out var stream); } } } - """, """ - using System.IO; + """ + }.RunAsync(); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestNoCollision3() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; + + class Program + { + static void Main() { - static void Main() + using (Stream stream = File.OpenRead("test")) + { + } + [|using|] (Stream stream1 = File.OpenRead("test")) { - using (Stream stream = File.OpenRead("test")) - { - } - using Stream stream1 = File.OpenRead("test"); {|CS0103:Goo|}(out var stream2); } } - """); - } + } + """, """ + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestCollision4() - { - await new VerifyCS.Test + class Program { - TestCode = """ - using System.IO; - - class Program + static void Main() + { + using (Stream stream = File.OpenRead("test")) { - static void Main() - { - using (Stream stream = File.OpenRead("test")) - { - } - using (Stream stream1 = File.OpenRead("test")) - {|CS0103:Goo|}(out var stream); - } } - """ - }.RunAsync(); - } + using Stream stream1 = File.OpenRead("test"); + {|CS0103:Goo|}(out var stream2); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestNoCollision4() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestCollision4() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.IO; class Program @@ -844,56 +823,54 @@ static void Main() using (Stream stream = File.OpenRead("test")) { } - [|using|] (Stream stream1 = File.OpenRead("test")) - {|CS0103:Goo|}(out var stream2); + using (Stream stream1 = File.OpenRead("test")) + {|CS0103:Goo|}(out var stream); } } - """, """ - using System.IO; + """ + }.RunAsync(); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestNoCollision4() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; + + class Program + { + static void Main() { - static void Main() + using (Stream stream = File.OpenRead("test")) { - using (Stream stream = File.OpenRead("test")) - { - } - using Stream stream1 = File.OpenRead("test"); - {|CS0103:Goo|}(out var stream2); } + [|using|] (Stream stream1 = File.OpenRead("test")) + {|CS0103:Goo|}(out var stream2); } - """); - } + } + """, """ + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestCollision5() - { - await new VerifyCS.Test + class Program { - TestCode = """ - using System.IO; - - class Program + static void Main() + { + using (Stream stream = File.OpenRead("test")) { - static void Main() - { - using (Stream stream = File.OpenRead("test")) - { - Stream stream1; - } - using (Stream stream1 = File.OpenRead("test")) - { - } - } } - """ - }.RunAsync(); - } + using Stream stream1 = File.OpenRead("test"); + {|CS0103:Goo|}(out var stream2); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] - public async Task TestNoCollision5() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestCollision5() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.IO; class Program @@ -904,449 +881,455 @@ static void Main() { Stream stream1; } - [|using|] (Stream stream2 = File.OpenRead("test")) + using (Stream stream1 = File.OpenRead("test")) { } } } - """, """ - using System.IO; + """ + }.RunAsync(); + } - class Program + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35879")] + public async Task TestNoCollision5() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; + + class Program + { + static void Main() { - static void Main() + using (Stream stream = File.OpenRead("test")) + { + Stream stream1; + } + [|using|] (Stream stream2 = File.OpenRead("test")) { - using (Stream stream = File.OpenRead("test")) - { - Stream stream1; - } - using Stream stream2 = File.OpenRead("test"); } } - """); - } + } + """, """ + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37678")] - public async Task TestCopyTrivia() - { - await VerifyCS.VerifyCodeFixAsync(""" - class Program + class Program + { + static void Main() { - static void Main(string[] args) + using (Stream stream = File.OpenRead("test")) { - [|using|] (var x = {|CS0103:y|}) - { - // comment - } + Stream stream1; } + using Stream stream2 = File.OpenRead("test"); } - """, """ - class Program + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37678")] + public async Task TestCopyTrivia() + { + await VerifyCS.VerifyCodeFixAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + [|using|] (var x = {|CS0103:y|}) { - using var x = {|CS0103:y|}; // comment } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37678")] - public async Task TestMultiCopyTrivia() - { - await VerifyCS.VerifyCodeFixAsync(""" - class Program + } + """, """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - [|using|] (var x = {|CS0103:y|}) - using (var a = {|CS0103:b|}) - { - // comment - } - } + using var x = {|CS0103:y|}; + // comment } - """, """ - class Program + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37678")] + public async Task TestMultiCopyTrivia() + { + await VerifyCS.VerifyCodeFixAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + [|using|] (var x = {|CS0103:y|}) + using (var a = {|CS0103:b|}) { - using var x = {|CS0103:y|}; - using var a = {|CS0103:b|}; // comment } } - """); - } + } + """, """ + class Program + { + static void Main(string[] args) + { + using var x = {|CS0103:y|}; + using var a = {|CS0103:b|}; + // comment + } + } + """); + } - [Fact] - public async Task TestFixAll_WithTrivia() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact] + public async Task TestFixAll_WithTrivia() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() + [|using|] (var a = {|CS0103:b|}) { - [|using|] (var a = {|CS0103:b|}) + [|using|] (var c = {|CS0103:d|}) { - [|using|] (var c = {|CS0103:d|}) - { - Console.WriteLine(a); - // comment1 - } - // comment2 + Console.WriteLine(a); + // comment1 } + // comment2 } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - using var c = {|CS0103:d|}; - Console.WriteLine(a); - // comment1 - // comment2 - } + using var a = {|CS0103:b|}; + using var c = {|CS0103:d|}; + Console.WriteLine(a); + // comment1 + // comment2 } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] - public async Task TestCopyCompilerDirectiveTrivia() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] + public async Task TestCopyCompilerDirectiveTrivia() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + static void M() { - static void M() + [|using|] (var obj = Dummy()) { - [|using|] (var obj = Dummy()) - { - #pragma warning disable CS0618, CS0612 - #if !FOO - LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - } + #pragma warning disable CS0618, CS0612 + #if !FOO + LegacyMethod(); + #endif + #pragma warning restore CS0618, CS0612 } - - static IDisposable Dummy() => throw new NotImplementedException(); - - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); } - """, """ - using System; - class C - { - static void M() - { - using var obj = Dummy(); - #pragma warning disable CS0618, CS0612 - #if !FOO - LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - } + static IDisposable Dummy() => throw new NotImplementedException(); - static IDisposable Dummy() => throw new NotImplementedException(); + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """, """ + using System; - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); + class C + { + static void M() + { + using var obj = Dummy(); + #pragma warning disable CS0618, CS0612 + #if !FOO + LegacyMethod(); + #endif + #pragma warning restore CS0618, CS0612 } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] - public async Task TestCopyCompilerDirectiveAndCommentTrivia_AfterRestore() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - class C - { - static void M() - { - [|using|] (var obj = Dummy()) - { - #pragma warning disable CS0618, CS0612 - #if !FOO - LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - // comment - } - } + static IDisposable Dummy() => throw new NotImplementedException(); - static IDisposable Dummy() => throw new NotImplementedException(); + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """); + } - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); - } - """, """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] + public async Task TestCopyCompilerDirectiveAndCommentTrivia_AfterRestore() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + static void M() { - static void M() + [|using|] (var obj = Dummy()) { - using var obj = Dummy(); - #pragma warning disable CS0618, CS0612 - #if !FOO + #pragma warning disable CS0618, CS0612 + #if !FOO LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - // comment + #endif + #pragma warning restore CS0618, CS0612 + // comment } - - static IDisposable Dummy() => throw new NotImplementedException(); - - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] - public async Task TestCopyCompilerDirectiveAndCommentTrivia_BeforeRestore() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + static IDisposable Dummy() => throw new NotImplementedException(); - class C + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """, """ + using System; + + class C + { + static void M() { - static void M() - { - [|using|] (var obj = Dummy()) - { - #pragma warning disable CS0618, CS0612 - #if !FOO - LegacyMethod(); - // comment - #endif - #pragma warning restore CS0618, CS0612 - } - } + using var obj = Dummy(); + #pragma warning disable CS0618, CS0612 + #if !FOO + LegacyMethod(); + #endif + #pragma warning restore CS0618, CS0612 + // comment + } - static IDisposable Dummy() => throw new NotImplementedException(); + static IDisposable Dummy() => throw new NotImplementedException(); - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); - } - """, """ - using System; + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] + public async Task TestCopyCompilerDirectiveAndCommentTrivia_BeforeRestore() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + static void M() { - static void M() + [|using|] (var obj = Dummy()) { - using var obj = Dummy(); - #pragma warning disable CS0618, CS0612 - #if !FOO + #pragma warning disable CS0618, CS0612 + #if !FOO LegacyMethod(); // comment - #endif - #pragma warning restore CS0618, CS0612 + #endif + #pragma warning restore CS0618, CS0612 } - - static IDisposable Dummy() => throw new NotImplementedException(); - - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] - public async Task TestCopyCompilerDirectiveAndCommentTrivia_AfterDisable() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + static IDisposable Dummy() => throw new NotImplementedException(); - class C + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """, """ + using System; + + class C + { + static void M() { - static void M() - { - [|using|] (var obj = Dummy()) - { - #pragma warning disable CS0618, CS0612 - #if !FOO - // comment - LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - } - } + using var obj = Dummy(); + #pragma warning disable CS0618, CS0612 + #if !FOO + LegacyMethod(); + // comment + #endif + #pragma warning restore CS0618, CS0612 + } - static IDisposable Dummy() => throw new NotImplementedException(); + static IDisposable Dummy() => throw new NotImplementedException(); - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); - } - """, """ - using System; + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] + public async Task TestCopyCompilerDirectiveAndCommentTrivia_AfterDisable() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + static void M() { - static void M() + [|using|] (var obj = Dummy()) { - using var obj = Dummy(); - #pragma warning disable CS0618, CS0612 - #if !FOO + #pragma warning disable CS0618, CS0612 + #if !FOO // comment LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 + #endif + #pragma warning restore CS0618, CS0612 } - - static IDisposable Dummy() => throw new NotImplementedException(); - - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] - public async Task TestCopyCompilerDirectiveAndCommentTrivia_BeforeDisable() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + static IDisposable Dummy() => throw new NotImplementedException(); - class C + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """, """ + using System; + + class C + { + static void M() { - static void M() - { - [|using|] (var obj = Dummy()) - { - // comment - #pragma warning disable CS0618, CS0612 - #if !FOO - LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - } - } + using var obj = Dummy(); + #pragma warning disable CS0618, CS0612 + #if !FOO + // comment + LegacyMethod(); + #endif + #pragma warning restore CS0618, CS0612 + } - static IDisposable Dummy() => throw new NotImplementedException(); + static IDisposable Dummy() => throw new NotImplementedException(); - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); - } - """, """ - using System; + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] + public async Task TestCopyCompilerDirectiveAndCommentTrivia_BeforeDisable() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + static void M() { - static void M() + [|using|] (var obj = Dummy()) { - using var obj = Dummy(); // comment - #pragma warning disable CS0618, CS0612 - #if !FOO + #pragma warning disable CS0618, CS0612 + #if !FOO LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 + #endif + #pragma warning restore CS0618, CS0612 } - - static IDisposable Dummy() => throw new NotImplementedException(); - - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] - public async Task TestCopyCompilerDirectiveTrivia_PreserveCodeBeforeAndAfterDirective() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + static IDisposable Dummy() => throw new NotImplementedException(); - class C + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """, """ + using System; + + class C + { + static void M() { - static void M() - { - [|using|] (var obj = Dummy()) - { - LegacyMethod(); - #pragma warning disable CS0618, CS0612 - #if !FOO - LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 - LegacyMethod(); - } - } + using var obj = Dummy(); + // comment + #pragma warning disable CS0618, CS0612 + #if !FOO + LegacyMethod(); + #endif + #pragma warning restore CS0618, CS0612 + } - static IDisposable Dummy() => throw new NotImplementedException(); + static IDisposable Dummy() => throw new NotImplementedException(); - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); - } - """, """ - using System; + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38737")] + public async Task TestCopyCompilerDirectiveTrivia_PreserveCodeBeforeAndAfterDirective() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + static void M() { - static void M() + [|using|] (var obj = Dummy()) { - using var obj = Dummy(); LegacyMethod(); - #pragma warning disable CS0618, CS0612 - #if !FOO + #pragma warning disable CS0618, CS0612 + #if !FOO LegacyMethod(); - #endif - #pragma warning restore CS0618, CS0612 + #endif + #pragma warning restore CS0618, CS0612 LegacyMethod(); } - - static IDisposable Dummy() => throw new NotImplementedException(); - - [Obsolete] - static void LegacyMethod() => throw new NotImplementedException(); } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38842")] - public async Task TestNextLineIndentation1() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + static IDisposable Dummy() => throw new NotImplementedException(); - class C + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """, """ + using System; + + class C + { + static void M() { - void Goo(IDisposable disposable) - { - [|using|] (var v = disposable) - { - {|CS0103:Bar|}(1, - 2, - 3); - {|CS1501:Goo|}(1, - 2, - 3); - } - } + using var obj = Dummy(); + LegacyMethod(); + #pragma warning disable CS0618, CS0612 + #if !FOO + LegacyMethod(); + #endif + #pragma warning restore CS0618, CS0612 + LegacyMethod(); } - """, """ - using System; - class C + static IDisposable Dummy() => throw new NotImplementedException(); + + [Obsolete] + static void LegacyMethod() => throw new NotImplementedException(); + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38842")] + public async Task TestNextLineIndentation1() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void Goo(IDisposable disposable) { - void Goo(IDisposable disposable) + [|using|] (var v = disposable) { - using var v = disposable; {|CS0103:Bar|}(1, 2, 3); @@ -1355,570 +1338,586 @@ void Goo(IDisposable disposable) 3); } } - """); - } + } + """, """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38842")] - public async Task TestNextLineIndentation2() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.IO; + class C + { + void Goo(IDisposable disposable) + { + using var v = disposable; + {|CS0103:Bar|}(1, + 2, + 3); + {|CS1501:Goo|}(1, + 2, + 3); + } + } + """); + } - class C - { - static void Main() - { - [|using|] (var stream = new MemoryStream()) - { - _ = new Action( - () => { } - ); - } - } - } - """, """ - using System; - using System.IO; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38842")] + public async Task TestNextLineIndentation2() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.IO; - class C + class C + { + static void Main() { - static void Main() + [|using|] (var stream = new MemoryStream()) { - using var stream = new MemoryStream(); _ = new Action( - () => { } - ); - } - } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48586")] - public async Task TestKeepSurroundingComments() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - - class C - { - void M() - { - [|using|] (var a = {|CS0103:b|}) - { // Make sure that... - Console.WriteLine({|CS0103:s|}.CanRead); - } // ...all comments remain + () => { } + ); } } - """, """ - using System; + } + """, """ + using System; + using System.IO; - class C + class C + { + static void Main() { - void M() - { - using var a = {|CS0103:b|}; - // Make sure that... - Console.WriteLine({|CS0103:s|}.CanRead); - // ...all comments remain - } + using var stream = new MemoryStream(); + _ = new Action( + () => { } + ); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48586")] - public async Task TestKeepSurroundingComments2() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48586")] + public async Task TestKeepSurroundingComments() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - // Make... - [|using|] (var a = {|CS0103:b|}) // ...sure... - { // ...that... - Console.WriteLine({|CS0103:s|}.CanRead); // ...all... - } // ...comments... - // ...remain - } + [|using|] (var a = {|CS0103:b|}) + { // Make sure that... + Console.WriteLine({|CS0103:s|}.CanRead); + } // ...all comments remain } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - // Make... - using var a = {|CS0103:b|}; // ...sure... - // ...that... - Console.WriteLine({|CS0103:s|}.CanRead); // ...all... - // ...comments... - // ...remain - } + using var a = {|CS0103:b|}; + // Make sure that... + Console.WriteLine({|CS0103:s|}.CanRead); + // ...all comments remain } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48586")] - public async Task TestKeepSurroundingComments3() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48586")] + public async Task TestKeepSurroundingComments2() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - // Make... - [|using|] (var a = {|CS0103:b|}) // ...sure... - using (var c = {|CS0103:d|}) // ...that... - // ...really... - using (var e = {|CS0103:f|}) // ...all... - { // ...comments... - Console.WriteLine({|CS0103:s|}.CanRead); // ...are... - } // ...kept... - // ...during... - // ...transformation - } - } - """, """ - using System; + // Make... + [|using|] (var a = {|CS0103:b|}) // ...sure... + { // ...that... + Console.WriteLine({|CS0103:s|}.CanRead); // ...all... + } // ...comments... + // ...remain + } + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - // Make... - using var a = {|CS0103:b|}; // ...sure... - using var c = {|CS0103:d|}; // ...that... - // ...really... - using var e = {|CS0103:f|}; // ...all... - // ...comments... + // Make... + using var a = {|CS0103:b|}; // ...sure... + // ...that... + Console.WriteLine({|CS0103:s|}.CanRead); // ...all... + // ...comments... + // ...remain + } + } + """); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48586")] + public async Task TestKeepSurroundingComments3() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void M() + { + // Make... + [|using|] (var a = {|CS0103:b|}) // ...sure... + using (var c = {|CS0103:d|}) // ...that... + // ...really... + using (var e = {|CS0103:f|}) // ...all... + { // ...comments... Console.WriteLine({|CS0103:s|}.CanRead); // ...are... - // ...kept... - // ...during... - // ...transformation - } + } // ...kept... + // ...during... + // ...transformation } - """); - } + } + """, """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] - public async Task TestWithBlockBodyWithOpeningBracketOnSameLine() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + class C + { + void M() + { + // Make... + using var a = {|CS0103:b|}; // ...sure... + using var c = {|CS0103:d|}; // ...that... + // ...really... + using var e = {|CS0103:f|}; // ...all... + // ...comments... + Console.WriteLine({|CS0103:s|}.CanRead); // ...are... + // ...kept... + // ...during... + // ...transformation + } + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] + public async Task TestWithBlockBodyWithOpeningBracketOnSameLine() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + + class C + { + void M() { - void M() - { - [|using|] (var a = {|CS0103:b|}){ - Console.WriteLine(a); - } + [|using|] (var a = {|CS0103:b|}){ + Console.WriteLine(a); } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - Console.WriteLine(a); - } + using var a = {|CS0103:b|}; + Console.WriteLine(a); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] - public async Task TestWithBlockBodyWithOpeningBracketOnSameLine2() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] + public async Task TestWithBlockBodyWithOpeningBracketOnSameLine2() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - [|using|] (var a = {|CS0103:b|}) { - Console.WriteLine(a); - } + [|using|] (var a = {|CS0103:b|}) { + Console.WriteLine(a); } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - Console.WriteLine(a); - } + using var a = {|CS0103:b|}; + Console.WriteLine(a); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] - public async Task TestWithBlockBodyWithOpeningBracketAndCommentOnSameLine() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] + public async Task TestWithBlockBodyWithOpeningBracketAndCommentOnSameLine() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - [|using|] (var a = {|CS0103:b|}) { //comment - Console.WriteLine(a); - } + [|using|] (var a = {|CS0103:b|}) { //comment + Console.WriteLine(a); } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; //comment - Console.WriteLine(a); - } + using var a = {|CS0103:b|}; //comment + Console.WriteLine(a); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] - public async Task TestWithBlockBodyWithOpeningBracketOnSameLineWithNoStatements() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] + public async Task TestWithBlockBodyWithOpeningBracketOnSameLineWithNoStatements() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - [|using|] (var a = {|CS0103:b|}) { - } + [|using|] (var a = {|CS0103:b|}) { } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - } + using var a = {|CS0103:b|}; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] - public async Task TestWithBlockBodyWithOpeningBracketOnSameLineAndCommentInBlock() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52970")] + public async Task TestWithBlockBodyWithOpeningBracketOnSameLineAndCommentInBlock() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; - class C + class C + { + void M() { - void M() - { - [|using|] (var a = {|CS0103:b|}) { - // intentionally empty - } + [|using|] (var a = {|CS0103:b|}) { + // intentionally empty } } - """, """ - using System; + } + """, """ + using System; - class C + class C + { + void M() { - void M() - { - using var a = {|CS0103:b|}; - // intentionally empty - } + using var a = {|CS0103:b|}; + // intentionally empty } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58911")] - public async Task TestUsingWithoutSpace() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58911")] + public async Task TestUsingWithoutSpace() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System; + using System.Collections.Generic; - public class Test + public class Test + { + public IEnumerable Collection { get; } = new[] { - public IEnumerable Collection { get; } = new[] + new Test() { - new Test() + Prop = () => { - Prop = () => + [|using|](var x = Get()) { - [|using|](var x = Get()) - { - int i = 0; - } + int i = 0; } } - }; + } + }; - public Action Prop { get; set; } - public static IDisposable Get() => throw new NotImplementedException(); - } - """, """ - using System; - using System.Collections.Generic; + public Action Prop { get; set; } + public static IDisposable Get() => throw new NotImplementedException(); + } + """, """ + using System; + using System.Collections.Generic; - public class Test + public class Test + { + public IEnumerable Collection { get; } = new[] { - public IEnumerable Collection { get; } = new[] + new Test() { - new Test() + Prop = () => { - Prop = () => - { - using var x = Get(); - int i = 0; - } + using var x = Get(); + int i = 0; } - }; + } + }; - public Action Prop { get; set; } - public static IDisposable Get() => throw new NotImplementedException(); - } - """); - } + public Action Prop { get; set; } + public static IDisposable Get() => throw new NotImplementedException(); + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] - public async Task TestWithConstantReturn1() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.IO; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] + public async Task TestWithConstantReturn1() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; - class C + class C + { + bool M() { - bool M() + [|using|] (var foo = new MemoryStream()) { - [|using|] (var foo = new MemoryStream()) - { - } - - return true; } - } - """, """ - using System.IO; - - class C - { - bool M() - { - using var foo = new MemoryStream(); - return true; - } + return true; } - """); - } + } + """, """ + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] - public async Task TestWithNonConstantReturn1() - { - await new VerifyCS.Test + class C { - TestCode = """ - using System.IO; - - class C - { - bool M(int a, int b) - { - using (var foo = new MemoryStream()) - { - } + bool M() + { + using var foo = new MemoryStream(); - return a > b; - } - } - """ - }.RunAsync(); - } + return true; + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] - public async Task TestWithLocalFunctions1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] + public async Task TestWithNonConstantReturn1() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.IO; class C { - void M() + bool M(int a, int b) { - [|using|] (var foo = new MemoryStream()) + using (var foo = new MemoryStream()) { } - void Inner1() { } - void Inner2() { } + return a > b; } } - """, """ - using System.IO; + """ + }.RunAsync(); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] + public async Task TestWithLocalFunctions1() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; + + class C + { + void M() { - void M() + [|using|] (var foo = new MemoryStream()) { - using var foo = new MemoryStream(); - - void Inner1() { } - void Inner2() { } } + + void Inner1() { } + void Inner2() { } } - """); - } + } + """, """ + using System.IO; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] - public async Task TestWithLocalFunctions2() - { - await new VerifyCS.Test + class C { - TestCode = """ - using System.IO; - - class C - { - bool M(int a, int b) - { - using (var foo = new MemoryStream()) - { - } - - void Inner1() { } - void Inner2() { } + void M() + { + using var foo = new MemoryStream(); - return a > b; - } - } - """ - }.RunAsync(); - } + void Inner1() { } + void Inner2() { } + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] - public async Task TestWithLocalFunctionsAndConstantReturn() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] + public async Task TestWithLocalFunctions2() + { + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync(""" + TestCode = """ using System.IO; class C { bool M(int a, int b) { - [|using|] (var foo = new MemoryStream()) + using (var foo = new MemoryStream()) { } void Inner1() { } void Inner2() { } - return true; + return a > b; } } - """, """ - using System.IO; + """ + }.RunAsync(); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42194")] + public async Task TestWithLocalFunctionsAndConstantReturn() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.IO; + + class C + { + bool M(int a, int b) { - bool M(int a, int b) + [|using|] (var foo = new MemoryStream()) { - using var foo = new MemoryStream(); + } - void Inner1() { } - void Inner2() { } + void Inner1() { } + void Inner2() { } - return true; - } + return true; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58861")] - public async Task TestOpenBraceTrivia1() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Security.Cryptography; + } + """, """ + using System.IO; - class C + class C + { + bool M(int a, int b) { - public static byte[] ComputeMD5Hash(byte[] source) - { - #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms - [|using|] (var md5 = MD5.Create()) - #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms - { - return md5.ComputeHash(source); - } - } + using var foo = new MemoryStream(); + + void Inner1() { } + void Inner2() { } + + return true; } - """, """ - using System.Security.Cryptography; + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58861")] + public async Task TestOpenBraceTrivia1() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Security.Cryptography; + + class C + { + public static byte[] ComputeMD5Hash(byte[] source) { - public static byte[] ComputeMD5Hash(byte[] source) + #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms + [|using|] (var md5 = MD5.Create()) + #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms { - #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms - using var md5 = MD5.Create(); - #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms return md5.ComputeHash(source); } } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58861")] - public async Task TestOpenBraceTrivia2() - { - await VerifyCS.VerifyCodeFixAsync(""" - using System.Security.Cryptography; + } + """, """ + using System.Security.Cryptography; - class C + class C + { + public static byte[] ComputeMD5Hash(byte[] source) { - public static byte[] ComputeMD5Hash(byte[] source) - { - #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms - [|using|] (var md5 = MD5.Create()) - #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms - { // comment - return md5.ComputeHash(source); - } - } + #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms + using var md5 = MD5.Create(); + #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms + return md5.ComputeHash(source); } - """, """ - using System.Security.Cryptography; + } + """); + } - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58861")] + public async Task TestOpenBraceTrivia2() + { + await VerifyCS.VerifyCodeFixAsync(""" + using System.Security.Cryptography; + + class C + { + public static byte[] ComputeMD5Hash(byte[] source) { - public static byte[] ComputeMD5Hash(byte[] source) - { - #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms - using var md5 = MD5.Create(); - #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms - // comment + #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms + [|using|] (var md5 = MD5.Create()) + #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms + { // comment return md5.ComputeHash(source); } } - """); - } + } + """, """ + using System.Security.Cryptography; + + class C + { + public static byte[] ComputeMD5Hash(byte[] source) + { + #pragma warning disable CA5351 // Do Not Use Broken Cryptographic Algorithms + using var md5 = MD5.Create(); + #pragma warning restore CA5351 // Do Not Use Broken Cryptographic Algorithms + // comment + return md5.ComputeHash(source); + } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseSystemHashCode/UseSystemHashCodeTests.cs b/src/Analyzers/CSharp/Tests/UseSystemHashCode/UseSystemHashCodeTests.cs index b5c45e4922ea7..cddd2183bc66c 100644 --- a/src/Analyzers/CSharp/Tests/UseSystemHashCode/UseSystemHashCodeTests.cs +++ b/src/Analyzers/CSharp/Tests/UseSystemHashCode/UseSystemHashCodeTests.cs @@ -13,252 +13,210 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseSystemHashCode +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseSystemHashCode; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseSystemHashCode)] +public partial class UseSystemHashCodeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseSystemHashCode)] - public partial class UseSystemHashCodeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseSystemHashCodeTests(ITestOutputHelper logger) + : base(logger) { - public UseSystemHashCodeTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new UseSystemHashCodeDiagnosticAnalyzer(), new UseSystemHashCodeCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new UseSystemHashCodeDiagnosticAnalyzer(), new UseSystemHashCodeCodeFixProvider()); + + [Fact] + public async Task TestDerivedClassWithFieldWithBase() + { + await TestInRegularAndScript1Async( + """ + namespace System { public struct HashCode { } } - [Fact] - public async Task TestDerivedClassWithFieldWithBase() - { - await TestInRegularAndScript1Async( - """ - namespace System { public struct HashCode { } } + class B + { + public override int GetHashCode() => 0; + } - class B + class C : B + { + int j; + + public override int $$GetHashCode() { - public override int GetHashCode() => 0; + var hashCode = 339610899; + hashCode = hashCode * -1521134295 + base.GetHashCode(); + hashCode = hashCode * -1521134295 + j.GetHashCode(); + return hashCode; } + } + """, + """ + namespace System { public struct HashCode { } } - class C : B - { - int j; + class B + { + public override int GetHashCode() => 0; + } - public override int $$GetHashCode() - { - var hashCode = 339610899; - hashCode = hashCode * -1521134295 + base.GetHashCode(); - hashCode = hashCode * -1521134295 + j.GetHashCode(); - return hashCode; - } - } - """, - """ - namespace System { public struct HashCode { } } + class C : B + { + int j; - class B + public override int GetHashCode() { - public override int GetHashCode() => 0; + return System.HashCode.Combine(base.GetHashCode(), j); } + } + """); + } - class C : B - { - int j; + [Fact] + public async Task TestDerivedClassWithFieldWithNoBase() + { + await TestInRegularAndScript1Async( + """ + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(base.GetHashCode(), j); - } - } - """); - } + class B + { + public override int GetHashCode() => 0; + } - [Fact] - public async Task TestDerivedClassWithFieldWithNoBase() - { - await TestInRegularAndScript1Async( - """ - namespace System { public struct HashCode { } } + class C : B + { + int j; - class B + public override int $$GetHashCode() { - public override int GetHashCode() => 0; + var hashCode = 339610899; + hashCode = hashCode * -1521134295 + j.GetHashCode(); + return hashCode; } + } + """, + """ + namespace System { public struct HashCode { } } - class C : B - { - int j; + class B + { + public override int GetHashCode() => 0; + } - public override int $$GetHashCode() - { - var hashCode = 339610899; - hashCode = hashCode * -1521134295 + j.GetHashCode(); - return hashCode; - } - } - """, - """ - namespace System { public struct HashCode { } } + class C : B + { + int j; - class B + public override int GetHashCode() { - public override int GetHashCode() => 0; + return System.HashCode.Combine(j); } + } + """); + } - class C : B - { - int j; + [Fact] + public async Task TestDerivedClassWithNoFieldWithBase() + { + await TestInRegularAndScript1Async( + """ + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(j); - } - } - """); - } + class B + { + public override int GetHashCode() => 0; + } - [Fact] - public async Task TestDerivedClassWithNoFieldWithBase() - { - await TestInRegularAndScript1Async( - """ - namespace System { public struct HashCode { } } + class C : B + { + int j; - class B + public override int $$GetHashCode() { - public override int GetHashCode() => 0; + var hashCode = 339610899; + hashCode = hashCode * -1521134295 + base.GetHashCode(); + return hashCode; } + } + """, + """ + namespace System { public struct HashCode { } } - class C : B - { - int j; + class B + { + public override int GetHashCode() => 0; + } - public override int $$GetHashCode() - { - var hashCode = 339610899; - hashCode = hashCode * -1521134295 + base.GetHashCode(); - return hashCode; - } - } - """, - """ - namespace System { public struct HashCode { } } + class C : B + { + int j; - class B + public override int GetHashCode() { - public override int GetHashCode() => 0; + return System.HashCode.Combine(base.GetHashCode()); } + } + """); + } - class C : B - { - int j; + [Fact] + public async Task TestFieldAndProp() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(base.GetHashCode()); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestFieldAndProp() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; - - string S { get; } - - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string S { get; } + string S { get; } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } - - [Fact] - public async Task TestUnchecked() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } - - class C + public override int GetHashCode() { - int i; - - string S { get; } - - public override int $$GetHashCode() - { - unchecked - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } + return System.HashCode.Combine(i, S); } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } - - class C - { - int i; + } + """); + } - string S { get; } + [Fact] + public async Task TestUnchecked() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestNotOnNonGetHashCode() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; - - string S { get; } - - public override int $$GetHashCode1() + unchecked { var hashCode = -538000506; hashCode = hashCode * -1521134295 + i.GetHashCode(); @@ -266,1186 +224,1227 @@ class C return hashCode; } } - """); - } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - [Fact] - public async Task TestNotWithoutReturn() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - class C + string S { get; } + + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string S { get; } + [Fact] + public async Task TestNotOnNonGetHashCode() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestNotWithoutLocal() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode1() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """); + } - string S { get; } + [Fact] + public async Task TestNotWithoutReturn() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestNotWithMultipleLocals() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + } + } + """); + } - string S { get; } + [Fact] + public async Task TestNotWithoutLocal() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - var hashCode = -538000506, x; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestNotWithoutInitializer() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """); + } - string S { get; } + [Fact] + public async Task TestNotWithMultipleLocals() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - var hashCode; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestNotReturningAccumulator() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506, x; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """); + } - string S { get; } + [Fact] + public async Task TestNotWithoutInitializer() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return 0; - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestAcumulatorInitializedToField() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """); + } + + [Fact] + public async Task TestNotReturningAccumulator() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string S { get; } + class C + { + int i; - public override int $$GetHashCode() - { - var hashCode = i; - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return 0; + } + } + """); + } - string S { get; } + [Fact] + public async Task TestAcumulatorInitializedToField() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestAcumulatorInitializedToHashedField() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = i; + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string S { get; } + class C + { + int i; - public override int $$GetHashCode() - { - var hashCode = i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string S { get; } + [Fact] + public async Task TestAcumulatorInitializedToHashedField() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestMissingOnThisGetHashCode() - { - await TestMissingAsync( - """ - namespace System { public struct HashCode { } } + string S { get; } - class B + public override int $$GetHashCode() { - public override int GetHashCode() => 0; + var hashCode = i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C : B - { - int j; + class C + { + int i; - public override int $$GetHashCode() - { - var hashCode = 339610899; - hashCode = hashCode * -1521134295 + this.GetHashCode(); - hashCode = hashCode * -1521134295 + j.GetHashCode(); - return hashCode; - } - } - """); - } + string S { get; } - [Fact] - public async Task TestMissingWithNoSystemHashCode() - { - await TestMissingAsync( - """ - class B + public override int GetHashCode() { - public override int GetHashCode() => 0; + return System.HashCode.Combine(i, S); } + } + """); + } - class C : B - { - int j; + [Fact] + public async Task TestMissingOnThisGetHashCode() + { + await TestMissingAsync( + """ + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - var hashCode = 339610899; - hashCode = hashCode * -1521134295 + base.GetHashCode(); - hashCode = hashCode * -1521134295 + j.GetHashCode(); - return hashCode; - } - } - """); - } + class B + { + public override int GetHashCode() => 0; + } - [Fact] - public async Task TestDirectNullCheck1() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C : B + { + int j; - class C + public override int $$GetHashCode() { - int i; - - string S { get; } - - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + (S != null ? S.GetHashCode() : 0); - return hashCode; - } + var hashCode = 339610899; + hashCode = hashCode * -1521134295 + this.GetHashCode(); + hashCode = hashCode * -1521134295 + j.GetHashCode(); + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """); + } - class C - { - int i; + [Fact] + public async Task TestMissingWithNoSystemHashCode() + { + await TestMissingAsync( + """ + class B + { + public override int GetHashCode() => 0; + } + + class C : B + { + int j; + + public override int $$GetHashCode() + { + var hashCode = 339610899; + hashCode = hashCode * -1521134295 + base.GetHashCode(); + hashCode = hashCode * -1521134295 + j.GetHashCode(); + return hashCode; + } + } + """); + } - string S { get; } + [Fact] + public async Task TestDirectNullCheck1() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestDirectNullCheck2() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int i; - - string S { get; } - - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + (S == null ? 0 : S.GetHashCode()); - return hashCode; - } + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + (S != null ? S.GetHashCode() : 0); + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string S { get; } + string S { get; } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } + public override int GetHashCode() + { + return System.HashCode.Combine(i, S); } - """); - } + } + """); + } - [Fact] - public async Task TestInt64Pattern() - { - await TestInRegularAndScript1Async( - """ - namespace System { public struct HashCode { } } + [Fact] + public async Task TestDirectNullCheck2() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int j; + class C + { + int i; - public override int $$GetHashCode() - { - long hashCode = -468965076; - hashCode = (hashCode * -1521134295 + j.GetHashCode()).GetHashCode(); - return hashCode; - } - } - """, - """ - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode() { - int j; - - public override int GetHashCode() - { - return System.HashCode.Combine(j); - } + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + (S == null ? 0 : S.GetHashCode()); + return hashCode; } - """); - } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - [Fact] - public async Task TestInt64Pattern2() - { - await TestInRegularAndScript1Async( - """ - namespace System { public struct HashCode { } } + class C + { + int i; - class C - { - int j; + string S { get; } - public override int $$GetHashCode() - { - long hashCode = -468965076; - hashCode = (hashCode * -1521134295 + j.GetHashCode()).GetHashCode(); - return (int)hashCode; - } + public override int GetHashCode() + { + return System.HashCode.Combine(i, S); } - """, - """ - namespace System { public struct HashCode { } } + } + """); + } - class C - { - int j; + [Fact] + public async Task TestInt64Pattern() + { + await TestInRegularAndScript1Async( + """ + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(j); - } + class C + { + int j; + + public override int $$GetHashCode() + { + long hashCode = -468965076; + hashCode = (hashCode * -1521134295 + j.GetHashCode()).GetHashCode(); + return hashCode; } - """); - } + } + """, + """ + namespace System { public struct HashCode { } } - [Fact] - public async Task TestTuple() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int j; - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(j); + } + } + """); + } - string S { get; } + [Fact] + public async Task TestInt64Pattern2() + { + await TestInRegularAndScript1Async( + """ + namespace System { public struct HashCode { } } - public override int $$GetHashCode() - { - return (i, S).GetHashCode(); - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int j; - class C + public override int $$GetHashCode() { - int i; + long hashCode = -468965076; + hashCode = (hashCode * -1521134295 + j.GetHashCode()).GetHashCode(); + return (int)hashCode; + } + } + """, + """ + namespace System { public struct HashCode { } } - string S { get; } + class C + { + int j; - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } + public override int GetHashCode() + { + return System.HashCode.Combine(j); } - """); - } + } + """); + } - [Fact] - public async Task TestNullable1() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + [Fact] + public async Task TestTuple() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string S { get; } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } + public override int $$GetHashCode() + { + return (i, S).GetHashCode(); } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string S { get; } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } + public override int GetHashCode() + { + return System.HashCode.Combine(i, S); } - """); - } + } + """); + } - [Fact] - public async Task TestNullable2() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + [Fact] + public async Task TestNullable1() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } + public override int $$GetHashCode() + { + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } + public override int GetHashCode() + { + return System.HashCode.Combine(i, S); } - """); - } + } + """); + } - [Fact] - public async Task TestNullable3() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + [Fact] + public async Task TestNullable2() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; - return hashCode; - } + public override int $$GetHashCode() + { + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } + public override int GetHashCode() + { + return System.HashCode.Combine(i, S); } - """); - } + } + """); + } - [Fact] - public async Task TestNullable4() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + [Fact] + public async Task TestNullable3() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; - return hashCode; - } + public override int $$GetHashCode() + { + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } + public override int GetHashCode() + { + return System.HashCode.Combine(i, S); } - """); - } - - [Fact] - public async Task TestNullable_Enable_1() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """); + } - #nullable enable + [Fact] + public async Task TestNullable4() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - class C - { - int i; + class C + { + int i; - string? S { get; } + string? S { get; } - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } + public override int $$GetHashCode() + { + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; + return hashCode; } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Enable_1() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable enable - [Fact] - public async Task TestNullable_Enable_2() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable enable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Enable_2() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable enable - [Fact] - public async Task TestNullable_Enable_3() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable enable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Enable_3() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable enable - [Fact] - public async Task TestNullable_Enable_4() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable enable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable enable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Enable_4() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable enable - [Fact] - public async Task TestNullable_Disable_1() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable enable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Disable_1() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable disable - [Fact] - public async Task TestNullable_Disable_2() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable disable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Disable_2() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable disable - [Fact] - public async Task TestNullable_Disable_3() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable disable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Disable_3() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable disable - [Fact] - public async Task TestNullable_Disable_4() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string? S { get; } + #nullable disable - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; - return hashCode; - } - } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + class C + { + int i; - #nullable disable + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string? S { get; } + [Fact] + public async Task TestNullable_Disable_4() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - return System.HashCode.Combine(i, S); - } - } - """); - } + #nullable disable + + class C + { + int i; - [Fact] - public async Task TestNotOnExistingUsageOfSystemHashCode() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string? S { get; } - class C + public override int $$GetHashCode() { - int i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S)!; + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - string S { get; } + #nullable disable - public override int $$GetHashCode1() - { - return HashCode.Combine(i, S); - } - } - """); - } + class C + { + int i; - [Fact] - public async Task TestNotOnExistingUsageOfSystemHashCode2() - { - await TestMissingAsync( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string? S { get; } - class C + public override int GetHashCode() { - int i; + return System.HashCode.Combine(i, S); + } + } + """); + } - string S { get; } + [Fact] + public async Task TestNotOnExistingUsageOfSystemHashCode() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int $$GetHashCode1() - { - var hash = new HashCode(); - hash.Add(i); - hash.Add(S); - return hash.ToHashCode(); - } - } - """); - } + class C + { + int i; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] - public async Task TestManyFields_ImplicitType() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode1() { - int a, b, c, d, e, f, g, h, i; - - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + a.GetHashCode(); - hashCode = hashCode * -1521134295 + b.GetHashCode(); - hashCode = hashCode * -1521134295 + c.GetHashCode(); - hashCode = hashCode * -1521134295 + d.GetHashCode(); - hashCode = hashCode * -1521134295 + e.GetHashCode(); - hashCode = hashCode * -1521134295 + f.GetHashCode(); - hashCode = hashCode * -1521134295 + g.GetHashCode(); - hashCode = hashCode * -1521134295 + h.GetHashCode(); - hashCode = hashCode * -1521134295 + i.GetHashCode(); - return hashCode; - } + return HashCode.Combine(i, S); } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """); + } - class C - { - int a, b, c, d, e, f, g, h, i; + [Fact] + public async Task TestNotOnExistingUsageOfSystemHashCode2() + { + await TestMissingAsync( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - public override int GetHashCode() - { - var hash = new System.HashCode(); - hash.Add(a); - hash.Add(b); - hash.Add(c); - hash.Add(d); - hash.Add(e); - hash.Add(f); - hash.Add(g); - hash.Add(h); - hash.Add(i); - return hash.ToHashCode(); - } - } - """, new TestParameters(options: this.PreferImplicitTypeWithInfo())); - } + class C + { + int i; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] - public async Task TestManyFields_ExplicitType() - { - await TestInRegularAndScript1Async( - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + string S { get; } - class C + public override int $$GetHashCode1() { - int a, b, c, d, e, f, g, h, i; - - public override int $$GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + a.GetHashCode(); - hashCode = hashCode * -1521134295 + b.GetHashCode(); - hashCode = hashCode * -1521134295 + c.GetHashCode(); - hashCode = hashCode * -1521134295 + d.GetHashCode(); - hashCode = hashCode * -1521134295 + e.GetHashCode(); - hashCode = hashCode * -1521134295 + f.GetHashCode(); - hashCode = hashCode * -1521134295 + g.GetHashCode(); - hashCode = hashCode * -1521134295 + h.GetHashCode(); - hashCode = hashCode * -1521134295 + i.GetHashCode(); - return hashCode; - } + var hash = new HashCode(); + hash.Add(i); + hash.Add(S); + return hash.ToHashCode(); } - """, - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + } + """); + } - class C - { - int a, b, c, d, e, f, g, h, i; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] + public async Task TestManyFields_ImplicitType() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + class C + { + int a, b, c, d, e, f, g, h, i; + + public override int $$GetHashCode() + { + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + a.GetHashCode(); + hashCode = hashCode * -1521134295 + b.GetHashCode(); + hashCode = hashCode * -1521134295 + c.GetHashCode(); + hashCode = hashCode * -1521134295 + d.GetHashCode(); + hashCode = hashCode * -1521134295 + e.GetHashCode(); + hashCode = hashCode * -1521134295 + f.GetHashCode(); + hashCode = hashCode * -1521134295 + g.GetHashCode(); + hashCode = hashCode * -1521134295 + h.GetHashCode(); + hashCode = hashCode * -1521134295 + i.GetHashCode(); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + class C + { + int a, b, c, d, e, f, g, h, i; + + public override int GetHashCode() + { + var hash = new System.HashCode(); + hash.Add(a); + hash.Add(b); + hash.Add(c); + hash.Add(d); + hash.Add(e); + hash.Add(f); + hash.Add(g); + hash.Add(h); + hash.Add(i); + return hash.ToHashCode(); + } + } + """, new TestParameters(options: this.PreferImplicitTypeWithInfo())); + } - public override int GetHashCode() - { - System.HashCode hash = new System.HashCode(); - hash.Add(a); - hash.Add(b); - hash.Add(c); - hash.Add(d); - hash.Add(e); - hash.Add(f); - hash.Add(g); - hash.Add(h); - hash.Add(i); - return hash.ToHashCode(); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] + public async Task TestManyFields_ExplicitType() + { + await TestInRegularAndScript1Async( + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + class C + { + int a, b, c, d, e, f, g, h, i; + + public override int $$GetHashCode() + { + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + a.GetHashCode(); + hashCode = hashCode * -1521134295 + b.GetHashCode(); + hashCode = hashCode * -1521134295 + c.GetHashCode(); + hashCode = hashCode * -1521134295 + d.GetHashCode(); + hashCode = hashCode * -1521134295 + e.GetHashCode(); + hashCode = hashCode * -1521134295 + f.GetHashCode(); + hashCode = hashCode * -1521134295 + g.GetHashCode(); + hashCode = hashCode * -1521134295 + h.GetHashCode(); + hashCode = hashCode * -1521134295 + i.GetHashCode(); + return hashCode; + } + } + """, + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + class C + { + int a, b, c, d, e, f, g, h, i; + + public override int GetHashCode() + { + System.HashCode hash = new System.HashCode(); + hash.Add(a); + hash.Add(b); + hash.Add(c); + hash.Add(d); + hash.Add(e); + hash.Add(f); + hash.Add(g); + hash.Add(h); + hash.Add(i); + return hash.ToHashCode(); + } + } + """); + } - [Fact] - public async Task TestNotOnSingleReturnedMember() - { - await TestMissingAsync( - """ - namespace System { public struct HashCode { } } + [Fact] + public async Task TestNotOnSingleReturnedMember() + { + await TestMissingAsync( + """ + namespace System { public struct HashCode { } } - class C - { - int j; + class C + { + int j; - public override int $$GetHashCode() - { - return j; - } + public override int $$GetHashCode() + { + return j; } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnSingleMemberWithInvokedGetHashCode() - { - await TestMissingAsync( - """ - namespace System { public struct HashCode { } } + [Fact] + public async Task TestNotOnSingleMemberWithInvokedGetHashCode() + { + await TestMissingAsync( + """ + namespace System { public struct HashCode { } } - class C - { - int j; + class C + { + int j; - public override int $$GetHashCode() - { - return j.GetHashCode(); - } + public override int $$GetHashCode() + { + return j.GetHashCode(); } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnSimpleBaseReturn() - { - await TestMissingAsync( - """ - namespace System { public struct HashCode { } } + [Fact] + public async Task TestNotOnSimpleBaseReturn() + { + await TestMissingAsync( + """ + namespace System { public struct HashCode { } } - class C - { - int j; + class C + { + int j; - public override int $$GetHashCode() - { - return base.GetHashCode(); - } + public override int $$GetHashCode() + { + return base.GetHashCode(); } - """); - } + } + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests.cs b/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests.cs index 1ae037684e418..c3fe4a3616fae 100644 --- a/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests.cs +++ b/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests.cs @@ -16,678 +16,677 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseThrowExpression +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseThrowExpression; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseThrowExpression)] +public partial class UseThrowExpressionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseThrowExpression)] - public partial class UseThrowExpressionTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public UseThrowExpressionTests(ITestOutputHelper logger) + : base(logger) { - public UseThrowExpressionTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUseThrowExpressionDiagnosticAnalyzer(), new UseThrowExpressionCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpUseThrowExpressionDiagnosticAnalyzer(), new UseThrowExpressionCodeFixProvider()); - [Fact] - public async Task WithoutBraces() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task WithoutBraces() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s == null) - [|throw|] new ArgumentNullException(nameof(s)); - _s = s; - } + if (s == null) + [|throw|] new ArgumentNullException(nameof(s)); + _s = s; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - _s = s ?? throw new ArgumentNullException(nameof(s)); - } + _s = s ?? throw new ArgumentNullException(nameof(s)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/38136")] - public async Task TestMissingOnIf() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/38136")] + public async Task TestMissingOnIf() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - [|if|] (s == null) - throw new ArgumentNullException(nameof(s)); - _s = s; - } + [|if|] (s == null) + throw new ArgumentNullException(nameof(s)); + _s = s; } - """); - } + } + """); + } - [Fact] - public async Task WithBraces() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task WithBraces() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) + if (s == null) { - if (s == null) - { - [|throw|] new ArgumentNullException(nameof(s)); - } - - _s = s; + [|throw|] new ArgumentNullException(nameof(s)); } + + _s = s; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - _s = s ?? throw new ArgumentNullException(nameof(s)); - } + _s = s ?? throw new ArgumentNullException(nameof(s)); } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnAssign() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotOnAssign() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (s == null) - throw new ArgumentNullException(nameof(s)); - _s = [|s|]; - } + if (s == null) + throw new ArgumentNullException(nameof(s)); + _s = [|s|]; } - """); - } + } + """); + } - [Fact] - public async Task OnlyInCSharp7AndHigher() - { - await TestMissingAsync( - """ - using System; + [Fact] + public async Task OnlyInCSharp7AndHigher() + { + await TestMissingAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) + if (s == null) { - if (s == null) - { - [|throw|] new ArgumentNullException(nameof(s)) }; - _s = s; - } + [|throw|] new ArgumentNullException(nameof(s)) }; + _s = s; } - """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); - } + } + """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); + } - [Fact] - public async Task WithIntermediaryStatements() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task WithIntermediaryStatements() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - [|throw|] new ArgumentNullException(nameof(s)); - } - - if (t == null) - { - throw new ArgumentNullException(nameof(t)); - } + [|throw|] new ArgumentNullException(nameof(s)); + } - _s = s; + if (t == null) + { + throw new ArgumentNullException(nameof(t)); } + + _s = s; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (t == null) { - if (t == null) - { - throw new ArgumentNullException(nameof(t)); - } - - _s = s ?? throw new ArgumentNullException(nameof(s)); + throw new ArgumentNullException(nameof(t)); } + + _s = s ?? throw new ArgumentNullException(nameof(s)); } - """); - } + } + """); + } - [Fact] - public async Task NotWithIntermediaryWrite() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotWithIntermediaryWrite() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - [|throw|] new ArgumentNullException(nameof(s)); - }; - s = "something"; - _s = s; - } + [|throw|] new ArgumentNullException(nameof(s)); + }; + s = "something"; + _s = s; } - """); - } + } + """); + } - [Fact] - public async Task NotWithIntermediaryMemberAccess() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task NotWithIntermediaryMemberAccess() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - [|throw|] new ArgumentNullException(nameof(s)); - }; - s.ToString(); - _s = s; - } + [|throw|] new ArgumentNullException(nameof(s)); + }; + s.ToString(); + _s = s; } - """); - } + } + """); + } - [Fact] - public async Task TestNullCheckOnLeft() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNullCheckOnLeft() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - if (null == s) - [|throw|] new ArgumentNullException(nameof(s)); - _s = s; - } + if (null == s) + [|throw|] new ArgumentNullException(nameof(s)); + _s = s; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - _s = s ?? throw new ArgumentNullException(nameof(s)); - } + _s = s ?? throw new ArgumentNullException(nameof(s)); } - """); - } + } + """); + } - [Fact] - public async Task TestWithLocal() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestWithLocal() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M() { - void M() - { - string s = null; - if (null == s) - [|throw|] new ArgumentNullException(nameof(s)); - _s = s; - } + string s = null; + if (null == s) + [|throw|] new ArgumentNullException(nameof(s)); + _s = s; } - """, - """ - using System; + } + """, + """ + using System; - class C + class C + { + void M() { - void M() - { - string s = null; - _s = s ?? throw new ArgumentNullException(nameof(s)); - } + string s = null; + _s = s ?? throw new ArgumentNullException(nameof(s)); } - """); - } + } + """); + } - [Fact] - public async Task TestNotOnField() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestNotOnField() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C - { - string s; + class C + { + string s; - void M() - { - if (null == s) - [|throw|] new ArgumentNullException(nameof(s)); - _s = s; - } + void M() + { + if (null == s) + [|throw|] new ArgumentNullException(nameof(s)); + _s = s; } - """); - } + } + """); + } - [Fact] - public async Task TestAssignBeforeCheck() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task TestAssignBeforeCheck() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) - { - _s = s; - if (s == null) - [|throw|] new ArgumentNullException(nameof(s)); - } + _s = s; + if (s == null) + [|throw|] new ArgumentNullException(nameof(s)); } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16234")] - public async Task TestNotInExpressionTree() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Linq.Expressions; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/16234")] + public async Task TestNotInExpressionTree() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Linq.Expressions; - class C - { - private string _s; + class C + { + private string _s; - void Goo() + void Goo() + { + Expression> e = s => { - Expression> e = s => - { - if (s == null) - [|throw|] new ArgumentNullException(nameof(s)); + if (s == null) + [|throw|] new ArgumentNullException(nameof(s)); - _s = s; - }; - } + _s = s; + }; } - """); - } + } + """); + } + + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=404142")] + public async Task TestNotWithAsCheck() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=404142")] - public async Task TestNotWithAsCheck() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + class BswParser3 + { + private ParserSyntax m_syntax; - class BswParser3 + public BswParser3(ISyntax syntax) { - private ParserSyntax m_syntax; - - public BswParser3(ISyntax syntax) + if (syntax == null) { - if (syntax == null) - { - [|throw|] new ArgumentNullException(nameof(syntax)); - } + [|throw|] new ArgumentNullException(nameof(syntax)); + } - m_syntax = syntax as ParserSyntax; + m_syntax = syntax as ParserSyntax; - if (m_syntax == null) - throw new ArgumentException(); - } + if (m_syntax == null) + throw new ArgumentException(); } + } - internal class ParserSyntax - { - } + internal class ParserSyntax + { + } - public interface ISyntax - { - } - """); - } + public interface ISyntax + { + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18670")] - public async Task TestNotWithElseClause() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18670")] + public async Task TestNotWithElseClause() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C - { - int? _x; + class C + { + int? _x; - public C(int? x) + public C(int? x) + { + if (x == null) + { + [|throw|] new ArgumentNullException(nameof(x)); + } + else { - if (x == null) - { - [|throw|] new ArgumentNullException(nameof(x)); - } - else - { - Console.WriteLine(); - } - - _x = x; + Console.WriteLine(); } + + _x = x; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19377")] - public async Task TestNotWithMultipleStatementsInIf1() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19377")] + public async Task TestNotWithMultipleStatementsInIf1() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) + if (s == null) { - if (s == null) - { - Console.WriteLine(); - [|throw|] new ArgumentNullException(nameof(s)); - } - _s = s; + Console.WriteLine(); + [|throw|] new ArgumentNullException(nameof(s)); } + _s = s; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19377")] - public async Task TestNotWithMultipleStatementsInIf2() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19377")] + public async Task TestNotWithMultipleStatementsInIf2() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s) { - void M(string s) + if (s == null) { - if (s == null) - { - [|throw|] new ArgumentNullException(nameof(s)); - Console.WriteLine(); - } - _s = s; + [|throw|] new ArgumentNullException(nameof(s)); + Console.WriteLine(); } + _s = s; } - """); - } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21612")] - public async Task TestNotWhenAccessedOnLeftOfAssignment() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21612")] + public async Task TestNotWhenAccessedOnLeftOfAssignment() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; + + class A + { + public string Id; + } + + class B + { + private Dictionary map = new Dictionary(); + public B(A a) + { + if (a == null) [|throw|] new ArgumentNullException(); + map[a.Id] = a; + } + } + """); + } - class A - { - public string Id; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24628")] + public async Task TestNotWhenAccessedOnLineBefore() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + using System.Collections.Generic; - class B + class B + { + public B(object arg) { - private Dictionary map = new Dictionary(); - public B(A a) - { - if (a == null) [|throw|] new ArgumentNullException(); - map[a.Id] = a; - } + Dictionary map = null; + + if (arg == null) [|throw|] new ArgumentNullException(); + var key = MakeKey(arg); + map[key] = arg; } - """); - } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24628")] - public async Task TestNotWhenAccessedOnLineBefore() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - using System.Collections.Generic; + object MakeKey(object x) => null; + } + """); + } - class B - { - public B(object arg) - { - Dictionary map = null; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22926")] + public async Task TestNotWhenUnconstrainedTypeParameter() + { + await TestMissingInRegularAndScriptAsync( + """ + using System; + class A + { + T x; + public A(T t) + { + if (t == null) [|throw|] new ArgumentNullException(); + x = t; + } + } + """); + } - if (arg == null) [|throw|] new ArgumentNullException(); - var key = MakeKey(arg); - map[key] = arg; - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22926")] + public async Task TestWhenClassConstrainedTypeParameter() + { + await TestInRegularAndScriptAsync( + """ + using System; + class A where T: class + { + T x; + public A(T t) + { + if (t == null) [|throw|] new ArgumentNullException(); + x = t; + } + } + """, + """ + using System; + class A where T: class + { + T x; + public A(T t) + { + x = t ?? throw new ArgumentNullException(); + } + } + """); + } - object MakeKey(object x) => null; - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22926")] + public async Task TestWhenStructConstrainedTypeParameter() + { + await TestInRegularAndScriptAsync( + """ + using System; + class A where T: struct + { + T? x; + public A(T? t) + { + if (t == null) [|throw|] new ArgumentNullException(); + x = t; + } + } + """, + """ + using System; + class A where T: struct + { + T? x; + public A(T? t) + { + x = t ?? throw new ArgumentNullException(); + } + } + """); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22926")] - public async Task TestNotWhenUnconstrainedTypeParameter() - { - await TestMissingInRegularAndScriptAsync( - """ - using System; - class A - { - T x; - public A(T t) - { - if (t == null) [|throw|] new ArgumentNullException(); - x = t; - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44454")] + public async Task TopLevelStatement() + { + await TestAsync( + """ + using System; + string s = null; + string x = null; + if (s == null) [|throw|] new ArgumentNullException(); + x = s; + """, + """ + using System; + string s = null; + string x = null; + + x = s ?? throw new ArgumentNullException(); + """, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22926")] - public async Task TestWhenClassConstrainedTypeParameter() - { - await TestInRegularAndScriptAsync( - """ - using System; - class A where T: class - { - T x; - public A(T t) - { - if (t == null) [|throw|] new ArgumentNullException(); - x = t; - } - } - """, - """ - using System; - class A where T: class - { - T x; - public A(T t) - { - x = t ?? throw new ArgumentNullException(); - } - } - """); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38102")] + public async Task PreserveTrailingTrivia1() + { + await TestAsync( + """ + using System; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/22926")] - public async Task TestWhenStructConstrainedTypeParameter() - { - await TestInRegularAndScriptAsync( - """ - using System; - class A where T: struct - { - T? x; - public A(T? t) - { - if (t == null) [|throw|] new ArgumentNullException(); - x = t; - } - } - """, - """ - using System; - class A where T: struct + class Program + { + object _arg; + + public Program(object arg) { - T? x; - public A(T? t) + if (arg == null) { - x = t ?? throw new ArgumentNullException(); + [|throw|] new ArgumentNullException(nameof(arg)); // Oh no! } + _arg = arg; } - """); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44454")] - public async Task TopLevelStatement() - { - await TestAsync( - """ - using System; - string s = null; - string x = null; - if (s == null) [|throw|] new ArgumentNullException(); - x = s; - """, - """ - using System; - string s = null; - string x = null; - - x = s ?? throw new ArgumentNullException(); - """, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38102")] - public async Task PreserveTrailingTrivia1() - { - await TestAsync( - """ - using System; - - class Program - { - object _arg; - - public Program(object arg) - { - if (arg == null) - { - [|throw|] new ArgumentNullException(nameof(arg)); // Oh no! - } - _arg = arg; - } - } - """, - """ - using System; + } + """, + """ + using System; - class Program - { - object _arg; + class Program + { + object _arg; - public Program(object arg) - { - _arg = arg ?? throw new ArgumentNullException(nameof(arg)); // Oh no! - } + public Program(object arg) + { + _arg = arg ?? throw new ArgumentNullException(nameof(arg)); // Oh no! } - """, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38102")] - public async Task PreserveTrailingTrivia2() - { - await TestAsync( - """ - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38102")] + public async Task PreserveTrailingTrivia2() + { + await TestAsync( + """ + using System; - class Program - { - object _arg; + class Program + { + object _arg; - public Program(object arg) + public Program(object arg) + { + if (arg == null) { - if (arg == null) - { - [|throw|] new ArgumentNullException(nameof(arg)); // Oh no! - } - _arg = arg; // oh yes! + [|throw|] new ArgumentNullException(nameof(arg)); // Oh no! } + _arg = arg; // oh yes! } - """, - """ - using System; + } + """, + """ + using System; - class Program - { - object _arg; + class Program + { + object _arg; - public Program(object arg) - { - // Oh no! - _arg = arg ?? throw new ArgumentNullException(nameof(arg)); // oh yes! - } + public Program(object arg) + { + // Oh no! + _arg = arg ?? throw new ArgumentNullException(nameof(arg)); // oh yes! } - """, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); - } + } + """, TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp9)); } } diff --git a/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests_FixAllTests.cs b/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests_FixAllTests.cs index fb008d28892bb..90265892987c6 100644 --- a/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests_FixAllTests.cs +++ b/src/Analyzers/CSharp/Tests/UseThrowExpression/UseThrowExpressionTests_FixAllTests.cs @@ -9,318 +9,317 @@ using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseThrowExpression +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseThrowExpression; + +[Trait(Traits.Feature, Traits.Features.CodeActionsUseThrowExpression)] +public partial class UseThrowExpressionTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsUseThrowExpression)] - public partial class UseThrowExpressionTests + [Fact] + public async Task FixAllInDocument1() { - [Fact] - public async Task FixAllInDocument1() - { - await TestInRegularAndScriptAsync( - """ - using System; - - class C + await TestInRegularAndScriptAsync( + """ + using System; + + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - {|FixAllInDocument:throw|} new ArgumentNullException(nameof(s)); - } - - if (t == null) - { - throw new ArgumentNullException(nameof(t)); - } - - _s = s; - _t = t; + {|FixAllInDocument:throw|} new ArgumentNullException(nameof(s)); } - } - """, - """ - using System; - class C - { - void M(string s, string t) + if (t == null) { - _s = s ?? throw new ArgumentNullException(nameof(s)); - _t = t ?? throw new ArgumentNullException(nameof(t)); + throw new ArgumentNullException(nameof(t)); } + + _s = s; + _t = t; + } + } + """, + """ + using System; + + class C + { + void M(string s, string t) + { + _s = s ?? throw new ArgumentNullException(nameof(s)); + _t = t ?? throw new ArgumentNullException(nameof(t)); } - """); - } + } + """); + } - [Fact] - public async Task FixAllInDocument2() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllInDocument2() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - if (t == null) - { - {|FixAllInDocument:throw|} new ArgumentNullException(nameof(t)); - } - - _s = s; - _t = t; + throw new ArgumentNullException(nameof(s)); } - } - """, - """ - using System; - class C - { - void M(string s, string t) + if (t == null) { - _s = s ?? throw new ArgumentNullException(nameof(s)); - _t = t ?? throw new ArgumentNullException(nameof(t)); + {|FixAllInDocument:throw|} new ArgumentNullException(nameof(t)); } + + _s = s; + _t = t; } - """); - } + } + """, + """ + using System; + + class C + { + void M(string s, string t) + { + _s = s ?? throw new ArgumentNullException(nameof(s)); + _t = t ?? throw new ArgumentNullException(nameof(t)); + } + } + """); + } - [Fact] - public async Task FixAllInDocument3() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllInDocument3() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - {|FixAllInDocument:throw new ArgumentNullException(nameof(s));|} - } - - if (t == null) - { - throw new ArgumentNullException(nameof(t)); - } - - _s = s; - _t = t; + {|FixAllInDocument:throw new ArgumentNullException(nameof(s));|} } - } - """, - """ - using System; - class C - { - void M(string s, string t) + if (t == null) { - _s = s ?? throw new ArgumentNullException(nameof(s)); - _t = t ?? throw new ArgumentNullException(nameof(t)); + throw new ArgumentNullException(nameof(t)); } + + _s = s; + _t = t; } - """); - } + } + """, + """ + using System; + + class C + { + void M(string s, string t) + { + _s = s ?? throw new ArgumentNullException(nameof(s)); + _t = t ?? throw new ArgumentNullException(nameof(t)); + } + } + """); + } - [Fact] - public async Task FixAllInDocument4() - { - await TestInRegularAndScriptAsync( - """ - using System; + [Fact] + public async Task FixAllInDocument4() + { + await TestInRegularAndScriptAsync( + """ + using System; - class C + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - if (t == null) - { - {|FixAllInDocument:throw new ArgumentNullException(nameof(t));|} - } - - _s = s; - _t = t; + throw new ArgumentNullException(nameof(s)); } - } - """, - """ - using System; - class C - { - void M(string s, string t) + if (t == null) { - _s = s ?? throw new ArgumentNullException(nameof(s)); - _t = t ?? throw new ArgumentNullException(nameof(t)); + {|FixAllInDocument:throw new ArgumentNullException(nameof(t));|} } + + _s = s; + _t = t; } - """); - } - - [Fact] - public async Task FixAllInDocumentDoNotTouchOtherDocuments() - { - await TestInRegularAndScriptAsync( - """ - - - - using System; - - class C + } + """, + """ + using System; + + class C + { + void M(string s, string t) { - void M(string s, string t) - { - if (s == null) - { - {|FixAllInDocument:throw|} new ArgumentNullException(nameof(s)); - } - - _s = s; - } + _s = s ?? throw new ArgumentNullException(nameof(s)); + _t = t ?? throw new ArgumentNullException(nameof(t)); } - - - using System; + } + """); + } - class D + [Fact] + public async Task FixAllInDocumentDoNotTouchOtherDocuments() + { + await TestInRegularAndScriptAsync( + """ + + + + using System; + + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - _s = s; + {|FixAllInDocument:throw|} new ArgumentNullException(nameof(s)); } + + _s = s; } - - - - """, - """ - - - - using System; - - class C + } + + + using System; + + class D + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - _s = s ?? throw new ArgumentNullException(nameof(s)); + throw new ArgumentNullException(nameof(s)); } - } - - - using System; - class D + _s = s; + } + } + + + + """, + """ + + + + using System; + + class C + { + void M(string s, string t) { - void M(string s, string t) - { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - _s = s; - } + _s = s ?? throw new ArgumentNullException(nameof(s)); } - - - - """); - } - - [Fact] - public async Task FixAllInProject1() - { - await TestInRegularAndScriptAsync( - """ - - - - using System; - - class C + } + + + using System; + + class D + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - {|FixAllInProject:throw|} new ArgumentNullException(nameof(s)); - } - - _s = s; + throw new ArgumentNullException(nameof(s)); } + + _s = s; } - - - using System; + } + + + + """); + } - class D + [Fact] + public async Task FixAllInProject1() + { + await TestInRegularAndScriptAsync( + """ + + + + using System; + + class C + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - if (s == null) - { - throw new ArgumentNullException(nameof(s)); - } - - _s = s; + {|FixAllInProject:throw|} new ArgumentNullException(nameof(s)); } + + _s = s; } - - - - """, - """ - - - - using System; - - class C + } + + + using System; + + class D + { + void M(string s, string t) { - void M(string s, string t) + if (s == null) { - _s = s ?? throw new ArgumentNullException(nameof(s)); + throw new ArgumentNullException(nameof(s)); } - } - - - using System; - class D + _s = s; + } + } + + + + """, + """ + + + + using System; + + class C + { + void M(string s, string t) { - void M(string s, string t) - { - _s = s ?? throw new ArgumentNullException(nameof(s)); - } + _s = s ?? throw new ArgumentNullException(nameof(s)); + } + } + + + using System; + + class D + { + void M(string s, string t) + { + _s = s ?? throw new ArgumentNullException(nameof(s)); } - - - - """); - } + } + + + + """); } } diff --git a/src/Analyzers/CSharp/Tests/UseTupleSwap/UseTupleSwapTests.cs b/src/Analyzers/CSharp/Tests/UseTupleSwap/UseTupleSwapTests.cs index 1cd5e53b12bb9..dd1ac5b1f3dc4 100644 --- a/src/Analyzers/CSharp/Tests/UseTupleSwap/UseTupleSwapTests.cs +++ b/src/Analyzers/CSharp/Tests/UseTupleSwap/UseTupleSwapTests.cs @@ -12,551 +12,550 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseTupleSwap -{ - using VerifyCS = CSharpCodeFixVerifier< - CSharpUseTupleSwapDiagnosticAnalyzer, - CSharpUseTupleSwapCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseTupleSwap; + +using VerifyCS = CSharpCodeFixVerifier< + CSharpUseTupleSwapDiagnosticAnalyzer, + CSharpUseTupleSwapCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)] - public partial class UseTupleSwapTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseLocalFunction)] +public partial class UseTupleSwapTests +{ + [Fact] + public async Task TestMissingBeforeCSharp7() { - [Fact] - public async Task TestMissingBeforeCSharp7() - { - var code = """ - class C + var code = """ + class C + { + void M(string[] args) { - void M(string[] args) - { - var temp = args[0]; - args[0] = args[1]; - args[1] = temp; - } + var temp = args[0]; + args[0] = args[1]; + args[1] = temp; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - LanguageVersion = LanguageVersion.CSharp6, - }.RunAsync(); - } - - [Fact] - public async Task TestMissingWithFeatureOff() + await new VerifyCS.Test { - var code = """ - class C - { - void M(string[] args) - { - var temp = args[0]; - args[0] = args[1]; - args[1] = temp; - } - } - """; + TestCode = code, + FixedCode = code, + LanguageVersion = LanguageVersion.CSharp6, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestMissingWithFeatureOff() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - Options = + void M(string[] args) { - { CSharpCodeStyleOptions.PreferTupleSwap, false, CodeStyle.NotificationOption2.Silent } + var temp = args[0]; + args[0] = args[1]; + args[1] = temp; } - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestBasicCase() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + TestCode = code, + FixedCode = code, + Options = + { + { CSharpCodeStyleOptions.PreferTupleSwap, false, CodeStyle.NotificationOption2.Silent } + } + }.RunAsync(); + } + + [Fact] + public async Task TestBasicCase() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - [|var|] temp = args[0]; - args[0] = args[1]; - args[1] = temp; - } + [|var|] temp = args[0]; + args[0] = args[1]; + args[1] = temp; } - """, - """ - class C + } + """, + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - (args[1], args[0]) = (args[0], args[1]); - } + (args[1], args[0]) = (args[0], args[1]); } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithRef() - { - var code = """ - class C + [Fact] + public async Task TestNotWithRef() + { + var code = """ + class C + { + void M(ref int a, ref int b) { - void M(ref int a, ref int b) - { - ref int temp = ref a; - a = ref b; - b = ref temp; - } + ref int temp = ref a; + a = ref b; + b = ref temp; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } - - [Fact] - public async Task TestArbitraryParens() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact] + public async Task TestArbitraryParens() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - [|var|] temp = (args[0]); - ((args[0])) = (((args[1]))); - ((((args[1])))) = (((((temp))))); - } + [|var|] temp = (args[0]); + ((args[0])) = (((args[1]))); + ((((args[1])))) = (((((temp))))); } - """, - """ - class C + } + """, + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - (args[1], args[0]) = (args[0], args[1]); - } + (args[1], args[0]) = (args[0], args[1]); } - """); - } + } + """); + } - [Fact] - public async Task TestTrivia1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestTrivia1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - // Comment - [|var|] temp = args[0]; - args[0] = args[1]; - args[1] = temp; - } + // Comment + [|var|] temp = args[0]; + args[0] = args[1]; + args[1] = temp; } - """, - """ - class C + } + """, + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - // Comment - (args[1], args[0]) = (args[0], args[1]); - } + // Comment + (args[1], args[0]) = (args[0], args[1]); } - """); - } + } + """); + } - [Fact] - public async Task TestTrivia2() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestTrivia2() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - [|var|] temp = args [ 0 ] ; - args [ 0 ] = args [ 1 ]; - args [ 1 ] = temp; - } + [|var|] temp = args [ 0 ] ; + args [ 0 ] = args [ 1 ]; + args [ 1 ] = temp; } - """, - """ - class C + } + """, + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - (args [ 1 ], args [ 0 ]) = (args [ 0 ], args [ 1 ]); - } + (args [ 1 ], args [ 0 ]) = (args [ 0 ], args [ 1 ]); } - """); - } + } + """); + } - [Fact] - public async Task TestSimpleAssignment1() - { - var code = """ - class C + [Fact] + public async Task TestSimpleAssignment1() + { + var code = """ + class C + { + void M(string[] args) { - void M(string[] args) - { - var temp = args[0]; - args[0] += args[1]; - args[1] = temp; - } + var temp = args[0]; + args[0] += args[1]; + args[1] = temp; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } - - [Fact] - public async Task TestSimpleAssignment2() + await new VerifyCS.Test { - var code = """ - class C - { - void M(string[] args) - { - var temp = args[0]; - args[0] = args[1]; - args[1] += temp; - } - } - """; + TestCode = code, + FixedCode = code, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestSimpleAssignment2() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } - - [Fact] - public async Task TestNotSwap1() - { - var code = """ - class C + void M(string[] args) { - void M(string[] args, string temp1) - { - var temp = args[0]; - args[0] = args[1]; - args[1] = temp1; - } + var temp = args[0]; + args[0] = args[1]; + args[1] += temp; } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotSwap2() + await new VerifyCS.Test { - var code = """ - class C - { - void M(string[] args) - { - var temp = args[0]; - args[1] = temp; - args[0] = args[1]; - } - } - """; + TestCode = code, + FixedCode = code, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestNotSwap1() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } - - [Fact] - public async Task TestNotSwap3() - { - var code = """ - class C + void M(string[] args, string temp1) { - void M(string[] args) - { - var temp = args[0]; - args[0] = args[1]; - args[0] = temp; - } + var temp = args[0]; + args[0] = args[1]; + args[1] = temp1; } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + } + """; - [Fact] - public async Task TestNotSwap4() + await new VerifyCS.Test { - var code = """ - class C + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact] + public async Task TestNotSwap2() + { + var code = """ + class C + { + void M(string[] args) { - void M(string[] args) - { - var temp = args[0]; - args[1] = args[0]; - args[0] = temp; - } + var temp = args[0]; + args[1] = temp; + args[0] = args[1]; } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestNotSwap3() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + void M(string[] args) + { + var temp = args[0]; + args[0] = args[1]; + args[0] = temp; + } + } + """; - [Fact] - public async Task TestNotSwap5() + await new VerifyCS.Test { - var code = """ - class C + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact] + public async Task TestNotSwap4() + { + var code = """ + class C + { + void M(string[] args) { - void M(string[] args) - { - string temp; - args[0] = args[1]; - args[1] = {|CS0165:temp|}; - } + var temp = args[0]; + args[1] = args[0]; + args[0] = temp; } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact] + public async Task TestNotSwap5() + { + var code = """ + class C { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + void M(string[] args) + { + string temp; + args[0] = args[1]; + args[1] = {|CS0165:temp|}; + } + } + """; - [Fact] - public async Task TestInSwitch() + await new VerifyCS.Test { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact] + public async Task TestInSwitch() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(string[] args, int x) { - void M(string[] args, int x) + switch (x) { - switch (x) - { - default: - [|var|] temp = args[0]; - args[0] = args[1]; - args[1] = temp; - break; - } + default: + [|var|] temp = args[0]; + args[0] = args[1]; + args[1] = temp; + break; } } - """, - """ - class C + } + """, + """ + class C + { + void M(string[] args, int x) { - void M(string[] args, int x) + switch (x) { - switch (x) - { - default: - (args[1], args[0]) = (args[0], args[1]); - break; - } + default: + (args[1], args[0]) = (args[0], args[1]); + break; } } - """); - } + } + """); + } - [Fact] - public async Task TestFixAll1() - { - await VerifyCS.VerifyCodeFixAsync( - """ - class C + [Fact] + public async Task TestFixAll1() + { + await VerifyCS.VerifyCodeFixAsync( + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - // comment 1 - [|var|] temp1 = args[0]; - args[0] = args[1]; - args[1] = temp1; - - // comment 2 - [|var|] temp2 = args[2]; - args[2] = args[3]; - args[3] = temp2; - } + // comment 1 + [|var|] temp1 = args[0]; + args[0] = args[1]; + args[1] = temp1; + + // comment 2 + [|var|] temp2 = args[2]; + args[2] = args[3]; + args[3] = temp2; } - """, - """ - class C + } + """, + """ + class C + { + void M(string[] args) { - void M(string[] args) - { - // comment 1 - (args[1], args[0]) = (args[0], args[1]); + // comment 1 + (args[1], args[0]) = (args[0], args[1]); - // comment 2 - (args[3], args[2]) = (args[2], args[3]); - } + // comment 2 + (args[3], args[2]) = (args[2], args[3]); } - """); - } + } + """); + } - [Fact] - public async Task TestNotWithMultipleVariables() - { - var code = """ - class C + [Fact] + public async Task TestNotWithMultipleVariables() + { + var code = """ + class C + { + void M(string[] args) { - void M(string[] args) - { - string temp = args[0], temp2 = ""; - args[0] = args[1]; - args[1] = temp; - } + string temp = args[0], temp2 = ""; + args[0] = args[1]; + args[1] = temp; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58759")] - public async Task TestTopLevelStatements() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/58759")] + public async Task TestTopLevelStatements() + { + await new VerifyCS.Test { - await new VerifyCS.Test + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + LanguageVersion = LanguageVersion.CSharp9, + TestState = { - ReferenceAssemblies = ReferenceAssemblies.Net.Net50, - LanguageVersion = LanguageVersion.CSharp9, - TestState = + Sources = { - Sources = - { - """ - [|var|] temp = args[0]; - args[0] = args[1]; - args[1] = temp; - """, - }, - OutputKind = OutputKind.ConsoleApplication, + """ + [|var|] temp = args[0]; + args[0] = args[1]; + args[1] = temp; + """, }, - FixedCode = """ - (args[1], args[0]) = (args[0], args[1]); + OutputKind = OutputKind.ConsoleApplication, + }, + FixedCode = """ + (args[1], args[0]) = (args[0], args[1]); - """, - }.RunAsync(); - } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66427")] - public async Task NotOnRefStruct() - { - var code = """ - ref struct S { } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66427")] + public async Task NotOnRefStruct() + { + var code = """ + ref struct S { } - class C + class C + { + void M() { - void M() - { - S v0 = default; - S v1 = default; + S v0 = default; + S v1 = default; - var vTmp = v0; - v0 = v1; - v1 = vTmp; - } + var vTmp = v0; + v0 = v1; + v1 = vTmp; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66427")] - public async Task OnNormalStruct() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66427")] + public async Task OnNormalStruct() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = """ - struct S { } + TestCode = """ + struct S { } - class C + class C + { + void M() { - void M() - { - S v0 = default; - S v1 = default; + S v0 = default; + S v1 = default; - [|var|] vTmp = v0; - v0 = v1; - v1 = vTmp; - } + [|var|] vTmp = v0; + v0 = v1; + v1 = vTmp; } - """, - FixedCode = """ - struct S { } + } + """, + FixedCode = """ + struct S { } - class C + class C + { + void M() { - void M() - { - S v0 = default; - S v1 = default; + S v0 = default; + S v1 = default; - (v1, v0) = (v0, v1); - } + (v1, v0) = (v0, v1); } - """, - }.RunAsync(); - } + } + """, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66427")] - public async Task NotOnPointer() - { - var code = """ - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/66427")] + public async Task NotOnPointer() + { + var code = """ + class C + { + unsafe void M(int* v0, int* v1) { - unsafe void M(int* v0, int* v1) - { - var vTmp = v0; - v0 = v1; - v1 = vTmp; - } + var vTmp = v0; + v0 = v1; + v1 = vTmp; } - """; + } + """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseUtf8StringLiteral/UseUtf8StringLiteralTests.cs b/src/Analyzers/CSharp/Tests/UseUtf8StringLiteral/UseUtf8StringLiteralTests.cs index 35089cb310bc0..5a36f81c5cd43 100644 --- a/src/Analyzers/CSharp/Tests/UseUtf8StringLiteral/UseUtf8StringLiteralTests.cs +++ b/src/Analyzers/CSharp/Tests/UseUtf8StringLiteral/UseUtf8StringLiteralTests.cs @@ -12,1592 +12,1591 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseUtf8StringLiteral -{ - using VerifyCS = CSharpCodeFixVerifier< - UseUtf8StringLiteralDiagnosticAnalyzer, - UseUtf8StringLiteralCodeFixProvider>; +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseUtf8StringLiteral; + +using VerifyCS = CSharpCodeFixVerifier< + UseUtf8StringLiteralDiagnosticAnalyzer, + UseUtf8StringLiteralCodeFixProvider>; - [Trait(Traits.Feature, Traits.Features.CodeActionsUseUtf8StringLiteral)] - public class UseUtf8StringLiteralTests +[Trait(Traits.Feature, Traits.Features.CodeActionsUseUtf8StringLiteral)] +public class UseUtf8StringLiteralTests +{ + [Fact] + public async Task TestNotInAttribute() { - [Fact] - public async Task TestNotInAttribute() + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class MyAttribute : System.Attribute { - TestCode = - """ - public class MyAttribute : System.Attribute + public MyAttribute(byte[] data) { - public MyAttribute(byte[] data) - { - } } + } - public class C + public class C + { + [MyAttribute(new byte[] { 65, 66, 67 })] + public void M() { - [MyAttribute(new byte[] { 65, 66, 67 })] - public void M() - { - } } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestNotInCSharp10() + [Fact] + public async Task TestNotInCSharp10() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[] { 65, 66, 67 }; - } + var x = new byte[] { 65, 66, 67 }; } - """, - LanguageVersion = LanguageVersion.CSharp10 - }.RunAsync(); - } + } + """, + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } - [Fact] - public async Task TestNotWhenNoReadOnlySpan() + [Fact] + public async Task TestNotWhenNoReadOnlySpan() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[] { 65, 66, 67 }; - } + var x = new byte[] { 65, 66, 67 }; } - """, - ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net20.Default, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net20.Default, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestNotWithoutInitializer() + [Fact] + public async Task TestNotWithoutInitializer() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[10]; - } + var x = new byte[10]; } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestNotInExpressionTree() + [Fact] + public async Task TestNotInExpressionTree() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - using System; - using System.Linq.Expressions; + TestCode = + """ + using System; + using System.Linq.Expressions; - public class C + public class C + { + public void M() { - public void M() - { - N(() => new byte[] { 65, 66, 67 }); - } + N(() => new byte[] { 65, 66, 67 }); + } - public void N(Expression> f) - { - } + public void N(Expression> f) + { } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestNotWhenNotByteArray() + [Fact] + public async Task TestNotWhenNotByteArray() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new int[] { 65, 66, 67 }; - } + var x = new int[] { 65, 66, 67 }; } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestNotWhenOptionNotSet() + [Fact] + public async Task TestNotWhenOptionNotSet() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C - { - public void M() - { - var x = new byte[] { 65, 66, 67 }; - } - } - """, - EditorConfig = """ - [*.cs] - csharp_style_prefer_utf8_string_literals = false - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } - - [Fact] - public async Task TestNotWhenNonLiteralElement() + public void M() + { + var x = new byte[] { 65, 66, 67 }; + } + } + """, + EditorConfig = """ + [*.cs] + csharp_style_prefer_utf8_string_literals = false + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } + + [Fact] + public async Task TestNotWhenNonLiteralElement() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[] { 65, GetB(), 67 }; - } - - public byte GetB() => 66; + var x = new byte[] { 65, GetB(), 67 }; } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } - [Fact] - public async Task TestNotWhenMultidimensionalArray() + public byte GetB() => 66; + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } + + [Fact] + public async Task TestNotWhenMultidimensionalArray() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[,] { { 65, 66 }, { 67, 68 }, { 69, 70 } }; - } + var x = new byte[,] { { 65, 66 }, { 67, 68 }, { 69, 70 } }; } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestSimpleByteArray() + [Fact] + public async Task TestSimpleByteArray() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 65, 66, 67 }; - } + var x = [|new|] byte[] { 65, 66, 67 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "ABC"u8.ToArray(); - } + var x = "ABC"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestConstant() + [Fact] + public async Task TestConstant() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + private const byte B = 66; + public void M() { - private const byte B = 66; - public void M() - { - var x = [|new|] byte[] { 65, B, 67 }; - } + var x = [|new|] byte[] { 65, B, 67 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + private const byte B = 66; + public void M() { - private const byte B = 66; - public void M() - { - var x = "ABC"u8.ToArray(); - } + var x = "ABC"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestImplicitArray() + [Fact] + public async Task TestImplicitArray() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] [] { (byte)65, (byte)66, (byte)67 }; - } + var x = [|new|] [] { (byte)65, (byte)66, (byte)67 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "ABC"u8.ToArray(); - } + var x = "ABC"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestExplicitCast() + [Fact] + public async Task TestExplicitCast() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 65, (byte)'B', 67 }; - } + var x = [|new|] byte[] { 65, (byte)'B', 67 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "ABC"u8.ToArray(); - } + var x = "ABC"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestHexLiteral() + [Fact] + public async Task TestHexLiteral() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 0x41, 0x42, 0x43 }; - } + var x = [|new|] byte[] { 0x41, 0x42, 0x43 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "ABC"u8.ToArray(); - } + var x = "ABC"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestBinaryExpression() + [Fact] + public async Task TestBinaryExpression() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 60 + 5, 60 + 6, 60 + 7 }; - } + var x = [|new|] byte[] { 60 + 5, 60 + 6, 60 + 7 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "ABC"u8.ToArray(); - } + var x = "ABC"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestEmptyArray() + [Fact] + public async Task TestEmptyArray() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { }; - } + var x = [|new|] byte[] { }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = ""u8.ToArray(); - } + var x = ""u8.ToArray(); } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestTrivia1() + [Fact] + public async Task TestTrivia1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 65, 66, 67 }; // I wish this byte array was easier to read - } + var x = [|new|] byte[] { 65, 66, 67 }; // I wish this byte array was easier to read } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "ABC"u8.ToArray(); // I wish this byte array was easier to read - } + var x = "ABC"u8.ToArray(); // I wish this byte array was easier to read } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestTrivia2() + [Fact] + public async Task TestTrivia2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(byte[] b) { - public void M(byte[] b) - { - M(/* arrays are */ [|new|] byte[] { 65, 66, 67 } /* cool */); - } + M(/* arrays are */ [|new|] byte[] { 65, 66, 67 } /* cool */); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(byte[] b) { - public void M(byte[] b) - { - M(/* arrays are */ "ABC"u8.ToArray() /* cool */); - } + M(/* arrays are */ "ABC"u8.ToArray() /* cool */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestMultiple() + [Fact] + public async Task TestMultiple() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 0x41, 0x42, 0x43 }; - var y = [|new|] byte[] { 0x44, 0x45, 0x46 }; - var z = [|new|] byte[] { 0x47, 0x48, 0x49 }; - } + var x = [|new|] byte[] { 0x41, 0x42, 0x43 }; + var y = [|new|] byte[] { 0x44, 0x45, 0x46 }; + var z = [|new|] byte[] { 0x47, 0x48, 0x49 }; } - """, - FixedCode = - """ - public class C - { - public void M() - { - var x = "ABC"u8.ToArray(); - var y = "DEF"u8.ToArray(); - var z = "GHI"u8.ToArray(); - } - } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + FixedCode = + """ + public class C + { + public void M() + { + var x = "ABC"u8.ToArray(); + var y = "DEF"u8.ToArray(); + var z = "GHI"u8.ToArray(); + } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestEscapeChars() + [Fact] + public async Task TestEscapeChars() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 34, 92, 10, 13, 9 }; - } + var x = [|new|] byte[] { 34, 92, 10, 13, 9 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "\"\\\n\r\t"u8.ToArray(); - } + var x = "\"\\\n\r\t"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestEmoji() + [Fact] + public async Task TestEmoji() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = [|new|] byte[] { 240, 159, 152, 128 }; - } + var x = [|new|] byte[] { 240, 159, 152, 128 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "😀"u8.ToArray(); - } + var x = "😀"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestHalfEmoji1() + [Fact] + public async Task TestHalfEmoji1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[] { 240, 159 }; - } + var x = new byte[] { 240, 159 }; } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestHalfEmoji2() + [Fact] + public async Task TestHalfEmoji2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[] { 152, 128 }; - } + var x = new byte[] { 152, 128 }; } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestHalfEmoji3() + [Fact] + public async Task TestHalfEmoji3() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M() { - public void M() - { - var x = new byte[] { 65, 152, 128, 66 }; - } + var x = new byte[] { 65, 152, 128, 66 }; } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestUnicodeReplacementChar() + [Fact] + public async Task TestUnicodeReplacementChar() + { + // The unicode replacement character is what is returned when, for example, an unpaired + // surrogate is converted to a UTF-8 string. This test just ensures that the presence of + // that character isn't being used to detect a failure state of some kind. + await new VerifyCS.Test { - // The unicode replacement character is what is returned when, for example, an unpaired - // surrogate is converted to a UTF-8 string. This test just ensures that the presence of - // that character isn't being used to detect a failure state of some kind. - await new VerifyCS.Test - { - TestCode = - """ - public class C - { - public void M() - { - var x = [|new|] byte[] { 239, 191, 189 }; - } + TestCode = + """ + public class C + { + public void M() + { + var x = [|new|] byte[] { 239, 191, 189 }; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M() { - public void M() - { - var x = "�"u8.ToArray(); - } + var x = "�"u8.ToArray(); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestCollectionInitializer() + [Fact] + public async Task TestCollectionInitializer() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - using System.Collections; - using System.Collections.Generic; - - class C : IEnumerable - { - void M(C c) - { - // Each literal of the three is a separate IArrayCreationOperation - // Lowered code is similar to: - /* - C c = new C(); - c.Add(new byte[] { 65 }); - c.Add(new byte[] { 66 }); - c.Add(new byte[] { 67 }); - */ - c = new() { [|65|], [|66|], [|67|] }; - } + TestCode = + """ + using System.Collections; + using System.Collections.Generic; - public void Add(params byte[] bytes) - { - } + class C : IEnumerable + { + void M(C c) + { + // Each literal of the three is a separate IArrayCreationOperation + // Lowered code is similar to: + /* + C c = new C(); + c.Add(new byte[] { 65 }); + c.Add(new byte[] { 66 }); + c.Add(new byte[] { 67 }); + */ + c = new() { [|65|], [|66|], [|67|] }; + } - public IEnumerator GetEnumerator() - { - throw new System.NotImplementedException(); - } + public void Add(params byte[] bytes) + { + } - IEnumerator IEnumerable.GetEnumerator() - { - throw new System.NotImplementedException(); - } + public IEnumerator GetEnumerator() + { + throw new System.NotImplementedException(); } - """, - FixedCode = - """ - using System.Collections; - using System.Collections.Generic; - - class C : IEnumerable - { - void M(C c) - { - // Each literal of the three is a separate IArrayCreationOperation - // Lowered code is similar to: - /* - C c = new C(); - c.Add(new byte[] { 65 }); - c.Add(new byte[] { 66 }); - c.Add(new byte[] { 67 }); - */ - c = new() { "A"u8.ToArray(), "B"u8.ToArray(), "C"u8.ToArray() }; - } - public void Add(params byte[] bytes) - { - } + IEnumerator IEnumerable.GetEnumerator() + { + throw new System.NotImplementedException(); + } + } + """, + FixedCode = + """ + using System.Collections; + using System.Collections.Generic; - public IEnumerator GetEnumerator() - { - throw new System.NotImplementedException(); - } + class C : IEnumerable + { + void M(C c) + { + // Each literal of the three is a separate IArrayCreationOperation + // Lowered code is similar to: + /* + C c = new C(); + c.Add(new byte[] { 65 }); + c.Add(new byte[] { 66 }); + c.Add(new byte[] { 67 }); + */ + c = new() { "A"u8.ToArray(), "B"u8.ToArray(), "C"u8.ToArray() }; + } - IEnumerator IEnumerable.GetEnumerator() - { - throw new System.NotImplementedException(); - } + public void Add(params byte[] bytes) + { } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } - [Fact] - public async Task TestUsingWithParamArray() - { - // From: https://github.com/dotnet/roslyn/blob/0c7c0b33f0871fc4308eb2d75d77b87fc9293290/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IUsingStatement.cs#L1189-L1194 - // There is an array creation operation for the param array - await new VerifyCS.Test - { - TestCode = - """ - class C - { - public static void M1() - { - using(var s = new S()) - { - } - } + public IEnumerator GetEnumerator() + { + throw new System.NotImplementedException(); } - ref struct S - { - public void Dispose(int a = 1, bool b = true, params byte[] others) { } - } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } - - [Theory] - // Standard C# escape characters - [InlineData(new byte[] { 0, 7, 8, 12, 11 })] - // Various cases copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http2/HuffmanDecodingTests.cs - [InlineData(new byte[] { 0xff, 0xcf })] - [InlineData(new byte[] { 0b100111_00, 0b101_10100, 0b0_101000_0, 0b0111_1111 })] - [InlineData(new byte[] { 0xb6, 0xb9, 0xac, 0x1c, 0x85, 0x58, 0xd5, 0x20, 0xa4, 0xb6, 0xc2, 0xad, 0x61, 0x7b, 0x5a, 0x54, 0x25, 0x1f })] - [InlineData(new byte[] { 0xfe, 0x53 })] - [InlineData(new byte[] { 0xff, 0xff, 0xf6, 0xff, 0xff, 0xfd, 0x68 })] - [InlineData(new byte[] { 0xff, 0xff, 0xf9, 0xff, 0xff, 0xfd, 0x86 })] - // Various cases copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http3/QPackDecoderTest.cs - [InlineData(new byte[] { 0xa8, 0xbe, 0x16, 0x9c, 0xa3, 0x90, 0xb6, 0x7f })] - [InlineData(new byte[] { 0x37, 0x02, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65 })] - [InlineData(new byte[] { 0x3f, 0x01 })] - // DaysInMonth365 from https://github.com/dotnet/runtime/blob/b5a8ece073110140e2d9696cdfdc047ec78c2fa1/src/libraries/System.Private.CoreLib/src/System/DateTime.cs - [InlineData(new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 })] - public async Task TestInvalidUtf8Strings(byte[] bytes) + + IEnumerator IEnumerable.GetEnumerator() + { + throw new System.NotImplementedException(); + } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } + + [Fact] + public async Task TestUsingWithParamArray() + { + // From: https://github.com/dotnet/roslyn/blob/0c7c0b33f0871fc4308eb2d75d77b87fc9293290/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IUsingStatement.cs#L1189-L1194 + // There is an array creation operation for the param array + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + class C { - TestCode = - $$""" - public class C + public static void M1() { - private static readonly byte[] _bytes = new byte[] { {{string.Join(", ", bytes)}} }; + using(var s = new S()) + { + } } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + ref struct S + { + public void Dispose(int a = 1, bool b = true, params byte[] others) { } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestDoesNotOfferForControlCharacters() + [Theory] + // Standard C# escape characters + [InlineData(new byte[] { 0, 7, 8, 12, 11 })] + // Various cases copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http2/HuffmanDecodingTests.cs + [InlineData(new byte[] { 0xff, 0xcf })] + [InlineData(new byte[] { 0b100111_00, 0b101_10100, 0b0_101000_0, 0b0111_1111 })] + [InlineData(new byte[] { 0xb6, 0xb9, 0xac, 0x1c, 0x85, 0x58, 0xd5, 0x20, 0xa4, 0xb6, 0xc2, 0xad, 0x61, 0x7b, 0x5a, 0x54, 0x25, 0x1f })] + [InlineData(new byte[] { 0xfe, 0x53 })] + [InlineData(new byte[] { 0xff, 0xff, 0xf6, 0xff, 0xff, 0xfd, 0x68 })] + [InlineData(new byte[] { 0xff, 0xff, 0xf9, 0xff, 0xff, 0xfd, 0x86 })] + // Various cases copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/tests/Tests/System/Net/aspnetcore/Http3/QPackDecoderTest.cs + [InlineData(new byte[] { 0xa8, 0xbe, 0x16, 0x9c, 0xa3, 0x90, 0xb6, 0x7f })] + [InlineData(new byte[] { 0x37, 0x02, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65 })] + [InlineData(new byte[] { 0x3f, 0x01 })] + // DaysInMonth365 from https://github.com/dotnet/runtime/blob/b5a8ece073110140e2d9696cdfdc047ec78c2fa1/src/libraries/System.Private.CoreLib/src/System/DateTime.cs + [InlineData(new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 })] + public async Task TestInvalidUtf8Strings(byte[] bytes) + { + await new VerifyCS.Test { - // Copied from https://github.com/dotnet/runtime/blob/6a889d234267a4c96ed21d0e1660dce787d78a38/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs - var input = """ - class C - { - internal enum ConvKind - { - Identity = 1, // Identity conversion - Implicit = 2, // Implicit conversion - Explicit = 3, // Explicit conversion - Unknown = 4, // Unknown so call canConvert - None = 5, // None - } + TestCode = + $$""" + public class C + { + private static readonly byte[] _bytes = new byte[] { {{string.Join(", ", bytes)}} }; + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - private const byte ID = (byte)ConvKind.Identity; // 0x01 - private const byte IMP = (byte)ConvKind.Implicit; // 0x02 - private const byte EXP = (byte)ConvKind.Explicit; // 0x03 - private const byte NO = (byte)ConvKind.None; // 0x05 - private const byte CONV_KIND_MASK = 0x0F; - private const byte UDC = 0x40; - private const byte XUD = EXP | UDC; - private const byte IUD = IMP | UDC; - - private static readonly byte[][] s_simpleTypeConversions = - { - // to: BYTE I2 I4 I8 FLT DBL DEC CHAR BOOL SBYTE U2 U4 U8 - /* from */ - new byte[] /* BYTE */ { ID, IMP, IMP, IMP, IMP, IMP, IUD, EXP, NO, EXP, IMP, IMP, IMP }, - new byte[] /* I2 */ { EXP, ID, IMP, IMP, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, EXP }, - new byte[] /* I4 */ { EXP, EXP, ID, IMP, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, EXP }, - new byte[] /* I8 */ { EXP, EXP, EXP, ID, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, EXP }, - new byte[] /* FLT */ { EXP, EXP, EXP, EXP, ID, IMP, XUD, EXP, NO, EXP, EXP, EXP, EXP }, - new byte[] /* DBL */ { EXP, EXP, EXP, EXP, EXP, ID, XUD, EXP, NO, EXP, EXP, EXP, EXP }, - new byte[] /* DEC */ { XUD, XUD, XUD, XUD, XUD, XUD, ID, XUD, NO, XUD, XUD, XUD, XUD }, - new byte[] /* CHAR */ { EXP, EXP, IMP, IMP, IMP, IMP, IUD, ID, NO, EXP, IMP, IMP, IMP }, - new byte[] /* BOOL */ { NO, NO, NO, NO, NO, NO, NO, NO, ID, NO, NO, NO, NO }, - new byte[] /*SBYTE */ { EXP, IMP, IMP, IMP, IMP, IMP, IUD, EXP, NO, ID, EXP, EXP, EXP }, - new byte[] /* U2 */ { EXP, EXP, IMP, IMP, IMP, IMP, IUD, EXP, NO, EXP, ID, IMP, IMP }, - new byte[] /* U4 */ { EXP, EXP, EXP, IMP, IMP, IMP, IUD, EXP, NO, EXP, EXP, ID, IMP }, - new byte[] /* U8 */ { EXP, EXP, EXP, EXP, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, ID }, - }; - } - """; - - await new VerifyCS.Test - { - TestCode = input, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } - - [Fact] - public async Task TestParamArray1() + [Fact] + public async Task TestDoesNotOfferForControlCharacters() + { + // Copied from https://github.com/dotnet/runtime/blob/6a889d234267a4c96ed21d0e1660dce787d78a38/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Conversion.cs + var input = """ + class C + { + internal enum ConvKind + { + Identity = 1, // Identity conversion + Implicit = 2, // Implicit conversion + Explicit = 3, // Explicit conversion + Unknown = 4, // Unknown so call canConvert + None = 5, // None + } + + private const byte ID = (byte)ConvKind.Identity; // 0x01 + private const byte IMP = (byte)ConvKind.Implicit; // 0x02 + private const byte EXP = (byte)ConvKind.Explicit; // 0x03 + private const byte NO = (byte)ConvKind.None; // 0x05 + private const byte CONV_KIND_MASK = 0x0F; + private const byte UDC = 0x40; + private const byte XUD = EXP | UDC; + private const byte IUD = IMP | UDC; + + private static readonly byte[][] s_simpleTypeConversions = + { + // to: BYTE I2 I4 I8 FLT DBL DEC CHAR BOOL SBYTE U2 U4 U8 + /* from */ + new byte[] /* BYTE */ { ID, IMP, IMP, IMP, IMP, IMP, IUD, EXP, NO, EXP, IMP, IMP, IMP }, + new byte[] /* I2 */ { EXP, ID, IMP, IMP, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, EXP }, + new byte[] /* I4 */ { EXP, EXP, ID, IMP, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, EXP }, + new byte[] /* I8 */ { EXP, EXP, EXP, ID, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, EXP }, + new byte[] /* FLT */ { EXP, EXP, EXP, EXP, ID, IMP, XUD, EXP, NO, EXP, EXP, EXP, EXP }, + new byte[] /* DBL */ { EXP, EXP, EXP, EXP, EXP, ID, XUD, EXP, NO, EXP, EXP, EXP, EXP }, + new byte[] /* DEC */ { XUD, XUD, XUD, XUD, XUD, XUD, ID, XUD, NO, XUD, XUD, XUD, XUD }, + new byte[] /* CHAR */ { EXP, EXP, IMP, IMP, IMP, IMP, IUD, ID, NO, EXP, IMP, IMP, IMP }, + new byte[] /* BOOL */ { NO, NO, NO, NO, NO, NO, NO, NO, ID, NO, NO, NO, NO }, + new byte[] /*SBYTE */ { EXP, IMP, IMP, IMP, IMP, IMP, IUD, EXP, NO, ID, EXP, EXP, EXP }, + new byte[] /* U2 */ { EXP, EXP, IMP, IMP, IMP, IMP, IUD, EXP, NO, EXP, ID, IMP, IMP }, + new byte[] /* U4 */ { EXP, EXP, EXP, IMP, IMP, IMP, IUD, EXP, NO, EXP, EXP, ID, IMP }, + new byte[] /* U8 */ { EXP, EXP, EXP, EXP, IMP, IMP, IUD, EXP, NO, EXP, EXP, EXP, ID }, + }; + } + """; + + await new VerifyCS.Test + { + TestCode = input, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } + + [Fact] + public async Task TestParamArray1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(params byte[] b) { - public void M(params byte[] b) - { - M([|new|] byte[] { 65, 66, 67 }); - } + M([|new|] byte[] { 65, 66, 67 }); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(params byte[] b) { - public void M(params byte[] b) - { - M("ABC"u8.ToArray()); - } + M("ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray2() + [Fact] + public async Task TestParamArray2() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int i, params byte[] b) { - public void M(int i, params byte[] b) - { - M(1, [|new|] byte[] { 65, 66, 67 }); - } + M(1, [|new|] byte[] { 65, 66, 67 }); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int i, params byte[] b) { - public void M(int i, params byte[] b) - { - M(1, "ABC"u8.ToArray()); - } + M(1, "ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray3() + [Fact] + public async Task TestParamArray3() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(params byte[] b) { - public void M(params byte[] b) - { - M([|65|]); - } + M([|65|]); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(params byte[] b) { - public void M(params byte[] b) - { - M("A"u8.ToArray()); - } + M("A"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray4() + [Fact] + public async Task TestParamArray4() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(params byte[] b) { - public void M(params byte[] b) - { - M(/* hi */ [|65|] /* there */); - } + M(/* hi */ [|65|] /* there */); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(params byte[] b) { - public void M(params byte[] b) - { - M(/* hi */ "A"u8.ToArray() /* there */); - } + M(/* hi */ "A"u8.ToArray() /* there */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray5() + [Fact] + public async Task TestParamArray5() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(params byte[] b) { - public void M(params byte[] b) - { - M([|65, 66, 67|]); - } + M([|65, 66, 67|]); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(params byte[] b) { - public void M(params byte[] b) - { - M("ABC"u8.ToArray()); - } + M("ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray6() + [Fact] + public async Task TestParamArray6() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(params byte[] b) { - public void M(params byte[] b) - { - M(/* hi */ [|65, 66, 67|] /* there */); - } + M(/* hi */ [|65, 66, 67|] /* there */); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(params byte[] b) { - public void M(params byte[] b) - { - M(/* hi */ "ABC"u8.ToArray() /* there */); - } + M(/* hi */ "ABC"u8.ToArray() /* there */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray7() + [Fact] + public async Task TestParamArray7() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1); - } + M(1); } - """, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray8() + [Fact] + public async Task TestParamArray8() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1, [|65, 66, 67|]); - } + M(1, [|65, 66, 67|]); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1, "ABC"u8.ToArray()); - } + M(1, "ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray9() + [Fact] + public async Task TestParamArray9() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1, /* hi */ [|65|] /* there */); - } + M(1, /* hi */ [|65|] /* there */); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1, /* hi */ "A"u8.ToArray() /* there */); - } + M(1, /* hi */ "A"u8.ToArray() /* there */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray10() + [Fact] + public async Task TestParamArray10() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1, /* hi */ [|65, 66, 67|] /* there */); - } + M(1, /* hi */ [|65, 66, 67|] /* there */); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int x, params byte[] b) { - public void M(int x, params byte[] b) - { - M(1, /* hi */ "ABC"u8.ToArray() /* there */); - } + M(1, /* hi */ "ABC"u8.ToArray() /* there */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray11() + [Fact] + public async Task TestParamArray11() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int x, int y, int z, params byte[] b) { - public void M(int x, int y, int z, params byte[] b) - { - M( /* b1 */ 1 /* a1 */, /* b2 */ 2 /* a2 */, /* b3 */ 3 /* a3 */, /* b4 */ [|65, /* x1 */ 66, /* x2 */ 67|] /* a4 */); - } + M( /* b1 */ 1 /* a1 */, /* b2 */ 2 /* a2 */, /* b3 */ 3 /* a3 */, /* b4 */ [|65, /* x1 */ 66, /* x2 */ 67|] /* a4 */); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int x, int y, int z, params byte[] b) { - public void M(int x, int y, int z, params byte[] b) - { - M( /* b1 */ 1 /* a1 */, /* b2 */ 2 /* a2 */, /* b3 */ 3 /* a3 */, /* b4 */ "ABC"u8.ToArray() /* a4 */); - } + M( /* b1 */ 1 /* a1 */, /* b2 */ 2 /* a2 */, /* b3 */ 3 /* a3 */, /* b4 */ "ABC"u8.ToArray() /* a4 */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray12() + [Fact] + public async Task TestParamArray12() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public C(params byte[] b) { - public C(params byte[] b) - { - new C([|65, 66, 67|]); - } + new C([|65, 66, 67|]); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public C(params byte[] b) { - public C(params byte[] b) - { - new C("ABC"u8.ToArray()); - } + new C("ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray13() + [Fact] + public async Task TestParamArray13() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public int this[params byte[] bytes] { - public int this[params byte[] bytes] - { - get => 0; - } + get => 0; + } - public void M() - { - _ = this[[|65, 66, 67|]]; - } + public void M() + { + _ = this[[|65, 66, 67|]]; } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public int this[params byte[] bytes] { - public int this[params byte[] bytes] - { - get => 0; - } + get => 0; + } - public void M() - { - _ = this["ABC"u8.ToArray()]; - } + public void M() + { + _ = this["ABC"u8.ToArray()]; } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray14() + [Fact] + public async Task TestParamArray14() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - public record C1(int x) : B([|65, 66, 67|]); + TestCode = + """ + public record C1(int x) : B([|65, 66, 67|]); - public record C2(params byte[] Bytes) : B(Bytes); + public record C2(params byte[] Bytes) : B(Bytes); - public record B(params byte[] Bytes) + public record B(params byte[] Bytes) + { + public void M() { - public void M() - { - new C1(1); - new C2([|65, 66, 67|]); - new B([|65, 66, 67|]); - } + new C1(1); + new C2([|65, 66, 67|]); + new B([|65, 66, 67|]); } - namespace System.Runtime.CompilerServices + } + namespace System.Runtime.CompilerServices + { + public sealed class IsExternalInit { - public sealed class IsExternalInit - { - } } - """, - FixedCode = - """ - public record C1(int x) : B("ABC"u8.ToArray()); + } + """, + FixedCode = + """ + public record C1(int x) : B("ABC"u8.ToArray()); - public record C2(params byte[] Bytes) : B(Bytes); + public record C2(params byte[] Bytes) : B(Bytes); - public record B(params byte[] Bytes) + public record B(params byte[] Bytes) + { + public void M() { - public void M() - { - new C1(1); - new C2("ABC"u8.ToArray()); - new B("ABC"u8.ToArray()); - } + new C1(1); + new C2("ABC"u8.ToArray()); + new B("ABC"u8.ToArray()); } - namespace System.Runtime.CompilerServices + } + namespace System.Runtime.CompilerServices + { + public sealed class IsExternalInit { - public sealed class IsExternalInit - { - } } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray15() + [Fact] + public async Task TestParamArray15() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C1 : B { - TestCode = - """ - public class C1 : B + public C1(int x) + : base([|65, 66, 67|]) { - public C1(int x) - : base([|65, 66, 67|]) - { - } } + } - public class C2 : B + public class C2 : B + { + public C2(params byte[] Bytes) + : base(Bytes) { - public C2(params byte[] Bytes) - : base(Bytes) - { - } } + } - public class B + public class B + { + public B(string x, params byte[] bytes) + : this(bytes) { - public B(string x, params byte[] bytes) - : this(bytes) - { - } + } - public B(int x) - : this([|65, 66, 67|]) - { - } + public B(int x) + : this([|65, 66, 67|]) + { + } - public B(params byte[] bytes) - { - new C1(1); - new C2([|65, 66, 67|]); - new B([|65, 66, 67|]); - new B("a", [|65, 66, 67|]); - } + public B(params byte[] bytes) + { + new C1(1); + new C2([|65, 66, 67|]); + new B([|65, 66, 67|]); + new B("a", [|65, 66, 67|]); } - """, - FixedCode = - """ - public class C1 : B + } + """, + FixedCode = + """ + public class C1 : B + { + public C1(int x) + : base("ABC"u8.ToArray()) { - public C1(int x) - : base("ABC"u8.ToArray()) - { - } } + } - public class C2 : B + public class C2 : B + { + public C2(params byte[] Bytes) + : base(Bytes) { - public C2(params byte[] Bytes) - : base(Bytes) - { - } } + } - public class B + public class B + { + public B(string x, params byte[] bytes) + : this(bytes) { - public B(string x, params byte[] bytes) - : this(bytes) - { - } + } - public B(int x) - : this("ABC"u8.ToArray()) - { - } + public B(int x) + : this("ABC"u8.ToArray()) + { + } - public B(params byte[] bytes) - { - new C1(1); - new C2("ABC"u8.ToArray()); - new B("ABC"u8.ToArray()); - new B("a", "ABC"u8.ToArray()); - } + public B(params byte[] bytes) + { + new C1(1); + new C2("ABC"u8.ToArray()); + new B("ABC"u8.ToArray()); + new B("a", "ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray16() + [Fact] + public async Task TestParamArray16() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int[] i, byte[] b) { - public void M(int[] i, byte[] b) - { - M(new int[] { 1 }, [|new|] byte[] { 65, 66, 67 }); - } + M(new int[] { 1 }, [|new|] byte[] { 65, 66, 67 }); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int[] i, byte[] b) { - public void M(int[] i, byte[] b) - { - M(new int[] { 1 }, "ABC"u8.ToArray()); - } + M(new int[] { 1 }, "ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestParamArray17() + [Fact] + public async Task TestParamArray17() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(int[] i, params byte[] b) { - public void M(int[] i, params byte[] b) - { - M(new int[] { 1 }, [|65, 66, 67|]); - } + M(new int[] { 1 }, [|65, 66, 67|]); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(int[] i, params byte[] b) { - public void M(int[] i, params byte[] b) - { - M(new int[] { 1 }, "ABC"u8.ToArray()); - } + M(new int[] { 1 }, "ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestMultidimensionalArray() + [Fact] + public async Task TestMultidimensionalArray() + { + await new VerifyCS.Test { - await new VerifyCS.Test + TestCode = + """ + public class C { - TestCode = - """ - public class C + public void M(byte[][] i, byte[] b) { - public void M(byte[][] i, byte[] b) - { - M(new byte[][] { [|new|] byte[] { 65, 66, 67 }, [|new|] byte[] { 65, 66, 67 } }, [|new|] byte[] { 65, 66, 67 }); - } + M(new byte[][] { [|new|] byte[] { 65, 66, 67 }, [|new|] byte[] { 65, 66, 67 } }, [|new|] byte[] { 65, 66, 67 }); } - """, - FixedCode = - """ - public class C + } + """, + FixedCode = + """ + public class C + { + public void M(byte[][] i, byte[] b) { - public void M(byte[][] i, byte[] b) - { - M(new byte[][] { "ABC"u8.ToArray(), "ABC"u8.ToArray() }, "ABC"u8.ToArray()); - } + M(new byte[][] { "ABC"u8.ToArray(), "ABC"u8.ToArray() }, "ABC"u8.ToArray()); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestTargettingReadOnlySpan1() + [Fact] + public async Task TestTargettingReadOnlySpan1() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - using System; + TestCode = + """ + using System; - public class C + public class C + { + public void M() { - public void M() - { - ReadOnlySpan x = [|new|] byte[] { 65, 66, 67 }; - } + ReadOnlySpan x = [|new|] byte[] { 65, 66, 67 }; } - """, - FixedCode = - """ - using System; + } + """, + FixedCode = + """ + using System; - public class C + public class C + { + public void M() { - public void M() - { - ReadOnlySpan x = "ABC"u8; - } + ReadOnlySpan x = "ABC"u8; } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); + } - [Fact] - public async Task TestTargettingReadOnlySpan2() + [Fact] + public async Task TestTargettingReadOnlySpan2() + { + await new VerifyCS.Test { - await new VerifyCS.Test - { - TestCode = - """ - using System; + TestCode = + """ + using System; - public class C + public class C + { + public void M(ReadOnlySpan x) { - public void M(ReadOnlySpan x) - { - M(/* 1 */[|new|] byte[] { 65, 66, 67 }/* 2 */); - } + M(/* 1 */[|new|] byte[] { 65, 66, 67 }/* 2 */); } - """, - FixedCode = - """ - using System; + } + """, + FixedCode = + """ + using System; - public class C + public class C + { + public void M(ReadOnlySpan x) { - public void M(ReadOnlySpan x) - { - M(/* 1 */"ABC"u8/* 2 */); - } + M(/* 1 */"ABC"u8/* 2 */); } - """, - CodeActionValidationMode = CodeActionValidationMode.None, - ReferenceAssemblies = ReferenceAssemblies.Net.Net60, - LanguageVersion = LanguageVersion.CSharp12 - }.RunAsync(); - } + } + """, + CodeActionValidationMode = CodeActionValidationMode.None, + ReferenceAssemblies = ReferenceAssemblies.Net.Net60, + LanguageVersion = LanguageVersion.CSharp12 + }.RunAsync(); } } diff --git a/src/Analyzers/CSharp/Tests/UseVarTestExtensions.cs b/src/Analyzers/CSharp/Tests/UseVarTestExtensions.cs index e27c3c994b33d..637be3194a53f 100644 --- a/src/Analyzers/CSharp/Tests/UseVarTestExtensions.cs +++ b/src/Analyzers/CSharp/Tests/UseVarTestExtensions.cs @@ -12,183 +12,182 @@ using AbstractCodeActionOrUserDiagnosticTest = Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor; #endif -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions; + +internal static class UseVarTestExtensions { - internal static class UseVarTestExtensions - { - private static readonly CodeStyleOption2 onWithNone = new CodeStyleOption2(true, NotificationOption2.None); - private static readonly CodeStyleOption2 offWithNone = new CodeStyleOption2(false, NotificationOption2.None); - private static readonly CodeStyleOption2 onWithSilent = new CodeStyleOption2(true, NotificationOption2.Silent); - private static readonly CodeStyleOption2 offWithSilent = new CodeStyleOption2(false, NotificationOption2.Silent); - private static readonly CodeStyleOption2 onWithInfo = new CodeStyleOption2(true, NotificationOption2.Suggestion); - private static readonly CodeStyleOption2 offWithInfo = new CodeStyleOption2(false, NotificationOption2.Suggestion); - private static readonly CodeStyleOption2 onWithWarning = new CodeStyleOption2(true, NotificationOption2.Warning); - private static readonly CodeStyleOption2 offWithWarning = new CodeStyleOption2(false, NotificationOption2.Warning); - private static readonly CodeStyleOption2 offWithError = new CodeStyleOption2(false, NotificationOption2.Error); - private static readonly CodeStyleOption2 onWithError = new CodeStyleOption2(true, NotificationOption2.Error); + private static readonly CodeStyleOption2 onWithNone = new CodeStyleOption2(true, NotificationOption2.None); + private static readonly CodeStyleOption2 offWithNone = new CodeStyleOption2(false, NotificationOption2.None); + private static readonly CodeStyleOption2 onWithSilent = new CodeStyleOption2(true, NotificationOption2.Silent); + private static readonly CodeStyleOption2 offWithSilent = new CodeStyleOption2(false, NotificationOption2.Silent); + private static readonly CodeStyleOption2 onWithInfo = new CodeStyleOption2(true, NotificationOption2.Suggestion); + private static readonly CodeStyleOption2 offWithInfo = new CodeStyleOption2(false, NotificationOption2.Suggestion); + private static readonly CodeStyleOption2 onWithWarning = new CodeStyleOption2(true, NotificationOption2.Warning); + private static readonly CodeStyleOption2 offWithWarning = new CodeStyleOption2(false, NotificationOption2.Warning); + private static readonly CodeStyleOption2 offWithError = new CodeStyleOption2(false, NotificationOption2.Error); + private static readonly CodeStyleOption2 onWithError = new CodeStyleOption2(true, NotificationOption2.Error); #if false - public static OptionsCollection PreferExplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithError }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithError }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithError }, - }; - - public static OptionsCollection PreferImplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithError }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithError }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithError }, - }; - - public static OptionsCollection PreferExplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithWarning }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithWarning }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithWarning }, - }; - - public static OptionsCollection PreferImplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithWarning }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithWarning }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithWarning }, - }; - - public static OptionsCollection PreferExplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; - - public static OptionsCollection PreferImplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, - }; - - public static OptionsCollection PreferExplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithSilent }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithSilent }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithSilent }, - }; - - public static OptionsCollection PreferImplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithSilent }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithSilent }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithSilent }, - }; - - public static OptionsCollection PreferExplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithNone }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithNone }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithNone }, - }; - - public static OptionsCollection PreferImplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithNone }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithNone }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithNone }, - }; + public static OptionsCollection PreferExplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithError }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithError }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithError }, + }; + + public static OptionsCollection PreferImplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithError }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithError }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithError }, + }; + + public static OptionsCollection PreferExplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithWarning }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithWarning }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithWarning }, + }; + + public static OptionsCollection PreferImplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithWarning }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithWarning }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithWarning }, + }; + + public static OptionsCollection PreferExplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; + + public static OptionsCollection PreferImplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, + }; + + public static OptionsCollection PreferExplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithSilent }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithSilent }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithSilent }, + }; + + public static OptionsCollection PreferImplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithSilent }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithSilent }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithSilent }, + }; + + public static OptionsCollection PreferExplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithNone }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithNone }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithNone }, + }; + + public static OptionsCollection PreferImplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithNone }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithNone }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithNone }, + }; #endif - public static OptionsCollection PreferExplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithError }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithError }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithError }, - }; - - public static OptionsCollection PreferImplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithError }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithError }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithError }, - }; - - public static OptionsCollection PreferExplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithWarning }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithWarning }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithWarning }, - }; - - public static OptionsCollection PreferImplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithWarning }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithWarning }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithWarning }, - }; - - public static OptionsCollection PreferExplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, - }; - - public static OptionsCollection PreferImplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, - }; - - public static OptionsCollection PreferExplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithSilent }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithSilent }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithSilent }, - }; - - public static OptionsCollection PreferImplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithSilent }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithSilent }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithSilent }, - }; - - public static OptionsCollection PreferExplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, offWithNone }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithNone }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithNone }, - }; - - public static OptionsCollection PreferImplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) - => new OptionsCollection(test.GetLanguage()) - { - { CSharpCodeStyleOptions.VarElsewhere, onWithNone }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithNone }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithNone }, - }; - } + public static OptionsCollection PreferExplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithError }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithError }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithError }, + }; + + public static OptionsCollection PreferImplicitTypeWithError(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithError }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithError }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithError }, + }; + + public static OptionsCollection PreferExplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithWarning }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithWarning }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithWarning }, + }; + + public static OptionsCollection PreferImplicitTypeWithWarning(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithWarning }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithWarning }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithWarning }, + }; + + public static OptionsCollection PreferExplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithInfo }, + }; + + public static OptionsCollection PreferImplicitTypeWithInfo(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithInfo }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithInfo }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithInfo }, + }; + + public static OptionsCollection PreferExplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithSilent }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithSilent }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithSilent }, + }; + + public static OptionsCollection PreferImplicitTypeWithSilent(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithSilent }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithSilent }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithSilent }, + }; + + public static OptionsCollection PreferExplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, offWithNone }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, offWithNone }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, offWithNone }, + }; + + public static OptionsCollection PreferImplicitTypeWithNone(this AbstractCodeActionOrUserDiagnosticTest_NoEditor test) + => new OptionsCollection(test.GetLanguage()) + { + { CSharpCodeStyleOptions.VarElsewhere, onWithNone }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, onWithNone }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, onWithNone }, + }; } diff --git a/src/Analyzers/CSharp/Tests/ValidateFormatString/ValidateFormatStringTests.cs b/src/Analyzers/CSharp/Tests/ValidateFormatString/ValidateFormatStringTests.cs index b0974fa0e23ad..a06235ce783dc 100644 --- a/src/Analyzers/CSharp/Tests/ValidateFormatString/ValidateFormatStringTests.cs +++ b/src/Analyzers/CSharp/Tests/ValidateFormatString/ValidateFormatStringTests.cs @@ -12,1129 +12,1128 @@ using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ValidateFormatString +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ValidateFormatString; + +[Trait(Traits.Feature, Traits.Features.ValidateFormatString)] +public class ValidateFormatStringTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor { - [Trait(Traits.Feature, Traits.Features.ValidateFormatString)] - public class ValidateFormatStringTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor + public ValidateFormatStringTests(ITestOutputHelper logger) + : base(logger) { - public ValidateFormatStringTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider?) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpValidateFormatStringDiagnosticAnalyzer(), null); + internal override (DiagnosticAnalyzer, CodeFixProvider?) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (new CSharpValidateFormatStringDiagnosticAnalyzer(), null); - [Fact] - public async Task OnePlaceholder() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This {0[||]} works", "test"); - } - } - """); - } + [Fact] + public async Task OnePlaceholder() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This {0[||]} works", "test"); + } + } + """); + } - [Fact] - public async Task TwoPlaceholders() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This {0[||]} {1} works", "test", "also"); - } - } - """); - } + [Fact] + public async Task TwoPlaceholders() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This {0[||]} {1} works", "test", "also"); + } + } + """); + } - [Fact] - public async Task ThreePlaceholders() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This {0} {1[||]} works {2} ", "test", "also", "well"); - } - } - """); - } + [Fact] + public async Task ThreePlaceholders() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This {0} {1[||]} works {2} ", "test", "also", "well"); + } + } + """); + } - [Fact] - public async Task FourPlaceholders() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This {1} is {2} my {6[||]} test ", "teststring1", "teststring2", - "teststring3", "teststring4", "teststring5", "teststring6", "teststring7"); - } - } - """); - } + [Fact] + public async Task FourPlaceholders() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This {1} is {2} my {6[||]} test ", "teststring1", "teststring2", + "teststring3", "teststring4", "teststring5", "teststring6", "teststring7"); + } + } + """); + } - [Fact] - public async Task ObjectArray() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - object[] objectArray = { 1.25, "2", "teststring"}; - string.Format("This {0} {1} {2[||]} works", objectArray); - } - } - """); - } + [Fact] + public async Task ObjectArray() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + object[] objectArray = { 1.25, "2", "teststring"}; + string.Format("This {0} {1} {2[||]} works", objectArray); + } + } + """); + } - [Fact] - public async Task MultipleObjectArrays() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - object[] objectArray = { 1.25, "2", "teststring"}; - string.Format("This {0} {1} {2[||]} works", objectArray, objectArray, objectArray, objectArray); - } - } - """); - } + [Fact] + public async Task MultipleObjectArrays() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + object[] objectArray = { 1.25, "2", "teststring"}; + string.Format("This {0} {1} {2[||]} works", objectArray, objectArray, objectArray, objectArray); + } + } + """); + } - [Fact] - public async Task IntArray() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - int[] intArray = {1, 2, 3}; - string.Format("This {0[||]} works", intArray); - } - } - """); - } + [Fact] + public async Task IntArray() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2, 3}; + string.Format("This {0[||]} works", intArray); + } + } + """); + } - [Fact] - public async Task StringArray() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string[] stringArray = {"test1", "test2", "test3"}; - string.Format("This {0} {1} {2[||]} works", stringArray); - } - } - """); - } + [Fact] + public async Task StringArray() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string[] stringArray = {"test1", "test2", "test3"}; + string.Format("This {0} {1} {2[||]} works", stringArray); + } + } + """); + } - [Fact] - public async Task LiteralArray() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This {0[||]} {1} {2} {3} works", new [] {"test1", "test2", "test3", "test4"}); - } - } - """); - } + [Fact] + public async Task LiteralArray() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This {0[||]} {1} {2} {3} works", new [] {"test1", "test2", "test3", "test4"}); + } + } + """); + } - [Fact] - public async Task StringArrayOutOfBounds_NoDiagnostic() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string[] stringArray = {"test1", "test2"}; - string.Format("This {0} {1} {2[||]} works", stringArray); - } - } - """); - } + [Fact] + public async Task StringArrayOutOfBounds_NoDiagnostic() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string[] stringArray = {"test1", "test2"}; + string.Format("This {0} {1} {2[||]} works", stringArray); + } + } + """); + } - [Fact] - public async Task IFormatProviderAndOnePlaceholder() - { - await TestDiagnosticMissingAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0[||]:C2} per ounce", 2.45); - } - } - """); - } + [Fact] + public async Task IFormatProviderAndOnePlaceholder() + { + await TestDiagnosticMissingAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0[||]:C2} per ounce", 2.45); + } + } + """); + } - [Fact] - public async Task IFormatProviderAndTwoPlaceholders() - { - await TestDiagnosticMissingAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0[||]:C2} per {1} ", 2.45, "ounce"); - } - } - """); - } + [Fact] + public async Task IFormatProviderAndTwoPlaceholders() + { + await TestDiagnosticMissingAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0[||]:C2} per {1} ", 2.45, "ounce"); + } + } + """); + } - [Fact] - public async Task IFormatProviderAndThreePlaceholders() - { - await TestDiagnosticMissingAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0} {[||]1} {2} ", - 2.45, "per", "ounce"); - } - } - """); - } + [Fact] + public async Task IFormatProviderAndThreePlaceholders() + { + await TestDiagnosticMissingAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0} {[||]1} {2} ", + 2.45, "per", "ounce"); + } + } + """); + } - [Fact] - public async Task IFormatProviderAndFourPlaceholders() - { - await TestDiagnosticMissingAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0} {1[||]} {2} {3} ", - 2.45, "per", "ounce", "today only"); - } - } - """); - } + [Fact] + public async Task IFormatProviderAndFourPlaceholders() + { + await TestDiagnosticMissingAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + testStr = string.Format(new CultureInfo("pt-BR", useUserOverride: false), "The current price is {0} {1[||]} {2} {3} ", + 2.45, "per", "ounce", "today only"); + } + } + """); + } - [Fact] - public async Task IFormatProviderAndObjectArray() - { - await TestDiagnosticMissingAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - object[] objectArray = { 1.25, "2", "teststring"}; - string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This {0} {1} {[||]2} works", objectArray); - } - } - """); - } + [Fact] + public async Task IFormatProviderAndObjectArray() + { + await TestDiagnosticMissingAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + object[] objectArray = { 1.25, "2", "teststring"}; + string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This {0} {1} {[||]2} works", objectArray); + } + } + """); + } - [Fact] - public async Task WithComma() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("{0[||],6}", 34); - } - } - """); - } + [Fact] + public async Task WithComma() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("{0[||],6}", 34); + } + } + """); + } - [Fact] - public async Task WithColon() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("{[||]0:N0}", 34); - } - } - """); - } + [Fact] + public async Task WithColon() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("{[||]0:N0}", 34); + } + } + """); + } - [Fact] - public async Task WithCommaAndColon() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("Test {0,[||]15:N0} output", 34); - } - } - """); - } + [Fact] + public async Task WithCommaAndColon() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("Test {0,[||]15:N0} output", 34); + } + } + """); + } - [Fact] - public async Task WithPlaceholderAtBeginning() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("{0[||]} is my test case", "This"); - } - } - """); - } + [Fact] + public async Task WithPlaceholderAtBeginning() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("{0[||]} is my test case", "This"); + } + } + """); + } - [Fact] - public async Task WithPlaceholderAtEnd() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This is my {0[||]}", "test"); - } - } - """); - } + [Fact] + public async Task WithPlaceholderAtEnd() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This is my {0[||]}", "test"); + } + } + """); + } - [Fact] - public async Task WithDoubleBraces() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format(" {{ 2}} This {1[||]} is {2} {{ my {0} test }} ", "teststring1", "teststring2", "teststring3"); - } - } - """); - } + [Fact] + public async Task WithDoubleBraces() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format(" {{ 2}} This {1[||]} is {2} {{ my {0} test }} ", "teststring1", "teststring2", "teststring3"); + } + } + """); + } - [Fact] - public async Task WithDoubleBracesAtBeginning() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("{{ 2}} This {1[||]} is {2} {{ my {0} test }} ", "teststring1", "teststring2", "teststring3"); - } - } - """); - } + [Fact] + public async Task WithDoubleBracesAtBeginning() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("{{ 2}} This {1[||]} is {2} {{ my {0} test }} ", "teststring1", "teststring2", "teststring3"); + } + } + """); + } - [Fact] - public async Task WithDoubleBracesAtEnd() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format(" {{ 2}} This {1[||]} is {2} {{ my {0} test }}", "teststring1", "teststring2", "teststring3"); - } - } - """); - } + [Fact] + public async Task WithDoubleBracesAtEnd() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format(" {{ 2}} This {1[||]} is {2} {{ my {0} test }}", "teststring1", "teststring2", "teststring3"); + } + } + """); + } - [Fact] - public async Task WithTripleBraces() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format(" {{{2}} This {1[||]} is {2} {{ my {0} test }}", "teststring1", "teststring2", "teststring3"); - } - } - """); - } + [Fact] + public async Task WithTripleBraces() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format(" {{{2}} This {1[||]} is {2} {{ my {0} test }}", "teststring1", "teststring2", "teststring3"); + } + } + """); + } - [Fact] - public async Task NamedParameters() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format(arg0: "test", arg1: "also", format: "This {0} {[||]1} works"); - } - } - """); - } + [Fact] + public async Task NamedParameters() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format(arg0: "test", arg1: "also", format: "This {0} {[||]1} works"); + } + } + """); + } - [Fact] - public async Task NamedParametersWithIFormatProvider() - { - await TestDiagnosticMissingAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(arg0: "test", provider: new CultureInfo("pt-BR", useUserOverride: false), format: "This {0[||]} works"); - } - } - """); - } + [Fact] + public async Task NamedParametersWithIFormatProvider() + { + await TestDiagnosticMissingAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(arg0: "test", provider: new CultureInfo("pt-BR", useUserOverride: false), format: "This {0[||]} works"); + } + } + """); + } - [Fact] - public async Task NamespaceAliasForStringClass() - { - await TestDiagnosticMissingAsync(""" - using stringAlias = System.String; - class Program - { - static void Main(string[] args) - { - stringAlias.Format("This {0[||]} works", "test"); - } - } - """); - } + [Fact] + public async Task NamespaceAliasForStringClass() + { + await TestDiagnosticMissingAsync(""" + using stringAlias = System.String; + class Program + { + static void Main(string[] args) + { + stringAlias.Format("This {0[||]} works", "test"); + } + } + """); + } - [Fact] - public async Task MethodCallAsAnArgumentToAnotherMethod() - { - await TestDiagnosticMissingAsync(""" - using System.IO; - class Program + [Fact] + public async Task MethodCallAsAnArgumentToAnotherMethod() + { + await TestDiagnosticMissingAsync(""" + using System.IO; + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine(string.Format(format: "This {0[||]} works", arg0:"test")); - } + Console.WriteLine(string.Format(format: "This {0[||]} works", arg0:"test")); } - """); - } + } + """); + } - [Fact] - public async Task VerbatimMultipleLines() - { - await TestDiagnosticMissingAsync(""" - class Program + [Fact] + public async Task VerbatimMultipleLines() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - string.Format(@"This {0} - {1} {2[||]} works", "multiple", "line", "test")); - } + string.Format(@"This {0} + {1} {2[||]} works", "multiple", "line", "test")); } - """); - } + } + """); + } - [Fact] - public async Task Interpolated() - { - await TestDiagnosticMissingAsync(""" - class Program + [Fact] + public async Task Interpolated() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - var Name = "Peter"; - var Age = 30; + var Name = "Peter"; + var Age = 30; - string.Format($"{Name,[||] 20} is {Age:D3} "); - } + string.Format($"{Name,[||] 20} is {Age:D3} "); } - """); - } + } + """); + } - [Fact] - public async Task Empty() - { - await TestDiagnosticMissingAsync(""" - class Program + [Fact] + public async Task Empty() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - string.Format("[||]"); - } + string.Format("[||]"); } - """); - } + } + """); + } - [Fact] - public async Task LeftParenOnly() - { - await TestDiagnosticMissingAsync(""" - class Program + [Fact] + public async Task LeftParenOnly() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - string.Format([||]; - } + string.Format([||]; } - """); - } + } + """); + } - [Fact] - public async Task ParenthesesOnly() - { - await TestDiagnosticMissingAsync(""" - class Program + [Fact] + public async Task ParenthesesOnly() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - string.Format([||]); - } + string.Format([||]); } - """); - } + } + """); + } - [Fact] - public async Task EmptyString() - { - await TestDiagnosticMissingAsync(""" - class Program + [Fact] + public async Task EmptyString() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - string.Format("[||]"); - } + string.Format("[||]"); } - """); - } + } + """); + } - [Fact] - public async Task FormatOnly_NoStringDot() - { - await TestDiagnosticMissingAsync(""" - using static System.String - class Program + [Fact] + public async Task FormatOnly_NoStringDot() + { + await TestDiagnosticMissingAsync(""" + using static System.String + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - Format("[||]"); - } + Format("[||]"); } - """); - } + } + """); + } - [Fact] - public async Task NamedParameters_BlankName() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format( : "value"[||])); - } - } - """); - } + [Fact] + public async Task NamedParameters_BlankName() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format( : "value"[||])); + } + } + """); + } - [Fact] - public async Task DuplicateNamedArgs() - { - await TestDiagnosticMissingAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format(format:"This [||] ", format:" test "); - } - } - """); - } + [Fact] + public async Task DuplicateNamedArgs() + { + await TestDiagnosticMissingAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format(format:"This [||] ", format:" test "); + } + } + """); + } - [Fact] - public async Task GenericIdentifier() - { - await TestDiagnosticMissingAsync(""" - using System; - using System.Collections; - using System.Collections.Generic; - using System.Text; + [Fact] + public async Task GenericIdentifier() + { + await TestDiagnosticMissingAsync(""" + using System; + using System.Collections; + using System.Collections.Generic; + using System.Text; - namespace Generics_CSharp + namespace Generics_CSharp + { + public class String { - public class String + public void Format(string teststr) { - public void Format(string teststr) - { - Console.WriteLine(teststr); - } + Console.WriteLine(teststr); } + } - class Generics + class Generics + { + static void Main(string[] args) { - static void Main(string[] args) - { - String testList = new String(); - testList.Format("Test[||]String"); - } + String testList = new String(); + testList.Format("Test[||]String"); } } - """); - } + } + """); + } - [Fact] - public async Task ClassNamedString() - { - await TestDiagnosticMissingAsync(""" - using System; + [Fact] + public async Task ClassNamedString() + { + await TestDiagnosticMissingAsync(""" + using System; - namespace System + namespace System + { + public class String { - public class String - { - public static String Format(string format, object arg0) { return new String(); } - } + public static String Format(string format, object arg0) { return new String(); } } + } - class C + class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - Console.WriteLine(String.Format("test {[||]5} ", 1)); - } + Console.WriteLine(String.Format("test {[||]5} ", 1)); } - """); - } + } + """); + } #if CODE_STYLE - // Option has no effect on CodeStyle layer CI execution as it is not an editorconfig option. - [Fact] - public async Task TestOption_Ignored() - { - var source = """ - class Program - { - static void Main(string[] args) - { - string.Format("This [|{1}|] is my test", "teststring1"); - } - } - """; - await TestDiagnosticInfoAsync( - source, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } + // Option has no effect on CodeStyle layer CI execution as it is not an editorconfig option. + [Fact] + public async Task TestOption_Ignored() + { + var source = """ + class Program + { + static void Main(string[] args) + { + string.Format("This [|{1}|] is my test", "teststring1"); + } + } + """; + await TestDiagnosticInfoAsync( + source, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } #else - [Fact] - public async Task TestOption_Enabled() - { - var source = """ - class Program - { - static void Main(string[] args) - { - string.Format("This [|{1}|] is my test", "teststring1"); - } - } - """; - var options = Option(IdeAnalyzerOptionsStorage.ReportInvalidPlaceholdersInStringDotFormatCalls, true); - - await TestDiagnosticInfoAsync( - source, - options: null, - globalOptions: options, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task TestOption_Disabled() - { - var source = """ - class Program - { - static void Main(string[] args) - { - string.Format("This [|{1}|] is my test", "teststring1"); - } - } - """; - var options = Option(IdeAnalyzerOptionsStorage.ReportInvalidPlaceholdersInStringDotFormatCalls, false); + [Fact] + public async Task TestOption_Enabled() + { + var source = """ + class Program + { + static void Main(string[] args) + { + string.Format("This [|{1}|] is my test", "teststring1"); + } + } + """; + var options = Option(IdeAnalyzerOptionsStorage.ReportInvalidPlaceholdersInStringDotFormatCalls, true); + + await TestDiagnosticInfoAsync( + source, + options: null, + globalOptions: options, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } - await TestDiagnosticMissingAsync(source, new TestParameters(globalOptions: options)); - } + [Fact] + public async Task TestOption_Disabled() + { + var source = """ + class Program + { + static void Main(string[] args) + { + string.Format("This [|{1}|] is my test", "teststring1"); + } + } + """; + var options = Option(IdeAnalyzerOptionsStorage.ReportInvalidPlaceholdersInStringDotFormatCalls, false); + + await TestDiagnosticMissingAsync(source, new TestParameters(globalOptions: options)); + } #endif - [Fact] - public async Task OnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This [|{1}|] is my test", "teststring1"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task TwoPlaceholdersWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This [|{2}|] is my test", "teststring1", "teststring2"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task ThreePlaceholdersWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This{0}{1}{2}[|{3}|] is my test", "teststring1", "teststring2", "teststring3"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task FourPlaceholdersWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format("This{0}{1}{2}{3}[|{4}|] is my test", "teststring1", "teststring2", - "teststring3", "teststring4"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task iFormatProviderAndOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This [|{1}|] is my test", "teststring1"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task iFormatProviderAndTwoPlaceholdersWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This [|{2}|] is my test", "teststring1", "teststring2"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task IFormatProviderAndThreePlaceholdersWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This{0}{1}{2}[|{3}|] is my test", "teststring1", - "teststring2", "teststring3"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task IFormatProviderAndFourPlaceholdersWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This{0}{1}{2}{3}[|{4}|] is my test", "teststring1", - "teststring2", "teststring3", "teststring4"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task PlaceholderAtBeginningWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format( "[|{1}|]is my test", "teststring1"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task PlaceholderAtEndWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format( "is my test [|{2}|]", "teststring1", "teststring2"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task DoubleBracesAtBeginningWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format( "}}is my test [|{2}|]", "teststring1", "teststring2"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task DoubleBracesAtEndWithOnePlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format( "is my test [|{2}|]{{", "teststring1", "teststring2"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task NamedParametersOneOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(arg0: "test", arg1: "also", format: "This {0} [|{2}|] works"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task NamedParametersWithIFormatProviderOneOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using System.Globalization; - class Program - { - static void Main(string[] args) - { - string.Format(arg0: "test", arg1: "also", format: "This {0} [|{2}|] works", provider: new CultureInfo("pt-BR", useUserOverride: false)) - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task FormatOnly_NoStringDot_OneOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - using static System.String - class Program - { - static void Main(string[] args) - { - Format("This {0} [|{2}|] squiggles", "test", "gets"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task Net45TestOutOfBounds() - { - var input = """ - < Workspace > - < Project Language = "C#" AssemblyName="Assembly1" CommonReferencesNet45="true"> - - - - - """; - await TestDiagnosticInfoAsync(input, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task VerbatimMultipleLinesPlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - string.Format(@"This {0} - {1} [|{3}|] works", "multiple", "line", "test")); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task IntArrayOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - int[] intArray = {1, 2}; - string.Format("This {0} [|{1}|] {2} works", intArray); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task FirstPlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - int[] intArray = {1, 2}; - string.Format("This {0} [|{1}|] {2} works", "TestString"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task SecondPlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - int[] intArray = {1, 2}; - string.Format("This {0} {1} [|{2}|] works", "TestString"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task FirstOfMultipleSameNamedPlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - int[] intArray = {1, 2}; - string.Format("This {0} [|{2}|] {2} works", "TestString"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task SecondOfMultipleSameNamedPlaceholderOutOfBounds() - { - await TestDiagnosticInfoAsync(""" - class Program - { - static void Main(string[] args) - { - int[] intArray = {1, 2}; - string.Format("This {0} {2} [|{2}|] works", "TestString"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact] - public async Task EmptyPlaceholder() - { - await TestDiagnosticInfoAsync(""" - class Program + [Fact] + public async Task OnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This [|{1}|] is my test", "teststring1"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task TwoPlaceholdersWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This [|{2}|] is my test", "teststring1", "teststring2"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task ThreePlaceholdersWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This{0}{1}{2}[|{3}|] is my test", "teststring1", "teststring2", "teststring3"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task FourPlaceholdersWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format("This{0}{1}{2}{3}[|{4}|] is my test", "teststring1", "teststring2", + "teststring3", "teststring4"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task iFormatProviderAndOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This [|{1}|] is my test", "teststring1"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task iFormatProviderAndTwoPlaceholdersWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This [|{2}|] is my test", "teststring1", "teststring2"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task IFormatProviderAndThreePlaceholdersWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This{0}{1}{2}[|{3}|] is my test", "teststring1", + "teststring2", "teststring3"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task IFormatProviderAndFourPlaceholdersWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(new CultureInfo("pt-BR", useUserOverride: false), "This{0}{1}{2}{3}[|{4}|] is my test", "teststring1", + "teststring2", "teststring3", "teststring4"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task PlaceholderAtBeginningWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format( "[|{1}|]is my test", "teststring1"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task PlaceholderAtEndWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format( "is my test [|{2}|]", "teststring1", "teststring2"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task DoubleBracesAtBeginningWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format( "}}is my test [|{2}|]", "teststring1", "teststring2"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task DoubleBracesAtEndWithOnePlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format( "is my test [|{2}|]{{", "teststring1", "teststring2"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task NamedParametersOneOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(arg0: "test", arg1: "also", format: "This {0} [|{2}|] works"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task NamedParametersWithIFormatProviderOneOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using System.Globalization; + class Program + { + static void Main(string[] args) + { + string.Format(arg0: "test", arg1: "also", format: "This {0} [|{2}|] works", provider: new CultureInfo("pt-BR", useUserOverride: false)) + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task FormatOnly_NoStringDot_OneOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + using static System.String + class Program + { + static void Main(string[] args) + { + Format("This {0} [|{2}|] squiggles", "test", "gets"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task Net45TestOutOfBounds() + { + var input = """ + < Workspace > + < Project Language = "C#" AssemblyName="Assembly1" CommonReferencesNet45="true"> + + + + + """; + await TestDiagnosticInfoAsync(input, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task VerbatimMultipleLinesPlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + string.Format(@"This {0} + {1} [|{3}|] works", "multiple", "line", "test")); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task IntArrayOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2}; + string.Format("This {0} [|{1}|] {2} works", intArray); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task FirstPlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2}; + string.Format("This {0} [|{1}|] {2} works", "TestString"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task SecondPlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2}; + string.Format("This {0} {1} [|{2}|] works", "TestString"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task FirstOfMultipleSameNamedPlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2}; + string.Format("This {0} [|{2}|] {2} works", "TestString"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task SecondOfMultipleSameNamedPlaceholderOutOfBounds() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2}; + string.Format("This {0} {2} [|{2}|] works", "TestString"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact] + public async Task EmptyPlaceholder() + { + await TestDiagnosticInfoAsync(""" + class Program + { + static void Main(string[] args) + { + int[] intArray = {1, 2}; + string.Format("This [|{}|] ", "TestString"); + } + } + """, + options: null, + diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, + diagnosticSeverity: DiagnosticSeverity.Info, + diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29398")] + public async Task LocalFunctionNamedFormat() + { + await TestDiagnosticMissingAsync(""" + public class C + { + public void M() { - static void Main(string[] args) - { - int[] intArray = {1, 2}; - string.Format("This [|{}|] ", "TestString"); - } - } - """, - options: null, - diagnosticId: IDEDiagnosticIds.ValidateFormatStringDiagnosticID, - diagnosticSeverity: DiagnosticSeverity.Info, - diagnosticMessage: AnalyzersResources.Format_string_contains_invalid_placeholder); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29398")] - public async Task LocalFunctionNamedFormat() - { - await TestDiagnosticMissingAsync(""" - public class C - { - public void M() - { - Forma[||]t(); - void Format() { } - } + Forma[||]t(); + void Format() { } } - """); - } + } + """); } } diff --git a/src/Analyzers/Core/Analyzers/Formatting/FormatterHelper.cs b/src/Analyzers/Core/Analyzers/Formatting/FormatterHelper.cs index cc91eb9d9ddc7..ad221cea502b9 100644 --- a/src/Analyzers/Core/Analyzers/Formatting/FormatterHelper.cs +++ b/src/Analyzers/Core/Analyzers/Formatting/FormatterHelper.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.Text; @@ -30,10 +31,10 @@ internal static IEnumerable GetDefaultFormattingRules(IS /// An optional cancellation token. /// The formatted tree's root node. public static SyntaxNode Format(SyntaxNode node, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, CancellationToken cancellationToken) - => Format(node, [node.FullSpan], syntaxFormattingService, options, rules: null, cancellationToken: cancellationToken); + => Format(node, [node.FullSpan], syntaxFormattingService, options, rules: default, cancellationToken: cancellationToken); public static SyntaxNode Format(SyntaxNode node, TextSpan spanToFormat, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, CancellationToken cancellationToken) - => Format(node, [spanToFormat], syntaxFormattingService, options, rules: null, cancellationToken: cancellationToken); + => Format(node, [spanToFormat], syntaxFormattingService, options, rules: default, cancellationToken: cancellationToken); /// /// Formats the whitespace of a syntax tree. @@ -44,15 +45,15 @@ public static SyntaxNode Format(SyntaxNode node, TextSpan spanToFormat, ISyntaxF /// An optional cancellation token. /// The formatted tree's root node. public static SyntaxNode Format(SyntaxNode node, SyntaxAnnotation annotation, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) - => Format(node, GetAnnotatedSpans(node, annotation), syntaxFormattingService, options, rules, cancellationToken: cancellationToken); + => Format(node, GetAnnotatedSpans(node, annotation), syntaxFormattingService, options, rules.AsImmutableOrNull(), cancellationToken: cancellationToken); - internal static SyntaxNode Format(SyntaxNode node, IEnumerable spans, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + internal static SyntaxNode Format(SyntaxNode node, IEnumerable spans, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, ImmutableArray rules, CancellationToken cancellationToken) => GetFormattingResult(node, spans, syntaxFormattingService, options, rules, cancellationToken).GetFormattedRoot(cancellationToken); - internal static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable spans, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + internal static IList GetFormattedTextChanges(SyntaxNode node, IEnumerable spans, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, ImmutableArray rules, CancellationToken cancellationToken) => GetFormattingResult(node, spans, syntaxFormattingService, options, rules, cancellationToken).GetTextChanges(cancellationToken); - internal static IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerable spans, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, IEnumerable? rules, CancellationToken cancellationToken) + internal static IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerable spans, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, ImmutableArray rules, CancellationToken cancellationToken) => syntaxFormattingService.GetFormattingResult(node, spans, options, rules, cancellationToken); /// @@ -63,5 +64,5 @@ internal static IFormattingResult GetFormattingResult(SyntaxNode node, IEnumerab /// An optional cancellation token. /// The changes necessary to format the tree. public static IList GetFormattedTextChanges(SyntaxNode node, ISyntaxFormatting syntaxFormattingService, SyntaxFormattingOptions options, CancellationToken cancellationToken) - => GetFormattedTextChanges(node, [node.FullSpan], syntaxFormattingService, options, rules: null, cancellationToken: cancellationToken); + => GetFormattedTextChanges(node, [node.FullSpan], syntaxFormattingService, options, rules: default, cancellationToken: cancellationToken); } diff --git a/src/Analyzers/Core/Analyzers/Formatting/FormattingAnalyzerHelper.cs b/src/Analyzers/Core/Analyzers/Formatting/FormattingAnalyzerHelper.cs index 572aa92beeb8c..7eb990634811a 100644 --- a/src/Analyzers/Core/Analyzers/Formatting/FormattingAnalyzerHelper.cs +++ b/src/Analyzers/Core/Analyzers/Formatting/FormattingAnalyzerHelper.cs @@ -24,7 +24,7 @@ internal static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context, Format var root = tree.GetRoot(cancellationToken); var span = context.FilterSpan.HasValue ? context.FilterSpan.GetValueOrDefault() : root.FullSpan; var spans = SpecializedCollections.SingletonEnumerable(span); - var formattingChanges = Formatter.GetFormattedTextChanges(root, spans, formattingProvider, options, rules: null, cancellationToken); + var formattingChanges = Formatter.GetFormattedTextChanges(root, spans, formattingProvider, options, rules: default, cancellationToken); // formattingChanges could include changes that impact a larger section of the original document than // necessary. Before reporting diagnostics, process the changes to minimize the span of individual diff --git a/src/Analyzers/Core/Analyzers/NewLines/ConsecutiveStatementPlacement/AbstractConsecutiveStatementPlacementDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/NewLines/ConsecutiveStatementPlacement/AbstractConsecutiveStatementPlacementDiagnosticAnalyzer.cs index 6f2572311e6d6..5af03023ac6ab 100644 --- a/src/Analyzers/Core/Analyzers/NewLines/ConsecutiveStatementPlacement/AbstractConsecutiveStatementPlacementDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/NewLines/ConsecutiveStatementPlacement/AbstractConsecutiveStatementPlacementDiagnosticAnalyzer.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.NewLines.ConsecutiveStatementPlacement; @@ -59,8 +60,8 @@ private void Recurse(SyntaxTreeAnalysisContext context, NotificationOption2 noti if (!context.ShouldAnalyzeSpan(child.FullSpan)) continue; - if (child.IsNode) - Recurse(context, notificationOption, child.AsNode()!, cancellationToken); + if (child.AsNode(out var childNode)) + Recurse(context, notificationOption, childNode, cancellationToken); } } diff --git a/src/Analyzers/Core/Analyzers/NewLines/MultipleBlankLines/AbstractMultipleBlankLinesDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/NewLines/MultipleBlankLines/AbstractMultipleBlankLinesDiagnosticAnalyzer.cs index 45b7cf0ac6921..c69ddbcdd7de6 100644 --- a/src/Analyzers/Core/Analyzers/NewLines/MultipleBlankLines/AbstractMultipleBlankLinesDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/NewLines/MultipleBlankLines/AbstractMultipleBlankLinesDiagnosticAnalyzer.cs @@ -4,10 +4,10 @@ using System.Collections.Immutable; using System.Threading; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.NewLines.MultipleBlankLines; @@ -59,8 +59,8 @@ private void Recurse( if (!context.ShouldAnalyzeSpan(child.FullSpan)) continue; - if (child.IsNode) - Recurse(context, notificationOption, child.AsNode()!, cancellationToken); + if (child.AsNode(out var childNode)) + Recurse(context, notificationOption, childNode, cancellationToken); else if (child.IsToken) CheckToken(context, notificationOption, child.AsToken()); } diff --git a/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchExpressionHelpers.cs b/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchExpressionHelpers.cs index 2e4336069220e..828eb3fa49939 100644 --- a/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchExpressionHelpers.cs +++ b/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchExpressionHelpers.cs @@ -62,7 +62,7 @@ private static void RemoveExistingEnumMembers( } } - private static void HandleBinaryPattern(IBinaryPatternOperation? binaryPattern, Dictionary enumMembers) + internal static void HandleBinaryPattern(IBinaryPatternOperation? binaryPattern, Dictionary enumMembers) { if (binaryPattern?.OperatorKind == BinaryOperatorKind.Or) { diff --git a/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchStatementHelpers.cs b/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchStatementHelpers.cs index 710252b1e2b38..17ccd7460211a 100644 --- a/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchStatementHelpers.cs +++ b/src/Analyzers/Core/Analyzers/PopulateSwitch/PopulateSwitchStatementHelpers.cs @@ -133,6 +133,14 @@ private static bool TryRemoveExistingEnumMembers(ISwitchOperation switchStatemen var caseValue = IntegerUtilities.ToInt64(value.ConstantValue.Value); enumValues.Remove(caseValue); + break; + + case CaseKind.Pattern: + if (((IPatternCaseClauseOperation)clause).Pattern is IBinaryPatternOperation pattern) + { + PopulateSwitchExpressionHelpers.HandleBinaryPattern(pattern, enumValues); + } + break; } } diff --git a/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs index 8f0fb7a0a3c33..b9ad90458a74b 100644 --- a/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseObjectInitializer/UseNamedMemberInitializerAnalyzer.cs @@ -195,8 +195,8 @@ private bool ImplicitMemberAccessWouldBeAffected(SyntaxNode node) { foreach (var child in node.ChildNodesAndTokens()) { - if (child.IsNode && - ImplicitMemberAccessWouldBeAffected(child.AsNode()!)) + if (child.AsNode(out var childNode) && + ImplicitMemberAccessWouldBeAffected(childNode)) { return true; } diff --git a/src/Analyzers/Core/CodeFixes/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs index cbecadb7094d4..b64d63941b497 100644 --- a/src/Analyzers/Core/CodeFixes/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/MakeMethodSynchronous/AbstractMakeMethodSynchronousCodeFixProvider.cs @@ -177,18 +177,14 @@ private static async Task RemoveAwaitFromCallersAsync( var editor = new SyntaxEditor(root, currentSolution.Services); foreach (var location in group) - { - RemoveAwaitFromCallerIfPresent(editor, syntaxFactsService, root, location, cancellationToken); - } + RemoveAwaitFromCallerIfPresent(editor, syntaxFactsService, location, cancellationToken); var newRoot = editor.GetChangedRoot(); return currentSolution.WithDocumentSyntaxRoot(document.Id, newRoot); } private static void RemoveAwaitFromCallerIfPresent( - SyntaxEditor editor, ISyntaxFactsService syntaxFacts, - SyntaxNode root, ReferenceLocation referenceLocation, - CancellationToken cancellationToken) + SyntaxEditor editor, ISyntaxFactsService syntaxFacts, ReferenceLocation referenceLocation, CancellationToken cancellationToken) { if (referenceLocation.IsImplicit) { diff --git a/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs index c176e52e9c84b..b70f54298a2fd 100644 --- a/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/RemoveUnusedParametersAndValues/AbstractRemoveUnusedValuesCodeFixProvider.cs @@ -850,10 +850,10 @@ private async Task AdjustLocalDeclarationsAsync( // Run formatter prior to invoking IMoveDeclarationNearReferenceService. #if CODE_STYLE var provider = GetSyntaxFormatting(); - rootWithTrackedNodes = FormatterHelper.Format(rootWithTrackedNodes, originalDeclStatementsToMoveOrRemove.Select(s => s.Span), provider, options, rules: null, cancellationToken); + rootWithTrackedNodes = FormatterHelper.Format(rootWithTrackedNodes, originalDeclStatementsToMoveOrRemove.Select(s => s.Span), provider, options, rules: default, cancellationToken); #else var provider = document.Project.Solution.Services; - rootWithTrackedNodes = Formatter.Format(rootWithTrackedNodes, originalDeclStatementsToMoveOrRemove.Select(s => s.Span), provider, options, rules: null, cancellationToken); + rootWithTrackedNodes = Formatter.Format(rootWithTrackedNodes, originalDeclStatementsToMoveOrRemove.Select(s => s.Span), provider, options, rules: default, cancellationToken); #endif document = document.WithSyntaxRoot(rootWithTrackedNodes); diff --git a/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs index 5f39393f7b430..93ad981de4bc3 100644 --- a/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseConditionalExpression/AbstractUseConditionalExpressionCodeFixProvider.cs @@ -72,7 +72,7 @@ await FixOneAsync( // formatted to explicitly format things. Note: all we will format is the new // conditional expression as that's the only node that has the appropriate // annotation on it. - var rules = new List { GetMultiLineFormattingRule() }; + var rules = ImmutableArray.Create(GetMultiLineFormattingRule()); #if CODE_STYLE var provider = GetSyntaxFormatting(); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs index 48a9ac8a41427..ed092ad9a51e7 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder.ValueChecks.cs @@ -47,7 +47,7 @@ private readonly struct MixableDestination internal MixableDestination(ParameterSymbol parameter, BoundExpression argument) { - Debug.Assert(parameter.RefKind.IsWritableReference() && parameter.Type.IsRefLikeType); + Debug.Assert(parameter.RefKind.IsWritableReference() && parameter.Type.IsRefLikeOrAllowsRefLikeType()); Debug.Assert(GetParameterValEscapeLevel(parameter).HasValue); Argument = argument; Parameter = parameter; @@ -310,19 +310,8 @@ private static bool RequiresRefOrOut(BindValueKind kind) #nullable enable - /// - /// When an indexer is accessed with dynamic argument is resolved statically, - /// in some scenarios its result type is set to 'dynamic' type. - /// Assignments to such indexers should be bound statically as well, reverting back - /// to the indexer's type for the target and setting result type of the assignment to 'dynamic' type. - /// This flag and the assertion below help catch any new assignment scenarios and - /// make them aware of this subtlety. - /// The flag itself doesn't affect semantic analysis beyond the assertion. - /// - private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundIndexerAccess indexerAccess, BindValueKind valueKind, BindingDiagnosticBag diagnostics, bool dynamificationOfAssignmentResultIsHandled = false) + private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundIndexerAccess indexerAccess, BindValueKind valueKind, BindingDiagnosticBag diagnostics) { - Debug.Assert((valueKind & BindValueKind.Assignable) == 0 || (valueKind & BindValueKind.RefersToLocation) != 0 || dynamificationOfAssignmentResultIsHandled); - var useSetAccessor = valueKind == BindValueKind.Assignable && !indexerAccess.Indexer.ReturnsByRef; var accessorForDefaultArguments = useSetAccessor ? indexerAccess.Indexer.GetOwnOrInheritedSetMethod() @@ -415,26 +404,15 @@ private BoundIndexerAccess BindIndexerDefaultArgumentsAndParamsCollection(BoundI /// method returns a BoundBadExpression node. The method returns the original /// expression without generating any error if the expression has errors. /// - /// - /// When an indexer is accessed with dynamic argument is resolved statically, - /// in some scenarios its result type is set to 'dynamic' type. - /// Assignments to such indexers should be bound statically as well, reverting back - /// to the indexer's type for the target and setting result type of the assignment to 'dynamic' type. - /// This flag and the assertion below help catch any new assignment scenarios and - /// make them aware of this subtlety. - /// The flag itself doesn't affect semantic analysis beyond the assertion. - /// - private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind, BindingDiagnosticBag diagnostics, bool dynamificationOfAssignmentResultIsHandled = false) + private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind, BindingDiagnosticBag diagnostics) { - Debug.Assert((valueKind & BindValueKind.Assignable) == 0 || (valueKind & BindValueKind.RefersToLocation) != 0 || dynamificationOfAssignmentResultIsHandled); - switch (expr.Kind) { case BoundKind.PropertyGroup: expr = BindIndexedPropertyAccess((BoundPropertyGroup)expr, mustHaveAllOptionalParameters: false, diagnostics: diagnostics); if (expr is BoundIndexerAccess indexerAccess) { - expr = BindIndexerDefaultArgumentsAndParamsCollection(indexerAccess, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: dynamificationOfAssignmentResultIsHandled); + expr = BindIndexerDefaultArgumentsAndParamsCollection(indexerAccess, valueKind, diagnostics); } break; @@ -452,7 +430,7 @@ private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind return expr; case BoundKind.IndexerAccess: - expr = BindIndexerDefaultArgumentsAndParamsCollection((BoundIndexerAccess)expr, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: dynamificationOfAssignmentResultIsHandled); + expr = BindIndexerDefaultArgumentsAndParamsCollection((BoundIndexerAccess)expr, valueKind, diagnostics); break; case BoundKind.UnconvertedObjectCreationExpression: @@ -894,12 +872,24 @@ private static bool CheckNotNamespaceOrType(BoundExpression expr, BindingDiagnos } } - private bool CheckLocalValueKind(SyntaxNode node, BoundLocal local, BindValueKind valueKind, bool checkingReceiver, BindingDiagnosticBag diagnostics) + private void CheckAddressOfInAsyncOrIteratorMethod(SyntaxNode node, BindValueKind valueKind, BindingDiagnosticBag diagnostics) { - if (valueKind == BindValueKind.AddressOf && this.IsInAsyncMethod()) + if (valueKind == BindValueKind.AddressOf) { - Error(diagnostics, ErrorCode.WRN_AddressOfInAsync, node); + if (this.IsInAsyncMethod()) + { + Error(diagnostics, ErrorCode.WRN_AddressOfInAsync, node); + } + else if (this.IsDirectlyInIterator && Compilation.IsFeatureEnabled(MessageID.IDS_FeatureRefUnsafeInIteratorAsync)) + { + Error(diagnostics, ErrorCode.ERR_AddressOfInIterator, node); + } } + } + + private bool CheckLocalValueKind(SyntaxNode node, BoundLocal local, BindValueKind valueKind, bool checkingReceiver, BindingDiagnosticBag diagnostics) + { + CheckAddressOfInAsyncOrIteratorMethod(node, valueKind, diagnostics); // Local constants are never variables. Local variables are sometimes // not to be treated as variables, if they are fixed, declared in a using, @@ -990,10 +980,8 @@ internal partial class Binder private bool CheckParameterValueKind(SyntaxNode node, BoundParameter parameter, BindValueKind valueKind, bool checkingReceiver, BindingDiagnosticBag diagnostics) { Debug.Assert(!RequiresAssignableVariable(BindValueKind.AddressOf)); - if (valueKind == BindValueKind.AddressOf && this.IsInAsyncMethod()) - { - Error(diagnostics, ErrorCode.WRN_AddressOfInAsync, node); - } + + CheckAddressOfInAsyncOrIteratorMethod(node, valueKind, diagnostics); ParameterSymbol parameterSymbol = parameter.ParameterSymbol; @@ -1909,7 +1897,7 @@ bool isRefEscape } // check receiver if ref-like - if (receiver?.Type?.IsRefLikeType == true) + if (receiver?.Type?.IsRefLikeOrAllowsRefLikeType() == true) { escapeScope = Math.Max(escapeScope, GetValEscape(receiver, scopeOfTheContainingExpression)); } @@ -1952,7 +1940,9 @@ private uint GetInvocationEscapeWithUpdatedRules( // If `M()` does return ref-to-ref-struct, the *ref-safe-to-escape* is the narrowest *ref-safe-to-escape* contributed by all arguments which are ref-to-ref-struct. // if (!returnsRefToRefStruct - || (param is null or { RefKind: not RefKind.None, Type.IsRefLikeType: true } && isArgumentRefEscape == isRefEscape)) + || ((param is null || + (param is { RefKind: not RefKind.None, Type: { } type } && type.IsRefLikeOrAllowsRefLikeType())) && + isArgumentRefEscape == isRefEscape)) { uint argEscape = isArgumentRefEscape ? GetRefEscape(argument, scopeOfTheContainingExpression) : @@ -1981,7 +1971,9 @@ private static bool ReturnsRefToRefStruct(Symbol symbol) PropertySymbol p => p.GetMethod, _ => null }; - return method is { RefKind: not RefKind.None, ReturnType.IsRefLikeType: true }; + + return method is { RefKind: not RefKind.None, ReturnType: { } returnType } && + returnType.IsRefLikeOrAllowsRefLikeType(); } /// @@ -2076,7 +2068,7 @@ bool isRefEscape } // check receiver if ref-like - if (receiver?.Type?.IsRefLikeType == true) + if (receiver?.Type?.IsRefLikeOrAllowsRefLikeType() == true) { return CheckValEscape(receiver.Syntax, receiver, escapeFrom, escapeTo, false, diagnostics); } @@ -2122,7 +2114,9 @@ private bool CheckInvocationEscapeWithUpdatedRules( // If `M()` does return ref-to-ref-struct, the *ref-safe-to-escape* is the narrowest *ref-safe-to-escape* contributed by all arguments which are ref-to-ref-struct. // if (!returnsRefToRefStruct - || (param is null or { RefKind: not RefKind.None, Type.IsRefLikeType: true } && isArgumentRefEscape == isRefEscape)) + || ((param is null || + (param is { RefKind: not RefKind.None, Type: { } type } && type.IsRefLikeOrAllowsRefLikeType())) && + isArgumentRefEscape == isRefEscape)) { bool valid = isArgumentRefEscape ? CheckRefEscape(argument.Syntax, argument, escapeFrom, escapeTo, false, diagnostics) : @@ -2179,7 +2173,7 @@ private void GetInvocationArgumentsForEscape( Debug.Assert(receiverIsSubjectToCloning != ThreeState.Unknown); if (receiverIsSubjectToCloning == ThreeState.True) { - Debug.Assert(receiver is not BoundValuePlaceholderBase && method is not null && receiver.Type?.IsValueType == true); + Debug.Assert(receiver is not BoundValuePlaceholderBase && method is not null && receiver.Type?.IsReferenceType == false); #if DEBUG AssertVisited(receiver); #endif @@ -2244,7 +2238,7 @@ private void GetInvocationArgumentsForEscape( static bool isMixableParameter([NotNullWhen(true)] ParameterSymbol? parameter) => parameter is not null && - parameter.Type.IsRefLikeType && + parameter.Type.IsRefLikeOrAllowsRefLikeType() && parameter.RefKind.IsWritableReference(); static bool isMixableArgument(BoundExpression argument) @@ -2273,6 +2267,12 @@ static EscapeArgument getReceiver(MethodSymbol? method, BoundExpression receiver method.TryGetThisParameter(out thisParameter) && thisParameter is not null) { + if (receiver.Type is TypeParameterSymbol typeParameter) + { + // Pretend that the type of the parameter is the type parameter + thisParameter = new TypeParameterThisParameterSymbol(thisParameter, typeParameter); + } + refKind = thisParameter.RefKind; } @@ -2362,9 +2362,9 @@ static bool hasRefLikeReturn(Symbol symbol) return method.ContainingType.IsRefLikeType; } - return method.ReturnType.IsRefLikeType; + return method.ReturnType.IsRefLikeOrAllowsRefLikeType(); case PropertySymbol property: - return property.Type.IsRefLikeType; + return property.Type.IsRefLikeOrAllowsRefLikeType(); default: return false; } @@ -2424,7 +2424,7 @@ private void GetEscapeValuesForUpdatedRules( escapeValues.Add(new EscapeValue(parameter: null, argument, EscapeLevel.ReturnOnly, isRefEscape: true)); } - if (argument.Type?.IsRefLikeType == true) + if (argument.Type?.IsRefLikeOrAllowsRefLikeType() == true) { escapeValues.Add(new EscapeValue(parameter: null, argument, EscapeLevel.CallingMethod, isRefEscape: false)); } @@ -2432,7 +2432,7 @@ private void GetEscapeValuesForUpdatedRules( continue; } - if (parameter.Type.IsRefLikeType && parameter.RefKind != RefKind.Out && GetParameterValEscapeLevel(parameter) is { } valEscapeLevel) + if (parameter.Type.IsRefLikeOrAllowsRefLikeType() && parameter.RefKind != RefKind.Out && GetParameterValEscapeLevel(parameter) is { } valEscapeLevel) { escapeValues.Add(new EscapeValue(parameter, argument, valEscapeLevel, isRefEscape: false)); } @@ -2547,8 +2547,11 @@ private bool CheckInvocationArgMixing( // collect all writeable ref-like arguments, including receiver var receiverType = receiverOpt?.Type; - if (receiverType?.IsRefLikeType == true && !IsReceiverRefReadOnly(symbol)) + if (receiverType?.IsRefLikeOrAllowsRefLikeType() == true && !IsReceiverRefReadOnly(symbol)) { + // https://github.com/dotnet/roslyn/issues/73550: + // We do not have a test that demonstrates that the statement below makes a difference. + // If it is commented out, not a single test fails escapeTo = GetValEscape(receiverOpt, scopeOfTheContainingExpression); } @@ -2578,7 +2581,7 @@ private bool CheckInvocationArgMixing( if (refKind.IsWritableReference() && !argument.IsDiscardExpression() - && argument.Type?.IsRefLikeType == true) + && argument.Type?.IsRefLikeOrAllowsRefLikeType() == true) { escapeTo = Math.Min(escapeTo, GetValEscape(argument, scopeOfTheContainingExpression)); } @@ -2745,12 +2748,87 @@ private static bool AllParametersConsideredInEscapeAnalysisHaveArguments( } #endif -#nullable disable - private static ErrorCode GetStandardCallEscapeError(bool checkingReceiver) { return checkingReceiver ? ErrorCode.ERR_EscapeCall2 : ErrorCode.ERR_EscapeCall; } + + private sealed class TypeParameterThisParameterSymbol : ThisParameterSymbolBase + { + private readonly TypeParameterSymbol _type; + private readonly ParameterSymbol _underlyingParameter; + + internal TypeParameterThisParameterSymbol(ParameterSymbol underlyingParameter, TypeParameterSymbol type) + { + Debug.Assert(underlyingParameter.IsThis); + Debug.Assert(underlyingParameter.RefKind != RefKind.Out); // Shouldn't get here for a constructor + Debug.Assert(underlyingParameter.ContainingSymbol is MethodSymbol); + + _underlyingParameter = underlyingParameter; + _type = type; + } + + public override TypeWithAnnotations TypeWithAnnotations + => TypeWithAnnotations.Create(_type, NullableAnnotation.NotAnnotated); + + public override RefKind RefKind + { + get + { + if (_underlyingParameter.RefKind is not RefKind.None and var underlyingRefKind) + { + return underlyingRefKind; + } + + if (!_underlyingParameter.ContainingType.IsInterface || _type.IsReferenceType) + { + return RefKind.None; + } + + // Receiver of an interface method could possibly be a structure. + // Let's treat it as by ref parameter for the purpose of ref safety analysis. + return RefKind.Ref; + } + } + + public override ImmutableArray Locations + { + get { return _underlyingParameter.Locations; } + } + + public override Symbol ContainingSymbol + { + get { return _underlyingParameter.ContainingSymbol; } + } + + internal override ScopedKind EffectiveScope + { + get + { + if (HasUnscopedRefAttribute) + { + return ScopedKind.None; + } + + if (!_underlyingParameter.ContainingType.IsInterface || _type.IsReferenceType) + { + return ScopedKind.None; + } + + // Receiver of an interface method could possibly be a structure. + // Let's treat it as scoped ref by ref parameter for the purpose of ref safety analysis. + return ScopedKind.ScopedRef; + } + } + + internal override bool HasUnscopedRefAttribute + => _underlyingParameter.HasUnscopedRefAttribute; + + internal sealed override bool UseUpdatedEscapeRules + => _underlyingParameter.UseUpdatedEscapeRules; + } + +#nullable disable } internal partial class Binder @@ -3730,7 +3808,7 @@ internal uint GetValEscape(BoundExpression expr, uint scopeOfTheContainingExpres } // to have local-referring values an expression must have a ref-like type - if (expr.Type?.IsRefLikeType != true) + if (expr.Type?.IsRefLikeOrAllowsRefLikeType() != true) { return CallingMethodScope; } @@ -3949,27 +4027,44 @@ internal uint GetValEscape(BoundExpression expr, uint scopeOfTheContainingExpres isRefEscape: false); case BoundKind.ObjectCreationExpression: - var objectCreation = (BoundObjectCreationExpression)expr; - var constructorSymbol = objectCreation.Constructor; + { + var objectCreation = (BoundObjectCreationExpression)expr; + var constructorSymbol = objectCreation.Constructor; - var escape = GetInvocationEscapeScope( - constructorSymbol, - receiver: null, - receiverIsSubjectToCloning: ThreeState.Unknown, - constructorSymbol.Parameters, - objectCreation.Arguments, - objectCreation.ArgumentRefKindsOpt, - objectCreation.ArgsToParamsOpt, - scopeOfTheContainingExpression, - isRefEscape: false); + var escape = GetInvocationEscapeScope( + constructorSymbol, + receiver: null, + receiverIsSubjectToCloning: ThreeState.Unknown, + constructorSymbol.Parameters, + objectCreation.Arguments, + objectCreation.ArgumentRefKindsOpt, + objectCreation.ArgsToParamsOpt, + scopeOfTheContainingExpression, + isRefEscape: false); - var initializerOpt = objectCreation.InitializerExpressionOpt; - if (initializerOpt != null) - { - escape = Math.Max(escape, GetValEscape(initializerOpt, scopeOfTheContainingExpression)); + var initializerOpt = objectCreation.InitializerExpressionOpt; + if (initializerOpt != null) + { + escape = Math.Max(escape, GetValEscape(initializerOpt, scopeOfTheContainingExpression)); + } + + return escape; } - return escape; + case BoundKind.NewT: + { + var newT = (BoundNewT)expr; + // By default it is safe to escape + var escape = CallingMethodScope; + + var initializerOpt = newT.InitializerExpressionOpt; + if (initializerOpt != null) + { + escape = Math.Max(escape, GetValEscape(initializerOpt, scopeOfTheContainingExpression)); + } + + return escape; + } case BoundKind.WithExpression: var withExpression = (BoundWithExpression)expr; @@ -4049,8 +4144,15 @@ internal uint GetValEscape(BoundExpression expr, uint scopeOfTheContainingExpres return GetValEscape(conversion.Operand, scopeOfTheContainingExpression); case BoundKind.AssignmentOperator: + // https://github.com/dotnet/roslyn/issues/73549: + // We do not have a test that demonstrates that the statement below makes a difference. + // If 'scopeOfTheContainingExpression' is always returned, not a single test fails. + // Same for the 'case BoundKind.NullCoalescingAssignmentOperator:' below. return GetValEscape(((BoundAssignmentOperator)expr).Right, scopeOfTheContainingExpression); + case BoundKind.NullCoalescingAssignmentOperator: + return GetValEscape(((BoundNullCoalescingAssignmentOperator)expr).RightOperand, scopeOfTheContainingExpression); + case BoundKind.IncrementOperator: return GetValEscape(((BoundIncrementOperator)expr).Operand, scopeOfTheContainingExpression); @@ -4312,7 +4414,7 @@ internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeF } // to have local-referring values an expression must have a ref-like type - if (expr.Type?.IsRefLikeType != true) + if (expr.Type?.IsRefLikeOrAllowsRefLikeType() != true) { return true; } @@ -4615,6 +4717,27 @@ internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeF return escape; } + case BoundKind.NewT: + { + var newT = (BoundNewT)expr; + var escape = true; + + var initializerExpr = newT.InitializerExpressionOpt; + if (initializerExpr != null) + { + escape = escape && + CheckValEscape( + initializerExpr.Syntax, + initializerExpr, + escapeFrom, + escapeTo, + checkingReceiver: false, + diagnostics: diagnostics); + } + + return escape; + } + case BoundKind.WithExpression: { var withExpr = (BoundWithExpression)expr; @@ -4720,6 +4843,10 @@ internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeF var assignment = (BoundAssignmentOperator)expr; return CheckValEscape(node, assignment.Left, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics); + case BoundKind.NullCoalescingAssignmentOperator: + var nullCoalescingAssignment = (BoundNullCoalescingAssignmentOperator)expr; + return CheckValEscape(node, nullCoalescingAssignment.LeftOperand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics); + case BoundKind.IncrementOperator: var increment = (BoundIncrementOperator)expr; return CheckValEscape(node, increment.Operand, escapeFrom, escapeTo, checkingReceiver: false, diagnostics: diagnostics); @@ -4840,6 +4967,7 @@ internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeF case BoundKind.AsOperator: case BoundKind.AwaitExpression: case BoundKind.ConditionalAccess: + case BoundKind.ConditionalReceiver: case BoundKind.ArrayAccess: // only possible in error cases (if possible at all) return false; @@ -4874,7 +5002,6 @@ internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeF // case BoundKind.SizeOfOperator: // case BoundKind.DynamicMemberAccess: // case BoundKind.DynamicInvocation: - // case BoundKind.NewT: // case BoundKind.DelegateCreationExpression: // case BoundKind.ArrayCreation: // case BoundKind.AnonymousObjectCreationExpression: @@ -4974,7 +5101,6 @@ internal bool CheckValEscape(SyntaxNode node, BoundExpression expr, uint escapeF // case BoundKind.SequencePointExpression: // case BoundKind.SequencePointWithSpan: // case BoundKind.StateMachineScope: - // case BoundKind.ConditionalReceiver: // case BoundKind.ComplexConditionalReceiver: // case BoundKind.PreviousSubmissionReference: // case BoundKind.HostObjectMemberReference: diff --git a/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs b/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs index 39e48112f4f15..86c3bbd550cf6 100644 --- a/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs +++ b/src/Compilers/CSharp/Portable/Binder/BinderFactory.BinderFactoryVisitor.cs @@ -171,6 +171,7 @@ public override Binder VisitMethodDeclaration(MethodDeclarationSyntax methodDecl } SourceMemberMethodSymbol method = null; + bool isIteratorBody = false; if (usage != NodeUsage.Normal && methodDecl.TypeParameterList != null) { @@ -181,10 +182,11 @@ public override Binder VisitMethodDeclaration(MethodDeclarationSyntax methodDecl if (usage == NodeUsage.MethodBody) { method = method ?? GetMethodSymbol(methodDecl, resultBinder); + isIteratorBody = method.IsIterator; resultBinder = new InMethodBinder(method, resultBinder); } - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(methodDecl.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(methodDecl.Modifiers, isIteratorBody: isIteratorBody); binderCache.TryAdd(key, resultBinder); } @@ -222,7 +224,7 @@ public override Binder VisitConstructorDeclaration(ConstructorDeclarationSyntax } } - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); binderCache.TryAdd(key, resultBinder); } @@ -249,7 +251,7 @@ public override Binder VisitDestructorDeclaration(DestructorDeclarationSyntax pa SourceMemberMethodSymbol method = GetMethodSymbol(parent, resultBinder); resultBinder = new InMethodBinder(method, resultBinder); - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); binderCache.TryAdd(key, resultBinder); } @@ -311,6 +313,10 @@ public override Binder VisitAccessorDeclaration(AccessorDeclarationSyntax parent if ((object)accessor != null) { resultBinder = new InMethodBinder(accessor, resultBinder); + + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary( + modifiers: default, + isIteratorBody: accessor.IsIterator); } } @@ -338,12 +344,14 @@ private Binder VisitOperatorOrConversionDeclaration(BaseMethodDeclarationSyntax resultBinder = VisitCore(parent.Parent); MethodSymbol method = GetMethodSymbol(parent, resultBinder); + bool isIteratorBody = false; if ((object)method != null && inBody) { + isIteratorBody = method.IsIterator; resultBinder = new InMethodBinder(method, resultBinder); } - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(parent.Modifiers, isIteratorBody: isIteratorBody); binderCache.TryAdd(key, resultBinder); } @@ -363,24 +371,24 @@ public override Binder VisitConversionOperatorDeclaration(ConversionOperatorDecl public override Binder VisitFieldDeclaration(FieldDeclarationSyntax parent) { - return VisitCore(parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers); + return VisitCore(parent.Parent).SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); } public override Binder VisitEventDeclaration(EventDeclarationSyntax parent) { - return VisitCore(parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers); + return VisitCore(parent.Parent).SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); } public override Binder VisitEventFieldDeclaration(EventFieldDeclarationSyntax parent) { - return VisitCore(parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers); + return VisitCore(parent.Parent).SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); } public override Binder VisitPropertyDeclaration(PropertyDeclarationSyntax parent) { if (!LookupPosition.IsInBody(_position, parent)) { - return VisitCore(parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers); + return VisitCore(parent.Parent).SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); } return VisitPropertyOrIndexerExpressionBody(parent); @@ -390,7 +398,7 @@ public override Binder VisitIndexerDeclaration(IndexerDeclarationSyntax parent) { if (!LookupPosition.IsInBody(_position, parent)) { - return VisitCore(parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers); + return VisitCore(parent.Parent).SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); } return VisitPropertyOrIndexerExpressionBody(parent); @@ -403,12 +411,16 @@ private Binder VisitPropertyOrIndexerExpressionBody(BasePropertyDeclarationSynta Binder resultBinder; if (!binderCache.TryGetValue(key, out resultBinder)) { - resultBinder = VisitCore(parent.Parent).WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = VisitCore(parent.Parent).SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); var propertySymbol = GetPropertySymbol(parent, resultBinder); var accessor = propertySymbol.GetMethod; if ((object)accessor != null) { + // Expression body cannot be an iterator, otherwise we would need to pass + // `isIteratorBody` to `SetOrClearUnsafeRegionIfNecessary` above. + Debug.Assert(!accessor.IsIterator); + resultBinder = new InMethodBinder(accessor, resultBinder); } @@ -663,7 +675,7 @@ public override Binder VisitDelegateDeclaration(DelegateDeclarationSyntax parent resultBinder = new WithClassTypeParametersBinder(container, resultBinder); } - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); binderCache.TryAdd(key, resultBinder); } @@ -691,7 +703,7 @@ public override Binder VisitEnumDeclaration(EnumDeclarationSyntax parent) resultBinder = new InContainerBinder(container, outer); - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); binderCache.TryAdd(key, resultBinder); } @@ -773,7 +785,7 @@ internal Binder VisitTypeDeclarationCore(TypeDeclarationSyntax parent, NodeUsage } } - resultBinder = resultBinder.WithUnsafeRegionIfNecessary(parent.Modifiers); + resultBinder = resultBinder.SetOrClearUnsafeRegionIfNecessary(parent.Modifiers); binderCache.TryAdd(key, resultBinder); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs index 760478b534c1e..ea5066c8bb2b6 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Constraints.cs @@ -205,7 +205,7 @@ internal ImmutableArray BindTypeParameterConstrai diagnostics.Add(ErrorCode.ERR_NewBoundWithUnmanaged, syntax.GetFirstToken().GetLocation()); } - if (i != n - 1) + if (i != n - 1 && constraintsSyntax[i + 1].Kind() != SyntaxKind.AllowsConstraintClause) { diagnostics.Add(ErrorCode.ERR_NewBoundMustBeLast, syntax.GetFirstToken().GetLocation()); } @@ -290,6 +290,47 @@ internal ImmutableArray BindTypeParameterConstrai syntaxBuilder!.Add(typeConstraintSyntax); } continue; + + case SyntaxKind.AllowsConstraintClause: + + if (isForOverride) + { + reportOverrideWithConstraints(ref reportedOverrideWithConstraints, syntax, diagnostics); + continue; + } + + if (i != n - 1) + { + diagnostics.Add(ErrorCode.ERR_AllowsClauseMustBeLast, syntax.GetFirstToken().GetLocation()); + } + + bool hasRefStructConstraint = false; + + foreach (var allowsConstraint in ((AllowsConstraintClauseSyntax)syntax).Constraints) + { + if (allowsConstraint.Kind() == SyntaxKind.RefStructConstraint) + { + if (hasRefStructConstraint) + { + diagnostics.Add(ErrorCode.ERR_RefStructConstraintAlreadySpecified, allowsConstraint); + } + else + { + CheckFeatureAvailability(allowsConstraint, MessageID.IDS_FeatureRefStructInterfaces, diagnostics); + + if (!Compilation.Assembly.RuntimeSupportsByRefLikeGenerics) + { + Error(diagnostics, ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, allowsConstraint); + } + + constraints |= TypeParameterConstraintKind.AllowByRefLike; + hasRefStructConstraint = true; + } + } + } + + continue; + default: throw ExceptionUtilities.UnexpectedValue(syntax.Kind()); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs index 3c0a19894139f..6f24e552a0ed7 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Conversions.cs @@ -454,15 +454,13 @@ void checkConstraintLanguageVersionAndRuntimeSupportForConversion(SyntaxNode syn diagnostics.ReportUseSite(elementField, syntax); - Symbol? unsafeAsMethod = null; - if (destination.OriginalDefinition.Equals(Compilation.GetWellKnownType(WellKnownType.System_ReadOnlySpan_T), TypeCompareKind.AllIgnoreOptions)) { if (CheckValueKind(syntax, source, BindValueKind.RefersToLocation, checkingReceiver: false, BindingDiagnosticBag.Discarded)) { _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_InteropServices_MemoryMarshal__CreateReadOnlySpan, diagnostics, syntax: syntax); // This also takes care of an 'int' type _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__AsRef_T, diagnostics, syntax: syntax); - unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax); + _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax); } else { @@ -476,7 +474,7 @@ void checkConstraintLanguageVersionAndRuntimeSupportForConversion(SyntaxNode syn if (CheckValueKind(syntax, source, BindValueKind.RefersToLocation | BindValueKind.Assignable, checkingReceiver: false, BindingDiagnosticBag.Discarded)) { _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_InteropServices_MemoryMarshal__CreateSpan, diagnostics, syntax: syntax); // This also takes care of an 'int' type - unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax); + _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: syntax); } else { @@ -484,15 +482,23 @@ void checkConstraintLanguageVersionAndRuntimeSupportForConversion(SyntaxNode syn } } - if (unsafeAsMethod is MethodSymbol { HasUnsupportedMetadata: false } method) - { - method.Construct(ImmutableArray.Create(TypeWithAnnotations.Create(source.Type), elementField.TypeWithAnnotations)). - CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, syntax.GetLocation(), diagnostics)); - } + CheckInlineArrayTypeIsSupported(syntax, source.Type, elementField.Type, diagnostics); } } } + private static void CheckInlineArrayTypeIsSupported(SyntaxNode syntax, TypeSymbol inlineArrayType, TypeSymbol elementType, BindingDiagnosticBag diagnostics) + { + if (elementType.IsPointerOrFunctionPointer() || elementType.IsRestrictedType()) + { + Error(diagnostics, ErrorCode.ERR_BadTypeArgument, syntax, elementType); + } + else if (inlineArrayType.IsRestrictedType()) + { + Error(diagnostics, ErrorCode.ERR_BadTypeArgument, syntax, inlineArrayType); + } + } + private static BoundExpression ConvertObjectCreationExpression( SyntaxNode syntax, BoundUnconvertedObjectCreationExpression node, Conversion conversion, bool isCast, TypeSymbol destination, ConversionGroup? conversionGroupOpt, bool wasCompilerGenerated, BindingDiagnosticBag diagnostics) @@ -1118,16 +1124,8 @@ static bool bindMethodGroupInvocation( addMethods = []; result = false; } - else if (finalApplicableCandidates.Length == 1 && - tryEarlyBindSingleCandidateInvocationWithDynamicArgument(addMethodBinder, syntax, expression, methodGroup, diagnostics, resolution, finalApplicableCandidates[0], out var addMethod) is bool earlyBoundResult) - { - addMethods = addMethod is null ? [] : [addMethod]; - result = earlyBoundResult; - } else { - Debug.Assert(finalApplicableCandidates.Length > 0); - addMethods = filterOutBadGenericMethods(addMethodBinder, syntax, methodGroup, analyzedArguments, resolution, finalApplicableCandidates, ref useSiteInfo); result = !addMethods.IsEmpty; @@ -1135,6 +1133,11 @@ static bool bindMethodGroupInvocation( { diagnostics.Add(ErrorCode.ERR_CollectionExpressionMissingAdd, syntax, methodGroup.ReceiverOpt.Type); } + else if (addMethods.Length == 1) + { + addMethodBinder.ReportDiagnosticsIfObsolete(diagnostics, addMethods[0], syntax, hasBaseReceiver: false); + ReportDiagnosticsIfUnmanagedCallersOnly(diagnostics, addMethods[0], syntax, isDelegateConversion: false); + } } } else @@ -1259,67 +1262,6 @@ static ImmutableArray filterOutBadGenericMethods( return resultBuilder.ToImmutableAndFree(); } - // This is what CanEarlyBindSingleCandidateInvocationWithDynamicArgument is doing in terms of reporting diagnostics and detecting a failure - static bool canEarlyBindSingleCandidateInvocationWithDynamicArgument( - Binder addMethodBinder, - SyntaxNode syntax, - BoundMethodGroup boundMethodGroup, - BindingDiagnosticBag diagnostics, - MethodGroupResolution resolution, - MemberResolutionResult methodResolutionResult, - MethodSymbol singleCandidate) - { - Debug.Assert(boundMethodGroup.TypeArgumentsOpt.IsDefaultOrEmpty); - - if (singleCandidate.IsGenericMethod) - { - return false; - } - - if (addMethodBinder.IsAmbiguousDynamicParamsArgument(resolution.AnalyzedArguments.Arguments, methodResolutionResult, out SyntaxNode argumentSyntax)) - { - return false; - } - - return true; - } - - // This is what TryEarlyBindSingleCandidateInvocationWithDynamicArgument is doing in terms of reporting diagnostics and detecting a failure - static bool? tryEarlyBindSingleCandidateInvocationWithDynamicArgument( - Binder addMethodBinder, - SyntaxNode syntax, - SyntaxNode expression, - BoundMethodGroup boundMethodGroup, - BindingDiagnosticBag diagnostics, - MethodGroupResolution resolution, - MemberResolutionResult methodResolutionResult, - out MethodSymbol? addMethod) - { - MethodSymbol singleCandidate = methodResolutionResult.LeastOverriddenMember; - if (!canEarlyBindSingleCandidateInvocationWithDynamicArgument(addMethodBinder, syntax, boundMethodGroup, diagnostics, resolution, methodResolutionResult, singleCandidate)) - { - addMethod = null; - return null; - } - - var resultWithSingleCandidate = OverloadResolutionResult.GetInstance(); - resultWithSingleCandidate.ResultsBuilder.Add(methodResolutionResult); - - bool result = bindInvocationExpressionContinued( - addMethodBinder, - node: syntax, - expression: expression, - result: resultWithSingleCandidate, - analyzedArguments: resolution.AnalyzedArguments, - methodGroup: resolution.MethodGroup, - diagnostics: diagnostics, - out addMethod); - - resultWithSingleCandidate.Free(); - - return result; - } - // This is what BindInvocationExpressionContinued is doing in terms of reporting diagnostics and detecting a failure static bool bindInvocationExpressionContinued( Binder addMethodBinder, diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs index 9f8e70e818d03..5341638741f87 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs @@ -128,7 +128,7 @@ private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment( var type = boundRHS.Type ?? voidType; return new BoundDeconstructionAssignmentOperator( node, - DeconstructionVariablesAsTuple(left, checkedVariables, assignmentResultTupleType: out _, diagnostics, ignoreDiagnosticsFromTuple: true), + DeconstructionVariablesAsTuple(left, checkedVariables, diagnostics, ignoreDiagnosticsFromTuple: true), new BoundConversion(boundRHS.Syntax, boundRHS, Conversion.Deconstruction, @checked: false, explicitCastInCode: false, conversionGroupOpt: null, constantValueOpt: null, type: type, hasErrors: true), resultIsUsed, @@ -154,9 +154,9 @@ private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment( FailRemainingInferences(checkedVariables, diagnostics); - var lhsTuple = DeconstructionVariablesAsTuple(left, checkedVariables, out NamedTypeSymbol returnType, diagnostics, ignoreDiagnosticsFromTuple: diagnostics.HasAnyErrors() || !resultIsUsed); + var lhsTuple = DeconstructionVariablesAsTuple(left, checkedVariables, diagnostics, ignoreDiagnosticsFromTuple: diagnostics.HasAnyErrors() || !resultIsUsed); Debug.Assert(hasErrors || lhsTuple.Type is object); - returnType = hasErrors ? CreateErrorType() : returnType; + TypeSymbol returnType = hasErrors ? CreateErrorType() : lhsTuple.Type!; var boundConversion = new BoundConversion( boundRHS.Syntax, @@ -316,8 +316,8 @@ private bool MakeDeconstructionConversion( } else { - Debug.Assert(variable.Single is object); - var single = AdjustAssignmentTargetForDynamic(variable.Single, forceDynamicResult: out _); + var single = variable.Single; + Debug.Assert(single is object); Debug.Assert(single.Type is not null); CompoundUseSiteInfo useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); nestedConversion = this.Conversions.ClassifyConversionFromType(tupleOrDeconstructedTypes[i], single.Type, isChecked: CheckOverflowAtRuntime, ref useSiteInfo); @@ -502,7 +502,7 @@ private string GetDebuggerDisplay() if ((object?)variable.Single.Type != null) { // typed-variable on the left - mergedType = AdjustAssignmentTargetForDynamic(variable.Single, forceDynamicResult: out _).Type; + mergedType = variable.Single.Type; } } } @@ -542,14 +542,11 @@ private string GetDebuggerDisplay() syntax: syntax); } - private BoundTupleExpression DeconstructionVariablesAsTuple( - CSharpSyntaxNode syntax, ArrayBuilder variables, - out NamedTypeSymbol assignmentResultTupleType, + private BoundTupleExpression DeconstructionVariablesAsTuple(CSharpSyntaxNode syntax, ArrayBuilder variables, BindingDiagnosticBag diagnostics, bool ignoreDiagnosticsFromTuple) { int count = variables.Count; var valuesBuilder = ArrayBuilder.GetInstance(count); - var resultTypesWithAnnotationsBuilder = ArrayBuilder.GetInstance(count); var typesWithAnnotationsBuilder = ArrayBuilder.GetInstance(count); var locationsBuilder = ArrayBuilder.GetInstance(count); var namesBuilder = ArrayBuilder.GetInstance(count); @@ -557,24 +554,18 @@ private BoundTupleExpression DeconstructionVariablesAsTuple( foreach (var variable in variables) { BoundExpression value; - TypeSymbol resultType; if (variable.NestedVariables is object) { - value = DeconstructionVariablesAsTuple(variable.Syntax, variable.NestedVariables, out NamedTypeSymbol nestedResultType, diagnostics, ignoreDiagnosticsFromTuple); - resultType = nestedResultType; + value = DeconstructionVariablesAsTuple(variable.Syntax, variable.NestedVariables, diagnostics, ignoreDiagnosticsFromTuple); namesBuilder.Add(null); } else { Debug.Assert(variable.Single is object); value = variable.Single; - Debug.Assert(value.Type is not null); - resultType = value.Type; - value = AdjustAssignmentTargetForDynamic(value, forceDynamicResult: out _); namesBuilder.Add(ExtractDeconstructResultElementName(value)); } valuesBuilder.Add(value); - resultTypesWithAnnotationsBuilder.Add(TypeWithAnnotations.Create(resultType)); typesWithAnnotationsBuilder.Add(TypeWithAnnotations.Create(value.Type)); locationsBuilder.Add(variable.Syntax.Location); } @@ -588,39 +579,14 @@ private BoundTupleExpression DeconstructionVariablesAsTuple( ImmutableArray inferredPositions = tupleNames.IsDefault ? default : tupleNames.SelectAsArray(n => n != null); bool disallowInferredNames = this.Compilation.LanguageVersion.DisallowInferredTupleElementNames(); - ImmutableArray elementLocations = locationsBuilder.ToImmutableAndFree(); - var createTupleDiagnostics = ignoreDiagnosticsFromTuple ? null : BindingDiagnosticBag.GetInstance(diagnostics); - var type = NamedTypeSymbol.CreateTuple( syntax.Location, - typesWithAnnotationsBuilder.ToImmutableAndFree(), elementLocations, - tupleNames, this.Compilation, - shouldCheckConstraints: createTupleDiagnostics is not null, - includeNullability: false, - errorPositions: disallowInferredNames ? inferredPositions : default, - syntax: syntax, diagnostics: createTupleDiagnostics); - - if (createTupleDiagnostics is { AccumulatesDiagnostics: true, DiagnosticBag: { } bag } && - bag.HasAnyResolvedErrors()) - { - diagnostics.AddRangeAndFree(createTupleDiagnostics); - createTupleDiagnostics = null; // Suppress possibly duplicate errors from CreateTuple call below. - } - - // This type is the same as the 'type' above, or differs only by using 'dynamic' for some elements. - assignmentResultTupleType = NamedTypeSymbol.CreateTuple( - syntax.Location, - resultTypesWithAnnotationsBuilder.ToImmutableAndFree(), elementLocations, + typesWithAnnotationsBuilder.ToImmutableAndFree(), locationsBuilder.ToImmutableAndFree(), tupleNames, this.Compilation, - shouldCheckConstraints: createTupleDiagnostics is not null, + shouldCheckConstraints: !ignoreDiagnosticsFromTuple, includeNullability: false, errorPositions: disallowInferredNames ? inferredPositions : default, - syntax: syntax, diagnostics: createTupleDiagnostics); - - if (createTupleDiagnostics is not null) - { - diagnostics.AddRangeAndFree(createTupleDiagnostics); - } + syntax: syntax, diagnostics: ignoreDiagnosticsFromTuple ? null : diagnostics); return (BoundTupleExpression)BindToNaturalType(new BoundTupleLiteral(syntax, arguments, tupleNames, inferredPositions, type), diagnostics); } @@ -822,17 +788,12 @@ private DeconstructionVariable BindDeconstructionVariables( } default: var boundVariable = BindExpression(node, diagnostics, invoked: false, indexed: false); - var checkedVariable = CheckValue(boundVariable, BindValueKind.Assignable, diagnostics, dynamificationOfAssignmentResultIsHandled: true); - + var checkedVariable = CheckValue(boundVariable, BindValueKind.Assignable, diagnostics); if (expression == null && checkedVariable.Kind != BoundKind.DiscardExpression) { expression = node; } - // This object doesn't escape BindDeconstruction method, we don't call AdjustAssignmentTargetForDynamic - // for checkedVariable here, instead we call it where binder accesses DeconstructionVariable.Single - // In some of the places we need to be able to detect the fact that the type used to be dynamic, and, - // if we erase the fact here, there will be no other place for us to look at. return new DeconstructionVariable(checkedVariable, node); } } @@ -933,7 +894,7 @@ private BoundExpression BindDeconstructionVariable( } if (declTypeWithAnnotations.HasType && - localSymbol.Scope == ScopedKind.ScopedValue && !declTypeWithAnnotations.Type.IsErrorTypeOrRefLikeType()) + localSymbol.Scope == ScopedKind.ScopedValue && !declTypeWithAnnotations.Type.IsErrorOrRefLikeOrAllowsRefLikeType()) { diagnostics.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly, typeSyntax.Location); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index dd1e7e83bc1e8..fbd07fc353ef3 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -233,10 +233,10 @@ internal NamedTypeSymbol CreateErrorType(string name = "") /// did not meet the requirements, the return value will be a that /// (typically) wraps the subexpression. /// - internal BoundExpression BindValue(ExpressionSyntax node, BindingDiagnosticBag diagnostics, BindValueKind valueKind, bool dynamificationOfAssignmentResultIsHandled = false) + internal BoundExpression BindValue(ExpressionSyntax node, BindingDiagnosticBag diagnostics, BindValueKind valueKind) { var result = this.BindExpression(node, diagnostics: diagnostics, invoked: false, indexed: false); - return CheckValue(result, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled); + return CheckValue(result, valueKind, diagnostics); } internal BoundExpression BindRValueWithoutTargetType(ExpressionSyntax node, BindingDiagnosticBag diagnostics, bool reportNoTargetType = true) @@ -2046,7 +2046,7 @@ private BoundExpression BindNonMethod(SimpleNameSyntax node, Symbol symbol, Bind } else { - Debug.Assert(parameter.Type.IsRefLikeType); + Debug.Assert(parameter.Type.IsRefLikeOrAllowsRefLikeType()); Error(diagnostics, ErrorCode.ERR_AnonDelegateCantUseRefLike, node, parameter.Name); } } @@ -2069,7 +2069,7 @@ private BoundExpression BindNonMethod(SimpleNameSyntax node, Symbol symbol, Bind } else { - Debug.Assert(parameter.Type.IsRefLikeType); + Debug.Assert(parameter.Type.IsRefLikeOrAllowsRefLikeType()); Error(diagnostics, ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefLike, node, parameter.Name); } } @@ -3126,7 +3126,7 @@ private BoundExpression BindOutVariableDeclarationArgument( CheckRestrictedTypeInAsyncMethod(this.ContainingMemberOrLambda, declType.Type, diagnostics, typeSyntax); - if (localSymbol.Scope == ScopedKind.ScopedValue && !declType.Type.IsErrorTypeOrRefLikeType()) + if (localSymbol.Scope == ScopedKind.ScopedValue && !declType.Type.IsErrorOrRefLikeOrAllowsRefLikeType()) { diagnostics.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly, typeSyntax.Location); } @@ -3182,21 +3182,13 @@ private BoundExpression BindOutVariableDeclarationArgument( /// /// Reports an error when a bad special by-ref local was found. /// - internal static void CheckRestrictedTypeInAsyncMethod(Symbol containingSymbol, TypeSymbol type, BindingDiagnosticBag diagnostics, SyntaxNode syntax, ErrorCode errorCode = ErrorCode.ERR_BadSpecialByRefLocal) + internal static void CheckRestrictedTypeInAsyncMethod(Symbol containingSymbol, TypeSymbol type, BindingDiagnosticBag diagnostics, SyntaxNode syntax) { - Debug.Assert(errorCode is ErrorCode.ERR_BadSpecialByRefLocal or ErrorCode.ERR_BadSpecialByRefUsing or ErrorCode.ERR_BadSpecialByRefLock); if (containingSymbol.Kind == SymbolKind.Method && ((MethodSymbol)containingSymbol).IsAsync && type.IsRestrictedType()) { - if (errorCode == ErrorCode.ERR_BadSpecialByRefLock) - { - Error(diagnostics, errorCode, syntax); - } - else - { - Error(diagnostics, errorCode, syntax, type); - } + CheckFeatureAvailability(syntax, MessageID.IDS_FeatureRefUnsafeInIteratorAsync, diagnostics); } } @@ -5703,7 +5695,7 @@ private BoundExpression BindObjectInitializerMember( { // D = { ..., = , ... }, where D : dynamic boundMember = new BoundDynamicObjectInitializerMember(leftSyntax, memberName.Identifier.Text, implicitReceiver.Type, initializerType, hasErrors: false); - return CheckValue(boundMember, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: true); + return CheckValue(boundMember, valueKind, diagnostics); } else { @@ -5806,15 +5798,7 @@ private BoundExpression BindObjectInitializerMember( case BoundKind.IndexerAccess: { - var indexer = BindIndexerDefaultArgumentsAndParamsCollection((BoundIndexerAccess)boundMember, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: true); - - Debug.Assert(valueKind is BindValueKind.RValue or BindValueKind.RefAssignable or BindValueKind.Assignable); - - if (valueKind == BindValueKind.Assignable) - { - indexer = (BoundIndexerAccess)AdjustAssignmentTargetForDynamic(indexer, forceDynamicResult: out _); - } - + var indexer = BindIndexerDefaultArgumentsAndParamsCollection((BoundIndexerAccess)boundMember, valueKind, diagnostics); boundMember = indexer; hasErrors |= isRhsNestedInitializer && !CheckNestedObjectInitializerPropertySymbol(indexer.Indexer, leftSyntax, diagnostics, hasErrors, ref resultKind); arguments = indexer.Arguments; @@ -5854,10 +5838,7 @@ private BoundExpression BindObjectInitializerMember( hasErrors |= !CheckNestedObjectInitializerPropertySymbol(property, leftSyntax, diagnostics, hasErrors, ref resultKind); } - Debug.Assert(boundMember is not BoundIndexerAccess); - return hasErrors ? - boundMember : - CheckValue(boundMember, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: true); + return hasErrors ? boundMember : CheckValue(boundMember, valueKind, diagnostics); case BoundKind.DynamicObjectInitializerMember: break; @@ -5874,8 +5855,7 @@ private BoundExpression BindObjectInitializerMember( case BoundKind.ArrayAccess: case BoundKind.PointerElementAccess: - Debug.Assert(boundMember is not BoundIndexerAccess); - return CheckValue(boundMember, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: true); + return CheckValue(boundMember, valueKind, diagnostics); default: return BadObjectInitializerMemberAccess(boundMember, implicitReceiver, leftSyntax, diagnostics, valueKind, hasErrors); @@ -5960,8 +5940,7 @@ private BoundExpression BadObjectInitializerMemberAccess( break; case LookupResultKind.Inaccessible: - Debug.Assert(boundMember is not BoundIndexerAccess); - boundMember = CheckValue(boundMember, valueKind, diagnostics, dynamificationOfAssignmentResultIsHandled: true); + boundMember = CheckValue(boundMember, valueKind, diagnostics); Debug.Assert(boundMember.HasAnyErrors); break; @@ -6172,15 +6151,22 @@ private bool CollectionInitializerTypeImplementsIEnumerable(TypeSymbol initializ } else if (!initializerType.IsErrorType()) { - TypeSymbol collectionsIEnumerableType = this.GetSpecialType(SpecialType.System_Collections_IEnumerable, diagnostics, node); + NamedTypeSymbol collectionsIEnumerableType = this.GetSpecialType(SpecialType.System_Collections_IEnumerable, diagnostics, node); // NOTE: Ideally, to check if the initializer type implements System.Collections.IEnumerable we can walk through // NOTE: its implemented interfaces. However the native compiler checks to see if there is conversion from initializer // NOTE: type to the predefined System.Collections.IEnumerable type, so we do the same. CompoundUseSiteInfo useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); - var result = Conversions.ClassifyImplicitConversionFromType(initializerType, collectionsIEnumerableType, ref useSiteInfo).IsValid; + var result = Conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(initializerType, collectionsIEnumerableType, ref useSiteInfo, out bool needSupportForRefStructInterfaces); diagnostics.Add(node, useSiteInfo); + + if (needSupportForRefStructInterfaces && + initializerType.ContainingModule != Compilation.SourceModule) + { + CheckFeatureAvailability(node, MessageID.IDS_FeatureRefStructInterfaces, diagnostics); + } + return result; } else @@ -6573,70 +6559,38 @@ protected BoundExpression BindClassCreationExpression( if (finalApplicableCandidates.Length == 1) { Debug.Assert(finalApplicableCandidates[0].IsApplicable); - - if (IsAmbiguousDynamicParamsArgument(analyzedArguments.Arguments, finalApplicableCandidates[0], out SyntaxNode argumentSyntax)) - { - MethodSymbol singleCandidate = finalApplicableCandidates[0].Member; - - // We're only in trouble if a dynamic argument is passed to the - // params parameter and is ambiguous at compile time between normal - // and expanded form i.e., there is exactly one dynamic argument to - // a params parameter, and we know that runtime binder might not be - // able to handle the disambiguation - if (!singleCandidate.Parameters.Last().Type.IsSZArray()) - { - Error(diagnostics, - ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, - argumentSyntax, singleCandidate); - } - } - else - { - if (!type.IsAbstract) - { - result = BindClassCreationExpressionContinued(node, typeNode, type, analyzedArguments, initializerSyntaxOpt, - initializerTypeOpt, wasTargetTyped, finalApplicableCandidates[0], accessibleConstructors, in useSiteInfo, diagnostics); - } - else - { - result = CreateBadClassCreationExpression(node, typeNode, type, analyzedArguments, - initializerSyntaxOpt, initializerTypeOpt, finalApplicableCandidates[0], accessibleConstructors, in useSiteInfo, diagnostics); - } - } + ReportMemberNotSupportedByDynamicDispatch(node, finalApplicableCandidates[0], analyzedArguments.Arguments, diagnostics); } - if (result == null) + if (finalApplicableCandidates.Length != 1 && + Compilation.LanguageVersion > LanguageVersion.CSharp12 && // The following check (while correct) is redundant otherwise + HasApplicableMemberWithPossiblyExpandedNonArrayParamsCollection(analyzedArguments.Arguments, finalApplicableCandidates)) { - if (finalApplicableCandidates.Length != 1 && - Compilation.LanguageVersion > LanguageVersion.CSharp12 && // The following check (while correct) is redundant otherwise - HasApplicableMemberWithPossiblyExpandedNonArrayParamsCollection(analyzedArguments.Arguments, finalApplicableCandidates)) - { - Error(diagnostics, - ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor, - node); - } + Error(diagnostics, + ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor, + node); + } - var argArray = BuildArgumentsForDynamicInvocation(analyzedArguments, diagnostics); - var refKindsArray = analyzedArguments.RefKinds.ToImmutableOrNull(); + var argArray = BuildArgumentsForDynamicInvocation(analyzedArguments, diagnostics); + var refKindsArray = analyzedArguments.RefKinds.ToImmutableOrNull(); - hasErrors &= ReportBadDynamicArguments(node, receiver: null, argArray, refKindsArray, diagnostics, queryClause: null); + hasErrors &= ReportBadDynamicArguments(node, receiver: null, argArray, refKindsArray, diagnostics, queryClause: null); - BoundObjectInitializerExpressionBase boundInitializerOpt; - boundInitializerOpt = MakeBoundInitializerOpt(typeNode, type, initializerSyntaxOpt, initializerTypeOpt, diagnostics); - result = new BoundDynamicObjectCreationExpression( - node, - typeName, - argArray, - analyzedArguments.GetNames(), - refKindsArray, - boundInitializerOpt, - overloadResolutionResult.GetAllApplicableMembers(), - wasTargetTyped, - type, - hasErrors); + BoundObjectInitializerExpressionBase boundInitializerOpt; + boundInitializerOpt = MakeBoundInitializerOpt(typeNode, type, initializerSyntaxOpt, initializerTypeOpt, diagnostics); + result = new BoundDynamicObjectCreationExpression( + node, + typeName, + argArray, + analyzedArguments.GetNames(), + refKindsArray, + boundInitializerOpt, + overloadResolutionResult.GetAllApplicableMembers(), + wasTargetTyped, + type, + hasErrors); - diagnostics.Add(node, useSiteInfo); - } + diagnostics.Add(node, useSiteInfo); } overloadResolutionResult.Free(); @@ -8674,10 +8628,14 @@ private void CheckReceiverAndRuntimeSupportForSymbolAccess(SyntaxNode node, Boun } } - if (!Compilation.Assembly.RuntimeSupportsDefaultInterfaceImplementation && Compilation.SourceModule != symbol.ContainingModule) + if (receiverOpt is { Type: TypeParameterSymbol { AllowsRefLikeType: true } } && + isNotImplementableInstanceMember(symbol)) + { + Error(diagnostics, ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, node); + } + else if (!Compilation.Assembly.RuntimeSupportsDefaultInterfaceImplementation && Compilation.SourceModule != symbol.ContainingModule) { - if (!symbol.IsStatic && !(symbol is TypeSymbol) && - !symbol.IsImplementableInterfaceMember()) + if (isNotImplementableInstanceMember(symbol)) { Error(diagnostics, ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, node); } @@ -8695,6 +8653,12 @@ private void CheckReceiverAndRuntimeSupportForSymbolAccess(SyntaxNode node, Boun } } } + + static bool isNotImplementableInstanceMember(Symbol symbol) + { + return !symbol.IsStatic && !(symbol is TypeSymbol) && + !symbol.IsImplementableInterfaceMember(); + } } private BoundExpression BindEventAccess( @@ -9122,15 +9086,11 @@ BoundExpression bindInlineArrayElementAccess(ExpressionSyntax node, BoundExpress } } - var unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: node); + _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: node); _ = GetWellKnownTypeMember(createSpanHelper, diagnostics, syntax: node); _ = GetWellKnownTypeMember(getItemOrSliceHelper, diagnostics, syntax: node); - if (unsafeAsMethod is MethodSymbol { HasUnsupportedMetadata: false } method) - { - method.Construct(ImmutableArray.Create(TypeWithAnnotations.Create(expr.Type), elementField.TypeWithAnnotations)). - CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, node.GetLocation(), diagnostics)); - } + CheckInlineArrayTypeIsSupported(node, expr.Type, elementField.Type, diagnostics); if (!Compilation.Assembly.RuntimeSupportsInlineArrayTypes) { @@ -9716,32 +9676,7 @@ private BoundExpression BindIndexerOrIndexedPropertyAccess( if (finalApplicableCandidates.Length == 1) { Debug.Assert(finalApplicableCandidates[0].IsApplicable); - - if (IsAmbiguousDynamicParamsArgument(analyzedArguments.Arguments, finalApplicableCandidates[0], out SyntaxNode argumentSyntax)) - { - PropertySymbol singleCandidate = finalApplicableCandidates[0].LeastOverriddenMember; - - // We're only in trouble if a dynamic argument is passed to the - // params parameter and is ambiguous at compile time between normal - // and expanded form i.e., there is exactly one dynamic argument to - // a params parameter, and we know that runtime binder might not be - // able to handle the disambiguation - if (!singleCandidate.Parameters.Last().Type.IsSZArray()) - { - Error(diagnostics, - ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, - argumentSyntax, singleCandidate); - } - } - // For C# 12 and earlier always bind at runtime. - else if (Compilation.LanguageVersion > LanguageVersion.CSharp12) - { - var resultWithSingleCandidate = OverloadResolutionResult.GetInstance(); - resultWithSingleCandidate.ResultsBuilder.Add(finalApplicableCandidates[0]); - overloadResolutionResult.Free(); - - return BindIndexerOrIndexedPropertyAccessContinued(syntax, receiver, propertyGroup, analyzedArguments, resultWithSingleCandidate, hasDynamicArgument: true, diagnostics); - } + ReportMemberNotSupportedByDynamicDispatch(syntax, finalApplicableCandidates[0], analyzedArguments.Arguments, diagnostics); } if (finalApplicableCandidates.Length != 1 && @@ -9757,7 +9692,7 @@ private BoundExpression BindIndexerOrIndexedPropertyAccess( return BindDynamicIndexer(syntax, receiver, analyzedArguments, finalApplicableCandidates.SelectAsArray(r => r.Member), diagnostics); } - return BindIndexerOrIndexedPropertyAccessContinued(syntax, receiver, propertyGroup, analyzedArguments, overloadResolutionResult, hasDynamicArgument: false, diagnostics); + return BindIndexerOrIndexedPropertyAccessContinued(syntax, receiver, propertyGroup, analyzedArguments, overloadResolutionResult, diagnostics); } private BoundExpression BindIndexerOrIndexedPropertyAccessContinued( @@ -9766,7 +9701,6 @@ private BoundExpression BindIndexerOrIndexedPropertyAccessContinued( ArrayBuilder propertyGroup, AnalyzedArguments analyzedArguments, OverloadResolutionResult overloadResolutionResult, - bool hasDynamicArgument, BindingDiagnosticBag diagnostics) { BoundExpression propertyAccess; @@ -9828,25 +9762,6 @@ private BoundExpression BindIndexerOrIndexedPropertyAccessContinued( MemberResolutionResult resolutionResult = overloadResolutionResult.ValidResult; PropertySymbol property = resolutionResult.Member; - bool forceDynamicResultType = false; - var useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); - - // Due to backward compatibility, invocations statically bound in presence of dynamic arguments - // should have dynamic result if their dynamic binding succeeded in C# 12 and there are no - // obvious reasons for the runtime binder to fail (ref return, for example). - if (hasDynamicArgument && - !(property.Type.IsDynamic() || property.ReturnsByRef || - !Conversions.ClassifyConversionFromExpressionType(property.Type, Compilation.DynamicType, isChecked: false, ref useSiteInfo).IsImplicit || - IsMemberWithExpandedNonArrayParamsCollection(resolutionResult))) - { - var tryDynamicAccessDiagnostics = BindingDiagnosticBag.GetInstance(withDiagnostics: true, withDependencies: false); - BindDynamicIndexer(syntax, receiver, analyzedArguments, ImmutableArray.Create(property), tryDynamicAccessDiagnostics); - forceDynamicResultType = !tryDynamicAccessDiagnostics.HasAnyResolvedErrors(); - tryDynamicAccessDiagnostics.Free(); - } - - diagnostics.Add(syntax, useSiteInfo); - ReportDiagnosticsIfObsolete(diagnostics, property, syntax, hasBaseReceiver: receiver != null && receiver.Kind == BoundKind.BaseReference); // Make sure that the result of overload resolution is valid. @@ -9877,7 +9792,7 @@ private BoundExpression BindIndexerOrIndexedPropertyAccessContinued( expanded: resolutionResult.Result.Kind == MemberResolutionKind.ApplicableInExpandedForm, argsToParams, defaultArguments: default, - forceDynamicResultType ? Compilation.DynamicType : property.Type, + property.Type, gotError); } @@ -10717,7 +10632,7 @@ bool satisfiesConstraintChecks(MethodSymbol method) parameters.SelectAsArray(p => p.ExplicitDefaultConstantValue) : default; - var hasParams = OverloadResolution.IsValidParams(this, methodSymbol); + var hasParams = OverloadResolution.IsValidParams(this, methodSymbol, out _); Debug.Assert(ContainingMemberOrLambda is { }); Debug.Assert(parameterRefKinds.IsDefault || parameterRefKinds.Length == parameterTypes.Length); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs index 7374ede9d1163..e594a2999aea2 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Flags.cs @@ -91,11 +91,24 @@ internal Binder WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags flags return new BinderWithContainingMemberOrLambda(this, this.Flags | flags, containing); } - internal Binder WithUnsafeRegionIfNecessary(SyntaxTokenList modifiers) + internal Binder SetOrClearUnsafeRegionIfNecessary(SyntaxTokenList modifiers, bool isIteratorBody = false) { - return (this.Flags.Includes(BinderFlags.UnsafeRegion) || !modifiers.Any(SyntaxKind.UnsafeKeyword)) - ? this - : new Binder(this, this.Flags | BinderFlags.UnsafeRegion); + // In C# 13 and above, iterator bodies define a safe context even when nested in an unsafe context. + // In C# 12 and below, we keep the (spec violating) behavior that iterator bodies inherit the safe/unsafe context + // from their containing scope. Since there are errors for unsafe constructs directly in iterators, + // this inherited unsafe context can be observed only in nested non-iterator local functions. + var withoutUnsafe = isIteratorBody && this.Compilation.IsFeatureEnabled(MessageID.IDS_FeatureRefUnsafeInIteratorAsync); + + if (this.Flags.Includes(BinderFlags.UnsafeRegion)) + { + return withoutUnsafe + ? new Binder(this, this.Flags & ~BinderFlags.UnsafeRegion) + : this; + } + + return !withoutUnsafe && modifiers.Any(SyntaxKind.UnsafeKeyword) + ? new Binder(this, this.Flags | BinderFlags.UnsafeRegion) + : this; } internal Binder WithCheckedOrUncheckedRegion(bool @checked) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs index 839d23ee94800..8a32d3821bb6f 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Invocation.cs @@ -641,40 +641,13 @@ private BoundExpression BindDelegateInvocation( if (analyzedArguments.HasDynamicArgument && overloadResolutionResult.HasAnyApplicableMember) { var applicable = overloadResolutionResult.Results.Single(r => r.IsApplicable); + ReportMemberNotSupportedByDynamicDispatch(node, applicable, analyzedArguments.Arguments, diagnostics); - // We have to do a dynamic dispatch only when a dynamic argument is - // passed to the params parameter and is ambiguous at compile time between normal - // and expanded form i.e., there is exactly one dynamic argument to - // a params parameter. - - if (IsAmbiguousDynamicParamsArgument(analyzedArguments.Arguments, applicable, out SyntaxNode argumentSyntax)) - { - MethodSymbol singleCandidate = applicable.Member; - - // We know that runtime binder might not be - // able to handle the disambiguation - if (!singleCandidate.Parameters.Last().Type.IsSZArray()) - { - Error(diagnostics, - ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, - argumentSyntax, singleCandidate); - } - - result = BindDynamicInvocation(node, boundExpression, analyzedArguments, overloadResolutionResult.GetAllApplicableMembers(), diagnostics, queryClause); - } - // For C# 12 and earlier always bind at runtime. - else if (Compilation.LanguageVersion > LanguageVersion.CSharp12) - { - result = BindInvocationExpressionContinued(node, expression, methodName, overloadResolutionResult, analyzedArguments, methodGroup, delegateType, hasDynamicArgument: true, boundExpression, diagnostics, queryClause); - } - else - { - result = BindDynamicInvocation(node, boundExpression, analyzedArguments, overloadResolutionResult.GetAllApplicableMembers(), diagnostics, queryClause); - } + result = BindDynamicInvocation(node, boundExpression, analyzedArguments, overloadResolutionResult.GetAllApplicableMembers(), diagnostics, queryClause); } else { - result = BindInvocationExpressionContinued(node, expression, methodName, overloadResolutionResult, analyzedArguments, methodGroup, delegateType, hasDynamicArgument: false, boundExpression, diagnostics, queryClause); + result = BindInvocationExpressionContinued(node, expression, methodName, overloadResolutionResult, analyzedArguments, methodGroup, delegateType, diagnostics, queryClause); } overloadResolutionResult.Free(); @@ -711,11 +684,25 @@ private bool HasApplicableMemberWithPossiblyExpandedNonArrayParamsCollection(MemberResolutionResult candidate) + private void ReportMemberNotSupportedByDynamicDispatch(SyntaxNode syntax, MemberResolutionResult candidate, ArrayBuilder arguments, BindingDiagnosticBag diagnostics) where TMember : Symbol { - return candidate.Result.Kind == MemberResolutionKind.ApplicableInExpandedForm && - !candidate.Member.GetParameters().Last().Type.IsSZArray(); + if (candidate.Result.Kind == MemberResolutionKind.ApplicableInExpandedForm && + !candidate.Member.GetParameters().Last().Type.IsSZArray()) + { + Error(diagnostics, + ErrorCode.ERR_DynamicDispatchToParamsCollection, + syntax, candidate.LeastOverriddenMember); + } + else if (IsAmbiguousDynamicParamsArgument(arguments, candidate, out SyntaxNode argumentSyntax) && + !candidate.LeastOverriddenMember.GetParameters().Last().Type.IsSZArray()) + { + // We know that runtime binder might not be + // able to handle the disambiguation + Error(diagnostics, + ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, + argumentSyntax, candidate.LeastOverriddenMember); + } } private BoundExpression BindMethodGroupInvocation( @@ -792,7 +779,7 @@ private BoundExpression BindMethodGroupInvocation( // we want to force any unbound lambda arguments to cache an appropriate conversion if possible; see 9448. result = BindInvocationExpressionContinued( syntax, expression, methodName, resolution.OverloadResolutionResult, resolution.AnalyzedArguments, - resolution.MethodGroup, delegateTypeOpt: null, hasDynamicArgument: false, methodGroup, diagnostics: BindingDiagnosticBag.Discarded, queryClause: queryClause); + resolution.MethodGroup, delegateTypeOpt: null, diagnostics: BindingDiagnosticBag.Discarded, queryClause: queryClause); } // Since the resolution is non-empty and has no diagnostics, the LookupResultKind in its MethodGroup is uninteresting. @@ -824,6 +811,11 @@ private BoundExpression BindMethodGroupInvocation( Debug.Assert(finalApplicableCandidates[0].IsApplicable); result = TryEarlyBindSingleCandidateInvocationWithDynamicArgument(syntax, expression, methodName, methodGroup, diagnostics, queryClause, resolution, finalApplicableCandidates[0]); + + if (result is null && finalApplicableCandidates[0].LeastOverriddenMember.MethodKind != MethodKind.LocalFunction) + { + ReportMemberNotSupportedByDynamicDispatch(syntax, finalApplicableCandidates[0], resolution.AnalyzedArguments.Arguments, diagnostics); + } } if (result is null) @@ -856,7 +848,7 @@ private BoundExpression BindMethodGroupInvocation( { result = BindInvocationExpressionContinued( syntax, expression, methodName, resolution.OverloadResolutionResult, resolution.AnalyzedArguments, - resolution.MethodGroup, delegateTypeOpt: null, hasDynamicArgument: false, methodGroup, diagnostics: diagnostics, queryClause: queryClause); + resolution.MethodGroup, delegateTypeOpt: null, diagnostics: diagnostics, queryClause: queryClause); } } } @@ -890,7 +882,7 @@ private void ReportDynamicInvocationWarnings(SyntaxNode syntax, BoundMethodGroup private bool IsAmbiguousDynamicParamsArgument(ArrayBuilder arguments, MemberResolutionResult candidate, out SyntaxNode argumentSyntax) where TMethodOrPropertySymbol : Symbol { - if (OverloadResolution.IsValidParams(this, candidate.LeastOverriddenMember) && + if (OverloadResolution.IsValidParams(this, candidate.LeastOverriddenMember, out _) && candidate.Result.Kind == MemberResolutionKind.ApplicableInNormalForm) { var parameters = candidate.Member.GetParameters(); @@ -920,13 +912,10 @@ private bool CanEarlyBindSingleCandidateInvocationWithDynamicArgument( MemberResolutionResult methodResolutionResult, MethodSymbol singleCandidate) { - // - // !!! ATTENTION !!! - // - // In terms of errors relevant for HasCollectionExpressionApplicableAddMethod check - // this function should be kept in sync with local function - // HasCollectionExpressionApplicableAddMethod.canEarlyBindSingleCandidateInvocationWithDynamicArgument - // + if (singleCandidate.MethodKind != MethodKind.LocalFunction) + { + return false; + } if (boundMethodGroup.TypeArgumentsOpt.IsDefaultOrEmpty && singleCandidate.IsGenericMethod) { @@ -943,19 +932,9 @@ private bool CanEarlyBindSingleCandidateInvocationWithDynamicArgument( // seem to worth the complexity. So, just disallow any mixing of dynamic and // inferred generics. (Explicit generic arguments are fine) - if (OverloadResolution.IsValidParams(this, singleCandidate) && - !singleCandidate.Parameters.Last().Type.IsSZArray()) - { - Error(diagnostics, - ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, - syntax, singleCandidate); - } - else if (singleCandidate.MethodKind == MethodKind.LocalFunction) - { - Error(diagnostics, - ErrorCode.ERR_DynamicLocalFunctionTypeParameter, - syntax, singleCandidate.Name); - } + Error(diagnostics, + ErrorCode.ERR_DynamicLocalFunctionTypeParameter, + syntax, singleCandidate.Name); return false; } @@ -968,18 +947,9 @@ private bool CanEarlyBindSingleCandidateInvocationWithDynamicArgument( // a params parameter, and we know that runtime binder might not be // able to handle the disambiguation // See https://github.com/dotnet/roslyn/issues/10708 - if (!singleCandidate.Parameters.Last().Type.IsSZArray()) - { - Error(diagnostics, - ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, - argumentSyntax, singleCandidate); - } - else if (singleCandidate.MethodKind == MethodKind.LocalFunction) - { - Error(diagnostics, - ErrorCode.ERR_DynamicLocalFunctionParamsParameter, - argumentSyntax, singleCandidate.Parameters.Last().Name, singleCandidate.Name); - } + Error(diagnostics, + ErrorCode.ERR_DynamicLocalFunctionParamsParameter, + argumentSyntax, singleCandidate.Parameters.Last().Name, singleCandidate.Name); return false; } @@ -997,14 +967,6 @@ private BoundExpression TryEarlyBindSingleCandidateInvocationWithDynamicArgument MethodGroupResolution resolution, MemberResolutionResult methodResolutionResult) { - // - // !!! ATTENTION !!! - // - // In terms of errors relevant for HasCollectionExpressionApplicableAddMethod check - // this function should be kept in sync with local function - // HasCollectionExpressionApplicableAddMethod.tryEarlyBindSingleCandidateInvocationWithDynamicArgument - // - MethodSymbol singleCandidate = methodResolutionResult.LeastOverriddenMember; if (!CanEarlyBindSingleCandidateInvocationWithDynamicArgument(syntax, boundMethodGroup, diagnostics, resolution, methodResolutionResult, singleCandidate)) @@ -1012,32 +974,23 @@ private BoundExpression TryEarlyBindSingleCandidateInvocationWithDynamicArgument return null; } - // For C# 12 and earlier statically bind invocations in presence of dynamic arguments only for local functions. - if (Compilation.LanguageVersion > LanguageVersion.CSharp12 || - singleCandidate.MethodKind == MethodKind.LocalFunction) - { - var resultWithSingleCandidate = OverloadResolutionResult.GetInstance(); - resultWithSingleCandidate.ResultsBuilder.Add(methodResolutionResult); - - BoundExpression result = BindInvocationExpressionContinued( - node: syntax, - expression: expression, - methodName: methodName, - result: resultWithSingleCandidate, - analyzedArguments: resolution.AnalyzedArguments, - methodGroup: resolution.MethodGroup, - delegateTypeOpt: null, - hasDynamicArgument: true, - boundMethodGroup, - diagnostics: diagnostics, - queryClause: queryClause); + var resultWithSingleCandidate = OverloadResolutionResult.GetInstance(); + resultWithSingleCandidate.ResultsBuilder.Add(methodResolutionResult); - resultWithSingleCandidate.Free(); + BoundExpression result = BindInvocationExpressionContinued( + node: syntax, + expression: expression, + methodName: methodName, + result: resultWithSingleCandidate, + analyzedArguments: resolution.AnalyzedArguments, + methodGroup: resolution.MethodGroup, + delegateTypeOpt: null, + diagnostics: diagnostics, + queryClause: queryClause); - return result; - } + resultWithSingleCandidate.Free(); - return null; + return result; } private ImmutableArray> GetCandidatesPassingFinalValidation( @@ -1120,7 +1073,7 @@ private void CheckRestrictedTypeReceiver(BoundExpression expression, CSharpCompi // error CS0029: Cannot implicitly convert type 'A' to 'B' // Case 1: receiver is a restricted type, and method called is defined on a parent type - if (call.ReceiverOpt.Type.IsRestrictedType() && !TypeSymbol.Equals(call.Method.ContainingType, call.ReceiverOpt.Type, TypeCompareKind.ConsiderEverything2)) + if (call.ReceiverOpt.Type.IsRestrictedType() && !call.Method.ContainingType.IsInterface && !TypeSymbol.Equals(call.Method.ContainingType, call.ReceiverOpt.Type, TypeCompareKind.ConsiderEverything2)) { SymbolDistinguisher distinguisher = new SymbolDistinguisher(compilation, call.ReceiverOpt.Type, call.Method.ContainingType); Error(diagnostics, ErrorCode.ERR_NoImplicitConv, call.ReceiverOpt.Syntax, distinguisher.First, distinguisher.Second); @@ -1176,8 +1129,6 @@ private BoundCall BindInvocationExpressionContinued( AnalyzedArguments analyzedArguments, MethodGroup methodGroup, NamedTypeSymbol delegateTypeOpt, - bool hasDynamicArgument, - BoundExpression targetMethodGroupOrDelegateInstance, BindingDiagnosticBag diagnostics, CSharpSyntaxNode queryClause = null) { @@ -1253,32 +1204,12 @@ private BoundCall BindInvocationExpressionContinued( GetOriginalMethods(result), methodGroup.ResultKind, methodGroup.TypeArguments.ToImmutable(), analyzedArguments, invokedAsExtensionMethod: invokedAsExtensionMethod, isDelegate: ((object)delegateTypeOpt != null)); } - // Otherwise, overload resolution found a unique best candidate. + // Otherwise, there were no dynamic arguments and overload resolution found a unique best candidate. // We still have to determine if it passes final validation. var methodResult = result.ValidResult; var returnType = methodResult.Member.ReturnType; var method = methodResult.Member; - bool forceDynamicResultType = false; - - var useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); - - // Due to backward compatibility, invocations statically bound in presence of dynamic arguments - // should have dynamic result if their dynamic binding succeeded in C# 12 and there are no - // obvious reasons for the runtime binder to fail (ref return, for example). - if (hasDynamicArgument && - !(methodGroup.IsExtensionMethodGroup || method.MethodKind == MethodKind.LocalFunction || - method.ReturnsVoid || method.ReturnsByRef || returnType.IsDynamic() || - !Conversions.ClassifyConversionFromExpressionType(returnType, Compilation.DynamicType, isChecked: false, ref useSiteInfo).IsImplicit || - IsMemberWithExpandedNonArrayParamsCollection(methodResult))) - { - var tryDynamicInvocationDiagnostics = BindingDiagnosticBag.GetInstance(withDiagnostics: true, withDependencies: false); - BindDynamicInvocation(node, targetMethodGroupOrDelegateInstance, analyzedArguments, ImmutableArray.Create(method), tryDynamicInvocationDiagnostics, queryClause); - forceDynamicResultType = !tryDynamicInvocationDiagnostics.HasAnyResolvedErrors(); - tryDynamicInvocationDiagnostics.Free(); - } - - diagnostics.Add(node, useSiteInfo); // It is possible that overload resolution succeeded, but we have chosen an // instance method and we're in a static method. A careful reading of the @@ -1408,9 +1339,7 @@ private BoundCall BindInvocationExpressionContinued( return new BoundCall(node, receiver, initialBindingReceiverIsSubjectToCloning: ReceiverIsSubjectToCloning(receiver, method), method, args, argNames, argRefKinds, isDelegateCall: isDelegateCall, expanded: expanded, invokedAsExtensionMethod: invokedAsExtensionMethod, - argsToParamsOpt: argsToParams, defaultArguments, resultKind: LookupResultKind.Viable, - type: forceDynamicResultType ? Compilation.DynamicType : returnType, - hasErrors: gotError); + argsToParamsOpt: argsToParams, defaultArguments, resultKind: LookupResultKind.Viable, type: returnType, hasErrors: gotError); } #nullable enable @@ -1430,7 +1359,7 @@ internal ThreeState ReceiverIsSubjectToCloning(BoundExpression? receiver, Proper internal ThreeState ReceiverIsSubjectToCloning(BoundExpression? receiver, MethodSymbol method) { - if (receiver is BoundValuePlaceholderBase || receiver?.Type?.IsValueType != true) + if (receiver is BoundValuePlaceholderBase || receiver?.Type is null or { IsReferenceType: true }) { return ThreeState.False; } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs index 498267c0fbd56..fd65a700503d9 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Lambda.cs @@ -368,7 +368,7 @@ private UnboundLambda BindAnonymousFunction(AnonymousFunctionExpressionSyntax sy // UNDONE: Where do we report improper use of pointer types? ParameterHelpers.ReportParameterErrors(owner: null, paramSyntax, ordinal: i, lastParameterIndex: lambda.ParameterCount - 1, isParams: isParams, lambda.ParameterTypeWithAnnotations(i), - lambda.RefKind(i), lambda.DeclaredScope(i), containingSymbol: null, thisKeyword: default, paramsKeyword: paramsKeyword, firstDefault, diagnostics); + lambda.RefKind(i), containingSymbol: null, thisKeyword: default, paramsKeyword: paramsKeyword, firstDefault, diagnostics); } } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs index 6a69fe918bbfd..0ad8bfe1caf04 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs @@ -22,7 +22,7 @@ private BoundExpression BindCompoundAssignment(AssignmentExpressionSyntax node, { node.Left.CheckDeconstructionCompatibleArgument(diagnostics); - BoundExpression left = BindValue(node.Left, diagnostics, GetBinaryAssignmentKind(node.Kind()), dynamificationOfAssignmentResultIsHandled: true); + BoundExpression left = BindValue(node.Left, diagnostics, GetBinaryAssignmentKind(node.Kind())); ReportSuppressionIfNeeded(left, diagnostics); BoundExpression right = BindValue(node.Right, diagnostics, BindValueKind.RValue); BinaryOperatorKind kind = SyntaxKindToBinaryOperatorKind(node.Kind()); @@ -43,8 +43,6 @@ private BoundExpression BindCompoundAssignment(AssignmentExpressionSyntax node, } } - left = AdjustAssignmentTargetForDynamic(left, out bool forceDynamicResult); - if (left.HasAnyErrors || right.HasAnyErrors) { // NOTE: no overload resolution candidates. @@ -83,7 +81,7 @@ private BoundExpression BindCompoundAssignment(AssignmentExpressionSyntax node, finalPlaceholder: placeholder, finalConversion: conversion, LookupResultKind.Viable, - AdjustAssignmentTypeToDynamicIfNecessary(left.Type, forceDynamicResult), + left.Type, hasErrors: false); } else @@ -246,56 +244,7 @@ private BoundExpression BindCompoundAssignment(AssignmentExpressionSyntax node, var leftConversion = CreateConversion(node.Left, leftPlaceholder, best.LeftConversion, isCast: false, conversionGroupOpt: null, best.Signature.LeftType, diagnostics); return new BoundCompoundAssignmentOperator(node, bestSignature, left, rightConverted, - leftPlaceholder, leftConversion, finalPlaceholder, finalConversion, resultKind, originalUserDefinedOperators, AdjustAssignmentTypeToDynamicIfNecessary(left.Type, forceDynamicResult), hasError); - } - - /// - /// When an indexer is accessed with dynamic argument is resolved statically, - /// in some scenarios its result type is set to 'dynamic' type. - /// Assignments to such indexers should be bound statically as well, reverting back - /// to the indexer's type for the target and setting result type of the assignment to 'dynamic' type. - /// - /// This helper takes care of the "reverting back to the indexer's type for the target" part. - /// See for the helper for the second part. - /// - private static BoundExpression AdjustAssignmentTargetForDynamic(BoundExpression target, out bool forceDynamicResult) - { - if (target is BoundIndexerAccess { Type.TypeKind: TypeKind.Dynamic, Indexer.Type.TypeKind: not TypeKind.Dynamic } indexerAccess) - { - Debug.Assert(!indexerAccess.Indexer.ReturnsByRef); - forceDynamicResult = true; - target = indexerAccess.Update( - indexerAccess.ReceiverOpt, - indexerAccess.InitialBindingReceiverIsSubjectToCloning, - indexerAccess.Indexer, - indexerAccess.Arguments, - indexerAccess.ArgumentNamesOpt, - indexerAccess.ArgumentRefKindsOpt, - indexerAccess.Expanded, - indexerAccess.ArgsToParamsOpt, - indexerAccess.DefaultArguments, - indexerAccess.Indexer.Type); - } - else - { - forceDynamicResult = false; - } - - return target; - } - - /// - /// When an indexer is accessed with dynamic argument is resolved statically, - /// in some scenarios its result type is set to 'dynamic' type. - /// Assignments to such indexers should be bound statically as well, reverting back - /// to the indexer's type for the target and setting result type of the assignment to 'dynamic' type. - /// - /// This helper takes care of the "setting result type of the assignment to 'dynamic' type" part. - /// See helper for the first part. - /// - TypeSymbol AdjustAssignmentTypeToDynamicIfNecessary(TypeSymbol leftType, bool forceDynamicResult) - { - return forceDynamicResult ? Compilation.DynamicType : leftType; + leftPlaceholder, leftConversion, finalPlaceholder, finalConversion, resultKind, originalUserDefinedOperators, leftType, hasError); } /// @@ -2312,9 +2261,7 @@ private BoundExpression BindIncrementOperator(CSharpSyntaxNode node, ExpressionS { operandSyntax.CheckDeconstructionCompatibleArgument(diagnostics); - BoundExpression operand = BindToNaturalType(BindValue(operandSyntax, diagnostics, BindValueKind.IncrementDecrement, dynamificationOfAssignmentResultIsHandled: true), - diagnostics); - + BoundExpression operand = BindToNaturalType(BindValue(operandSyntax, diagnostics, BindValueKind.IncrementDecrement), diagnostics); UnaryOperatorKind kind = SyntaxKindToUnaryOperatorKind(node.Kind()); // If the operand is bad, avoid generating cascading errors. @@ -2336,8 +2283,6 @@ private BoundExpression BindIncrementOperator(CSharpSyntaxNode node, ExpressionS hasErrors: true); } - operand = AdjustAssignmentTargetForDynamic(operand, out bool forceDynamicResult); - // The operand has to be a variable, property or indexer, so it must have a type. var operandType = operand.Type; Debug.Assert((object)operandType != null); @@ -2424,7 +2369,7 @@ private BoundExpression BindIncrementOperator(CSharpSyntaxNode node, ExpressionS resultConversion, resultKind, originalUserDefinedOperators, - AdjustAssignmentTypeToDynamicIfNecessary(operandType, forceDynamicResult), + operandType, hasErrors); } @@ -3566,10 +3511,37 @@ internal static ConstantValue GetIsOperatorConstantResult( return ConstantValue.False; } - // * If either type is a restricted type, the type check isn't supported because + // * If either type is a restricted type, the type check isn't supported for some scenarios because // a restricted type cannot be boxed or unboxed into. if (targetType.IsRestrictedType() || operandType.IsRestrictedType()) { + if (targetType is TypeParameterSymbol { AllowsRefLikeType: true }) + { + if (!operandType.IsRefLikeType && operandType is not TypeParameterSymbol) + { + return null; + } + } + else if (operandType is not TypeParameterSymbol { AllowsRefLikeType: true }) + { + if (targetType.IsRefLikeType) + { + if (operandType is TypeParameterSymbol) + { + Debug.Assert(operandType is TypeParameterSymbol { AllowsRefLikeType: false }); + return ConstantValue.False; + } + } + else if (operandType.IsRefLikeType) + { + if (targetType is TypeParameterSymbol) + { + Debug.Assert(targetType is TypeParameterSymbol { AllowsRefLikeType: false }); + return ConstantValue.False; + } + } + } + return ConstantValue.Bad; } @@ -3981,6 +3953,11 @@ internal static ConstantValue GetAsOperatorConstantResult(TypeSymbol operandType if (!isOperatorConstantResult.BooleanValue) { + if (operandType?.IsRefLikeType == true) + { + return ConstantValue.Bad; + } + return ConstantValue.Null; } } @@ -4189,11 +4166,8 @@ private BoundExpression BindNullCoalescingAssignmentOperator(AssignmentExpressio { MessageID.IDS_FeatureCoalesceAssignmentExpression.CheckFeatureAvailability(diagnostics, node.OperatorToken); - BoundExpression leftOperand = BindValue(node.Left, diagnostics, BindValueKind.CompoundAssignment, dynamificationOfAssignmentResultIsHandled: true); + BoundExpression leftOperand = BindValue(node.Left, diagnostics, BindValueKind.CompoundAssignment); ReportSuppressionIfNeeded(leftOperand, diagnostics); - - leftOperand = AdjustAssignmentTargetForDynamic(leftOperand, out bool forceDynamicResult); - BoundExpression rightOperand = BindValue(node.Right, diagnostics, BindValueKind.RValue); // If either operand is bad, bail out preventing more cascading errors @@ -4228,9 +4202,7 @@ private BoundExpression BindNullCoalescingAssignmentOperator(AssignmentExpressio { diagnostics.Add(node, useSiteInfo); var convertedRightOperand = CreateConversion(rightOperand, underlyingRightConversion, underlyingLeftType, diagnostics); - var result = new BoundNullCoalescingAssignmentOperator(node, leftOperand, convertedRightOperand, AdjustAssignmentTypeToDynamicIfNecessary(underlyingLeftType, forceDynamicResult)); - Debug.Assert(result.IsNullableValueTypeAssignment); - return result; + return new BoundNullCoalescingAssignmentOperator(node, leftOperand, convertedRightOperand, underlyingLeftType); } } @@ -4244,9 +4216,7 @@ private BoundExpression BindNullCoalescingAssignmentOperator(AssignmentExpressio if (rightConversion.Exists) { var convertedRightOperand = CreateConversion(rightOperand, rightConversion, leftType, diagnostics); - var result = new BoundNullCoalescingAssignmentOperator(node, leftOperand, convertedRightOperand, AdjustAssignmentTypeToDynamicIfNecessary(leftType, forceDynamicResult)); - Debug.Assert(!result.IsNullableValueTypeAssignment); - return result; + return new BoundNullCoalescingAssignmentOperator(node, leftOperand, convertedRightOperand, leftType); } // a and b are incompatible and a compile-time error occurs diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index 5fbaa109f9bed..f5392eafa6697 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -176,9 +176,7 @@ private BoundStatement BindUnsafeStatement(UnsafeStatementSyntax node, BindingDi } else if (this.IsIndirectlyInIterator) // called *after* we know the binder map has been created. { - // Spec 8.2: "An iterator block always defines a safe context, even when its declaration - // is nested in an unsafe context." - Error(diagnostics, ErrorCode.ERR_IllegalInnerUnsafe, node.UnsafeKeyword); + CheckFeatureAvailability(node.UnsafeKeyword, MessageID.IDS_FeatureRefUnsafeInIteratorAsync, diagnostics); } return BindEmbeddedBlock(node.Block, diagnostics); @@ -268,6 +266,15 @@ private BoundStatement BindYieldReturnStatement(YieldStatementSyntax node, Bindi { Error(diagnostics, ErrorCode.ERR_YieldNotAllowedInScript, node.YieldKeyword); } + else if (InUnsafeRegion && Compilation.IsFeatureEnabled(MessageID.IDS_FeatureRefUnsafeInIteratorAsync)) + { + Error(diagnostics, ErrorCode.ERR_BadYieldInUnsafe, node.YieldKeyword); + } + // NOTE: Error conditions should be checked above this point; only warning conditions below. + else if (this.Flags.Includes(BinderFlags.InLockBody)) + { + Error(diagnostics, ErrorCode.WRN_BadYieldInLock, node.YieldKeyword); + } CheckRequiredLangVersionForIteratorMethods(node, diagnostics); return new BoundYieldReturnStatement(node, argument); @@ -1100,7 +1107,7 @@ protected BoundLocalDeclaration BindVariableDeclaration( CheckRestrictedTypeInAsyncMethod(this.ContainingMemberOrLambda, declTypeOpt.Type, localDiagnostics, typeSyntax); - if (localSymbol.Scope == ScopedKind.ScopedValue && !declTypeOpt.Type.IsErrorTypeOrRefLikeType()) + if (localSymbol.Scope == ScopedKind.ScopedValue && !declTypeOpt.Type.IsErrorOrRefLikeOrAllowsRefLikeType()) { localDiagnostics.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly, typeSyntax.Location); } @@ -1165,15 +1172,9 @@ protected BoundLocalDeclaration BindVariableDeclaration( protected bool CheckRefLocalInAsyncOrIteratorMethod(SyntaxToken identifierToken, BindingDiagnosticBag diagnostics) { - if (IsInAsyncMethod()) + if (IsDirectlyInIterator || IsInAsyncMethod()) { - Error(diagnostics, ErrorCode.ERR_BadAsyncLocalType, identifierToken); - return true; - } - else if (IsDirectlyInIterator) - { - Error(diagnostics, ErrorCode.ERR_BadIteratorLocalType, identifierToken); - return true; + return !CheckFeatureAvailability(identifierToken, MessageID.IDS_FeatureRefUnsafeInIteratorAsync, diagnostics); } return false; @@ -1429,11 +1430,9 @@ private BoundExpression BindAssignment(AssignmentExpressionSyntax node, BindingD if (isRef) MessageID.IDS_FeatureRefReassignment.CheckFeatureAvailability(diagnostics, node.Right.GetFirstToken()); - var op1 = BindValue(node.Left, diagnostics, lhsKind, dynamificationOfAssignmentResultIsHandled: true); + var op1 = BindValue(node.Left, diagnostics, lhsKind); ReportSuppressionIfNeeded(op1, diagnostics); - op1 = AdjustAssignmentTargetForDynamic(op1, out bool forceDynamicResult); - var rhsKind = isRef ? GetRequiredRHSValueKindForRefAssignment(op1) : BindValueKind.RValue; var op2 = BindValue(rhsExpr, diagnostics, rhsKind); @@ -1444,10 +1443,7 @@ private BoundExpression BindAssignment(AssignmentExpressionSyntax node, BindingD op1 = InferTypeForDiscardAssignment((BoundDiscardExpression)op1, op2, diagnostics); } - BoundAssignmentOperator result = BindAssignment(node, op1, op2, isRef, diagnostics); - result = result.Update(result.Left, result.Right, result.IsRef, AdjustAssignmentTypeToDynamicIfNecessary(result.Type, forceDynamicResult)); - - return result; + return BindAssignment(node, op1, op2, isRef, diagnostics); } private static BindValueKind GetRequiredRHSValueKindForRefAssignment(BoundExpression boundLeft) @@ -1585,7 +1581,7 @@ private void ValidateAssignment( leftEscape = GetValEscape(op1, _localScopeDepth); rightEscape = GetValEscape(op2, _localScopeDepth); - Debug.Assert(leftEscape == rightEscape || op1.Type.IsRefLikeType); + Debug.Assert(leftEscape == rightEscape || op1.Type.IsRefLikeOrAllowsRefLikeType()); // We only check if the safe-to-escape of e2 is wider than the safe-to-escape of e1 here, // we don't check for equality. The case where the safe-to-escape of e2 is narrower than @@ -1604,7 +1600,7 @@ private void ValidateAssignment( } } - if (!hasErrors && op1.Type.IsRefLikeType) + if (!hasErrors && op1.Type.IsRefLikeOrAllowsRefLikeType()) { var leftEscape = GetValEscape(op1, _localScopeDepth); ValidateEscape(op2, leftEscape, isByRef: false, diagnostics); diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Unsafe.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Unsafe.cs index ec8cd5d3885b7..2c4d9b6a7fb88 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Unsafe.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Unsafe.cs @@ -56,18 +56,16 @@ private CSDiagnosticInfo GetUnsafeDiagnosticInfo(TypeSymbol sizeOfTypeOpt) { return null; } - else if (this.IsIndirectlyInIterator) - { - // Spec 8.2: "An iterator block always defines a safe context, even when its declaration - // is nested in an unsafe context." - return new CSDiagnosticInfo(ErrorCode.ERR_IllegalInnerUnsafe); - } else if (!this.InUnsafeRegion) { return ((object)sizeOfTypeOpt == null) ? new CSDiagnosticInfo(ErrorCode.ERR_UnsafeNeeded) : new CSDiagnosticInfo(ErrorCode.ERR_SizeofUnsafe, sizeOfTypeOpt); } + else if (this.IsIndirectlyInIterator && MessageID.IDS_FeatureRefUnsafeInIteratorAsync.GetFeatureAvailabilityDiagnosticInfo(Compilation) is { } unsafeInIteratorDiagnosticInfo) + { + return unsafeInIteratorDiagnosticInfo; + } else { return null; diff --git a/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs b/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs index edffa7f5535d3..e08152589f822 100644 --- a/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ExecutableCodeBinder.cs @@ -129,7 +129,7 @@ public static void ValidateIteratorMethod(CSharpCompilation compilation, MethodS if (((iterator as SourceMemberMethodSymbol)?.IsUnsafe == true || (iterator as LocalFunctionSymbol)?.IsUnsafe == true) && compilation.Options.AllowUnsafe) // Don't cascade { - diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, errorLocation); + MessageID.IDS_FeatureRefUnsafeInIteratorAsync.CheckFeatureAvailability(diagnostics, compilation, errorLocation); } var returnType = iterator.ReturnType; diff --git a/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs b/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs index c2db44e853310..888094f169b44 100644 --- a/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs @@ -315,7 +315,7 @@ private BoundForEachStatement BindForEachPartsWorker(BindingDiagnosticBag diagno CheckRestrictedTypeInAsyncMethod(this.ContainingMemberOrLambda, declType.Type, diagnostics, typeSyntax); - if (local.Scope == ScopedKind.ScopedValue && !declType.Type.IsErrorTypeOrRefLikeType()) + if (local.Scope == ScopedKind.ScopedValue && !declType.Type.IsErrorOrRefLikeOrAllowsRefLikeType()) { diagnostics.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly, typeSyntax.Location); } @@ -882,13 +882,9 @@ private EnumeratorResult GetEnumeratorInfoCore(SyntaxNode syntax, SyntaxNode col } _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__Add_T, diagnostics, syntax: collectionExpr.Syntax); - var unsafeAsMethod = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: collectionExpr.Syntax); + _ = GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_Unsafe__As_T, diagnostics, syntax: collectionExpr.Syntax); - if (unsafeAsMethod is MethodSymbol { HasUnsupportedMetadata: false } method) - { - method.Construct(ImmutableArray.Create(TypeWithAnnotations.Create(collectionExpr.Type), elementField.TypeWithAnnotations)). - CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(this.Compilation, this.Conversions, collectionExpr.Syntax.GetLocation(), diagnostics)); - } + CheckInlineArrayTypeIsSupported(collectionExpr.Syntax, collectionExpr.Type, elementField.Type, diagnostics); } return result; @@ -1069,6 +1065,12 @@ private EnumeratorResult SatisfiesIEnumerableInterfaces(SyntaxNode collectionSyn Debug.Assert((object)builder.CollectionType != null); NamedTypeSymbol collectionType = (NamedTypeSymbol)builder.CollectionType; + + if (unwrappedCollectionExprType.IsRefLikeOrAllowsRefLikeType()) + { + builder.CollectionType = unwrappedCollectionExprType; + } + if (collectionType.IsGenericType) { // If the type is generic, we have to search for the methods @@ -1188,14 +1190,12 @@ private void GetDisposalInfoForEnumerator(SyntaxNode syntax, ref ForEachEnumerat // is potentially disposable. TypeSymbol enumeratorType = builder.GetEnumeratorInfo.Method.ReturnType; - CompoundUseSiteInfo useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); - MethodSymbol patternDisposeMethod = null; if (enumeratorType.IsRefLikeType || isAsync) { // we throw away any binding diagnostics, and assume it's not disposable if we encounter errors var receiver = new BoundDisposableValuePlaceholder(syntax, enumeratorType); - patternDisposeMethod = TryFindDisposePatternMethod(receiver, syntax, isAsync, BindingDiagnosticBag.Discarded, out bool expanded); + MethodSymbol patternDisposeMethod = TryFindDisposePatternMethod(receiver, syntax, isAsync, BindingDiagnosticBag.Discarded, out bool expanded); if (patternDisposeMethod is object) { Debug.Assert(!patternDisposeMethod.IsExtensionMethod); @@ -1226,22 +1226,51 @@ private void GetDisposalInfoForEnumerator(SyntaxNode syntax, ref ForEachEnumerat // We already checked feature availability for async scenarios CheckFeatureAvailability(expr.Syntax, MessageID.IDS_FeatureDisposalPattern, diagnostics); } + + return; } } - if (!enumeratorType.IsRefLikeType && patternDisposeMethod is null) + if (implementsInterface(enumeratorType, isAsync, diagnostics)) { - // If it wasn't pattern-disposable, see if it's directly convertable to IDisposable - // For async foreach, we don't do the runtime check in unsealed case - if ((!enumeratorType.IsSealed && !isAsync) || - this.Conversions.ClassifyImplicitConversionFromType(enumeratorType, - isAsync ? this.Compilation.GetWellKnownType(WellKnownType.System_IAsyncDisposable) : this.Compilation.GetSpecialType(SpecialType.System_IDisposable), - ref useSiteInfo).IsImplicit) + builder.NeedsDisposal = true; + return; + } + + if (!enumeratorType.IsSealed && !isAsync) // For async foreach, we don't do the runtime check in unsealed case + { + Debug.Assert(!enumeratorType.IsRefLikeType); // Ref like types are supposed to be structs, therefore, sealed. + + if (enumeratorType is TypeParameterSymbol { AllowsRefLikeType: true }) + { + Error(diagnostics, ErrorCode.ERR_BadAllowByRefLikeEnumerator, expr.Syntax, enumeratorType); + } + else { builder.NeedsDisposal = true; } + } + + bool implementsInterface(TypeSymbol enumeratorType, bool isAsync, BindingDiagnosticBag diagnostics) + { + CompoundUseSiteInfo useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); + + NamedTypeSymbol targetInterface = isAsync ? this.Compilation.GetWellKnownType(WellKnownType.System_IAsyncDisposable) : this.Compilation.GetSpecialType(SpecialType.System_IDisposable); + + bool result = this.Conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(enumeratorType, + targetInterface, + ref useSiteInfo, + out bool needSupportForRefStructInterfaces); diagnostics.Add(syntax, useSiteInfo); + + if (needSupportForRefStructInterfaces && + enumeratorType.ContainingModule != Compilation.SourceModule) + { + CheckFeatureAvailability(syntax, MessageID.IDS_FeatureRefStructInterfaces, diagnostics); + } + + return result; } } @@ -1725,7 +1754,7 @@ private bool AllInterfacesContainsIEnumerable( out bool foundMultiple) { CompoundUseSiteInfo useSiteInfo = GetNewCompoundUseSiteInfo(diagnostics); - NamedTypeSymbol implementedIEnumerable = GetIEnumerableOfT(type, isAsync, Compilation, ref useSiteInfo, out foundMultiple); + NamedTypeSymbol implementedIEnumerable = GetIEnumerableOfT(type, isAsync, Compilation, ref useSiteInfo, out foundMultiple, out bool needSupportForRefStructInterfaces); // Prefer generic to non-generic, unless it is inaccessible. if (((object)implementedIEnumerable == null) || !this.IsAccessible(implementedIEnumerable, ref useSiteInfo)) @@ -1735,24 +1764,28 @@ private bool AllInterfacesContainsIEnumerable( if (!isAsync) { var implementedNonGeneric = this.Compilation.GetSpecialType(SpecialType.System_Collections_IEnumerable); - if ((object)implementedNonGeneric != null) + if ((object)implementedNonGeneric != null && + this.Conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(type, implementedNonGeneric, ref useSiteInfo, out needSupportForRefStructInterfaces)) { - var conversion = this.Conversions.ClassifyImplicitConversionFromType(type, implementedNonGeneric, ref useSiteInfo); - if (conversion.IsImplicit) - { - implementedIEnumerable = implementedNonGeneric; - } + implementedIEnumerable = implementedNonGeneric; } } } + if (implementedIEnumerable is not null && needSupportForRefStructInterfaces && type.ContainingModule != Compilation.SourceModule) + { + CheckFeatureAvailability(collectionSyntax, MessageID.IDS_FeatureRefStructInterfaces, diagnostics); + } + diagnostics.Add(collectionSyntax, useSiteInfo); builder.CollectionType = implementedIEnumerable; return (object)implementedIEnumerable != null; } - internal static NamedTypeSymbol GetIEnumerableOfT(TypeSymbol type, bool isAsync, CSharpCompilation compilation, ref CompoundUseSiteInfo useSiteInfo, out bool foundMultiple) + internal static NamedTypeSymbol GetIEnumerableOfT( + TypeSymbol type, bool isAsync, CSharpCompilation compilation, ref CompoundUseSiteInfo useSiteInfo, + out bool foundMultiple, out bool needSupportForRefStructInterfaces) { NamedTypeSymbol implementedIEnumerable = null; foundMultiple = false; @@ -1760,12 +1793,14 @@ internal static NamedTypeSymbol GetIEnumerableOfT(TypeSymbol type, bool isAsync, if (type.TypeKind == TypeKind.TypeParameter) { var typeParameter = (TypeParameterSymbol)type; + needSupportForRefStructInterfaces = typeParameter.AllowsRefLikeType; var allInterfaces = typeParameter.EffectiveBaseClass(ref useSiteInfo).AllInterfacesWithDefinitionUseSiteDiagnostics(ref useSiteInfo) .Concat(typeParameter.AllEffectiveInterfacesWithDefinitionUseSiteDiagnostics(ref useSiteInfo)); GetIEnumerableOfT(allInterfaces, isAsync, compilation, ref @implementedIEnumerable, ref foundMultiple); } else { + needSupportForRefStructInterfaces = type.IsRefLikeType; GetIEnumerableOfT(type.AllInterfacesWithDefinitionUseSiteDiagnostics(ref useSiteInfo), isAsync, compilation, ref @implementedIEnumerable, ref foundMultiple); } diff --git a/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs b/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs index 0695fe3f94395..1e6ee6bfc4953 100644 --- a/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs +++ b/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs @@ -416,7 +416,9 @@ public override void VisitLocalFunctionStatement(LocalFunctionStatementSyntax no ? new WithMethodTypeParametersBinder(match, _enclosing) : _enclosing; - binder = binder.WithUnsafeRegionIfNecessary(node.Modifiers); + binder = binder.SetOrClearUnsafeRegionIfNecessary(node.Modifiers, + isIteratorBody: match.IsIterator); + binder = new InMethodBinder(match, binder); } diff --git a/src/Compilers/CSharp/Portable/Binder/LockBinder.cs b/src/Compilers/CSharp/Portable/Binder/LockBinder.cs index c29d038662a25..0899da0cfdb69 100644 --- a/src/Compilers/CSharp/Portable/Binder/LockBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/LockBinder.cs @@ -64,13 +64,6 @@ internal override BoundStatement BindLockStatementParts(BindingDiagnosticBag dia _ = diagnostics.ReportUseSite(lockTypeInfo.EnterScopeMethod, exprSyntax) || diagnostics.ReportUseSite(lockTypeInfo.ScopeType, exprSyntax) || diagnostics.ReportUseSite(lockTypeInfo.ScopeDisposeMethod, exprSyntax); - - CheckRestrictedTypeInAsyncMethod( - originalBinder.ContainingMemberOrLambda, - lockTypeInfo.ScopeType, - diagnostics, - exprSyntax, - errorCode: ErrorCode.ERR_BadSpecialByRefLock); } BoundStatement stmt = originalBinder.BindPossibleEmbeddedStatement(_syntax.Statement, diagnostics); diff --git a/src/Compilers/CSharp/Portable/Binder/RefSafetyAnalysis.cs b/src/Compilers/CSharp/Portable/Binder/RefSafetyAnalysis.cs index 04ac043860e7d..44f2e3406ca1a 100644 --- a/src/Compilers/CSharp/Portable/Binder/RefSafetyAnalysis.cs +++ b/src/Compilers/CSharp/Portable/Binder/RefSafetyAnalysis.cs @@ -501,7 +501,7 @@ private void RemoveLocalScopes(LocalSymbol local) Debug.Assert(localSymbol.RefKind == RefKind.None || refEscapeScope >= GetRefEscape(initializer, _localScopeDepth)); - if (node.DeclaredTypeOpt?.Type.IsRefLikeType == true) + if (node.DeclaredTypeOpt?.Type.IsRefLikeOrAllowsRefLikeType() == true) { ValidateEscape(initializer, valEscapeScope, isByRef: false, _diagnostics); } @@ -578,7 +578,10 @@ private void RemoveLocalScopes(LocalSymbol local) static uint getDeclarationValEscape(BoundTypeExpression typeExpression, uint valEscape) { - return typeExpression.Type.IsRefLikeType ? valEscape : CallingMethodScope; + // https://github.com/dotnet/roslyn/issues/73551: + // We do not have a test that demonstrates the statement below makes a difference + // for ref like types. If 'CallingMethodScope' is always returned, not a single test fails. + return typeExpression.Type.IsRefLikeOrAllowsRefLikeType() ? valEscape : CallingMethodScope; } } @@ -603,7 +606,7 @@ static uint getPositionalValEscape(Symbol? symbol, uint valEscape) { return symbol is null ? valEscape - : symbol.GetTypeOrReturnType().IsRefLikeType() ? valEscape : CallingMethodScope; + : symbol.GetTypeOrReturnType().IsRefLikeOrAllowsRefLikeType() ? valEscape : CallingMethodScope; } } @@ -616,7 +619,7 @@ static uint getMemberValEscape(BoundPropertySubpatternMember? member, uint valEs { if (member is null) return valEscape; valEscape = getMemberValEscape(member.Receiver, valEscape); - return member.Type.IsRefLikeType ? valEscape : CallingMethodScope; + return member.Type.IsRefLikeOrAllowsRefLikeType() ? valEscape : CallingMethodScope; } } diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs index 1a38dcee394ba..28c1c79ac1461 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs @@ -2829,7 +2829,8 @@ public bool HasImplicitTypeParameterConversion(TypeParameterSymbol source, TypeS return true; } - if ((destination.TypeKind == TypeKind.TypeParameter) && + if (destination is TypeParameterSymbol { AllowsRefLikeType: false } && + !source.AllowsRefLikeType && source.DependsOn((TypeParameterSymbol)destination)) { return true; @@ -2848,6 +2849,11 @@ private bool HasImplicitReferenceTypeParameterConversion(TypeParameterSymbol sou return false; // Not a reference conversion. } + if (source.AllowsRefLikeType) + { + return false; + } + // The following implicit conversions exist for a given type parameter T: // // * From T to its effective base class C. @@ -2866,7 +2872,7 @@ private bool HasImplicitReferenceTypeParameterConversion(TypeParameterSymbol sou } // * From T to a type parameter U, provided T depends on U. - if ((destination.TypeKind == TypeKind.TypeParameter) && + if (destination is TypeParameterSymbol { AllowsRefLikeType: false } && source.DependsOn((TypeParameterSymbol)destination)) { return true; @@ -2901,6 +2907,11 @@ private bool HasImplicitEffectiveBaseConversion(TypeParameterSymbol source, Type } private bool HasImplicitEffectiveInterfaceSetConversion(TypeParameterSymbol source, TypeSymbol destination, ref CompoundUseSiteInfo useSiteInfo) + { + return HasVarianceCompatibleInterfaceInEffectiveInterfaceSet(source, destination, ref useSiteInfo); + } + + private bool HasVarianceCompatibleInterfaceInEffectiveInterfaceSet(TypeParameterSymbol source, TypeSymbol destination, ref CompoundUseSiteInfo useSiteInfo) { if (!destination.IsInterfaceType()) { @@ -2921,6 +2932,11 @@ private bool HasImplicitEffectiveInterfaceSetConversion(TypeParameterSymbol sour } private bool HasAnyBaseInterfaceConversion(TypeSymbol derivedType, TypeSymbol baseType, ref CompoundUseSiteInfo useSiteInfo) + { + return ImplementsVarianceCompatibleInterface(derivedType, baseType, ref useSiteInfo); + } + + private bool ImplementsVarianceCompatibleInterface(TypeSymbol derivedType, TypeSymbol baseType, ref CompoundUseSiteInfo useSiteInfo) { Debug.Assert((object)derivedType != null); Debug.Assert((object)baseType != null); @@ -2946,6 +2962,65 @@ private bool HasAnyBaseInterfaceConversion(TypeSymbol derivedType, TypeSymbol ba return false; } + internal bool ImplementsVarianceCompatibleInterface(NamedTypeSymbol derivedType, TypeSymbol baseType, ref CompoundUseSiteInfo useSiteInfo) + { + return ImplementsVarianceCompatibleInterface((TypeSymbol)derivedType, baseType, ref useSiteInfo); + } + + internal bool HasImplicitConversionToOrImplementsVarianceCompatibleInterface(TypeSymbol typeToCheck, NamedTypeSymbol targetInterfaceType, ref CompoundUseSiteInfo useSiteInfo, out bool needSupportForRefStructInterfaces) + { + Debug.Assert(targetInterfaceType.IsErrorType() || targetInterfaceType.IsInterface); + + if (ClassifyImplicitConversionFromType(typeToCheck, targetInterfaceType, ref useSiteInfo).IsImplicit) + { + needSupportForRefStructInterfaces = false; + return true; + } + + if (IsRefLikeOrAllowsRefLikeTypeImplementingVarianceCompatibleInterface(typeToCheck, targetInterfaceType, ref useSiteInfo)) + { + needSupportForRefStructInterfaces = true; + return true; + } + + needSupportForRefStructInterfaces = false; + return false; + } + + private bool IsRefLikeOrAllowsRefLikeTypeImplementingVarianceCompatibleInterface(TypeSymbol typeToCheck, NamedTypeSymbol targetInterfaceType, ref CompoundUseSiteInfo useSiteInfo) + { + if (typeToCheck is TypeParameterSymbol typeParameter) + { + return typeParameter.AllowsRefLikeType && HasVarianceCompatibleInterfaceInEffectiveInterfaceSet(typeParameter, targetInterfaceType, ref useSiteInfo); + } + else if (typeToCheck.IsRefLikeType) + { + return ImplementsVarianceCompatibleInterface(typeToCheck, targetInterfaceType, ref useSiteInfo); + } + + return false; + } + + internal bool HasImplicitConversionToOrImplementsVarianceCompatibleInterface(BoundExpression expressionToCheck, NamedTypeSymbol targetInterfaceType, ref CompoundUseSiteInfo useSiteInfo, out bool needSupportForRefStructInterfaces) + { + Debug.Assert(targetInterfaceType.IsErrorType() || targetInterfaceType.IsInterface); + + if (ClassifyImplicitConversionFromExpression(expressionToCheck, targetInterfaceType, ref useSiteInfo).IsImplicit) + { + needSupportForRefStructInterfaces = false; + return true; + } + + if (expressionToCheck.Type is TypeSymbol typeToCheck && IsRefLikeOrAllowsRefLikeTypeImplementingVarianceCompatibleInterface(typeToCheck, targetInterfaceType, ref useSiteInfo)) + { + needSupportForRefStructInterfaces = true; + return true; + } + + needSupportForRefStructInterfaces = false; + return false; + } + //////////////////////////////////////////////////////////////////////////////// // The rules for variant interface and delegate conversions are the same: // @@ -3151,6 +3226,11 @@ private bool HasImplicitBoxingTypeParameterConversion(TypeParameterSymbol source return false; // Not a boxing conversion; both source and destination are references. } + if (source.AllowsRefLikeType) + { + return false; + } + // The following implicit conversions exist for a given type parameter T: // // * From T to its effective base class C. @@ -3169,8 +3249,8 @@ private bool HasImplicitBoxingTypeParameterConversion(TypeParameterSymbol source } // SPEC: From T to a type parameter U, provided T depends on U - if ((destination.TypeKind == TypeKind.TypeParameter) && - source.DependsOn((TypeParameterSymbol)destination)) + if (destination is TypeParameterSymbol { AllowsRefLikeType: false } d && + source.DependsOn(d)) { return true; } @@ -3424,6 +3504,11 @@ private bool HasExplicitReferenceTypeParameterConversion(TypeSymbol source, Type TypeParameterSymbol s = source as TypeParameterSymbol; TypeParameterSymbol t = destination as TypeParameterSymbol; + if (s?.AllowsRefLikeType == true || t?.AllowsRefLikeType == true) + { + return false; + } + // SPEC: The following explicit conversions exist for a given type parameter T: // SPEC: If T is known to be a reference type, the conversions are all classified as explicit reference conversions. @@ -3471,6 +3556,11 @@ private bool HasUnboxingTypeParameterConversion(TypeSymbol source, TypeSymbol de TypeParameterSymbol s = source as TypeParameterSymbol; TypeParameterSymbol t = destination as TypeParameterSymbol; + if (s?.AllowsRefLikeType == true || t?.AllowsRefLikeType == true) + { + return false; + } + // SPEC: The following explicit conversions exist for a given type parameter T: // SPEC: If T is known to be a reference type, the conversions are all classified as explicit reference conversions. diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs index 4f85925b77db2..ab9b9436f10ae 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorOverloadResolution.cs @@ -716,6 +716,25 @@ private void GetAllBuiltInOperators(BinaryOperatorKind kind, bool isChecked, Bou // is not a string or delegate) we do not check any other operators. This patches // what is otherwise a flaw in the language specification. See 11426. GetReferenceEquality(kind, operators); + Debug.Assert(operators.Count == 1); + + if ((left.Type is TypeParameterSymbol { AllowsRefLikeType: true } && right.IsLiteralNull()) || + (right.Type is TypeParameterSymbol { AllowsRefLikeType: true } && left.IsLiteralNull())) + { + BinaryOperatorSignature op = operators[0]; + Debug.Assert(op.LeftType.IsObjectType()); + Debug.Assert(op.RightType.IsObjectType()); + + var convLeft = getOperandConversionForAllowByRefLikeNullCheck(isChecked, left, op.LeftType, ref useSiteInfo); + var convRight = getOperandConversionForAllowByRefLikeNullCheck(isChecked, right, op.RightType, ref useSiteInfo); + + Debug.Assert(convLeft.IsImplicit); + Debug.Assert(convRight.IsImplicit); + + results.Add(BinaryOperatorAnalysisResult.Applicable(op, convLeft, convRight)); + operators.Free(); + return; + } } else { @@ -754,6 +773,11 @@ static bool isUtf8ByteRepresentation(BoundExpression value) { return value is BoundUtf8String or BoundBinaryOperator { OperatorKind: BinaryOperatorKind.Utf8Addition }; } + + Conversion getOperandConversionForAllowByRefLikeNullCheck(bool isChecked, BoundExpression operand, TypeSymbol objectType, ref CompoundUseSiteInfo useSiteInfo) + { + return (operand.Type is TypeParameterSymbol { AllowsRefLikeType: true }) ? Conversion.Boxing : Conversions.ClassifyConversionFromExpression(operand, objectType, isChecked: isChecked, ref useSiteInfo); + } } private void GetReferenceEquality(BinaryOperatorKind kind, ArrayBuilder operators) diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MemberAnalysisResult.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MemberAnalysisResult.cs index f0a6c46065c3a..d60aa1ae31254 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MemberAnalysisResult.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/MemberAnalysisResult.cs @@ -105,6 +105,7 @@ private init public readonly int BadParameter; public readonly MemberResolutionKind Kind; + public readonly TypeWithAnnotations DefinitionParamsElementTypeOpt; public readonly TypeWithAnnotations ParamsElementTypeOpt; /// @@ -121,11 +122,14 @@ private MemberAnalysisResult( int missingParameter = -1, bool hasAnyRefOmittedArgument = false, ImmutableArray constraintFailureDiagnosticsOpt = default, + TypeWithAnnotations definitionParamsElementTypeOpt = default, TypeWithAnnotations paramsElementTypeOpt = default) { + Debug.Assert(kind != MemberResolutionKind.ApplicableInExpandedForm || definitionParamsElementTypeOpt.HasType); Debug.Assert(kind != MemberResolutionKind.ApplicableInExpandedForm || paramsElementTypeOpt.HasType); this.Kind = kind; + this.DefinitionParamsElementTypeOpt = definitionParamsElementTypeOpt; this.ParamsElementTypeOpt = paramsElementTypeOpt; this.BadArgumentsOpt = badArgumentsOpt; this.ArgsToParamsOpt = argsToParamsOpt; @@ -314,7 +318,7 @@ public static MemberAnalysisResult UnsupportedMetadata() return new MemberAnalysisResult(MemberResolutionKind.UnsupportedMetadata); } - public static MemberAnalysisResult BadArgumentConversions(ImmutableArray argsToParamsOpt, BitVector badArguments, ImmutableArray conversions, TypeWithAnnotations paramsElementTypeOpt) + public static MemberAnalysisResult BadArgumentConversions(ImmutableArray argsToParamsOpt, BitVector badArguments, ImmutableArray conversions, TypeWithAnnotations definitionParamsElementTypeOpt, TypeWithAnnotations paramsElementTypeOpt) { Debug.Assert(conversions.Length != 0); Debug.Assert(badArguments.TrueBits().Any()); @@ -323,6 +327,7 @@ public static MemberAnalysisResult BadArgumentConversions(ImmutableArray ar badArguments, argsToParamsOpt, conversions, + definitionParamsElementTypeOpt: definitionParamsElementTypeOpt, paramsElementTypeOpt: paramsElementTypeOpt); } @@ -373,9 +378,11 @@ public static MemberAnalysisResult NormalForm(ImmutableArray argsToParamsOp return new MemberAnalysisResult(MemberResolutionKind.ApplicableInNormalForm, BitVector.Null, argsToParamsOpt, conversions, hasAnyRefOmittedArgument: hasAnyRefOmittedArgument); } - public static MemberAnalysisResult ExpandedForm(ImmutableArray argsToParamsOpt, ImmutableArray conversions, bool hasAnyRefOmittedArgument, TypeWithAnnotations paramsElementType) + public static MemberAnalysisResult ExpandedForm(ImmutableArray argsToParamsOpt, ImmutableArray conversions, bool hasAnyRefOmittedArgument, TypeWithAnnotations definitionParamsElementType, TypeWithAnnotations paramsElementType) { - return new MemberAnalysisResult(MemberResolutionKind.ApplicableInExpandedForm, BitVector.Null, argsToParamsOpt, conversions, hasAnyRefOmittedArgument: hasAnyRefOmittedArgument, paramsElementTypeOpt: paramsElementType); + return new MemberAnalysisResult( + MemberResolutionKind.ApplicableInExpandedForm, BitVector.Null, argsToParamsOpt, conversions, + hasAnyRefOmittedArgument: hasAnyRefOmittedArgument, definitionParamsElementTypeOpt: definitionParamsElementType, paramsElementTypeOpt: paramsElementType); } public static MemberAnalysisResult Worse() diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs index 385db1686b016..5acde0dfa8f0a 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution.cs @@ -817,9 +817,9 @@ private void AddConstructorToCandidateSet(MethodSymbol constructor, ArrayBuilder var result = normalResult; if (!normalResult.IsValid) { - if (IsValidParams(_binder, constructor)) + if (IsValidParams(_binder, constructor, out TypeWithAnnotations definitionElementType)) { - var expandedResult = IsConstructorApplicableInExpandedForm(constructor, arguments, completeResults, ref useSiteInfo); + var expandedResult = IsConstructorApplicableInExpandedForm(constructor, arguments, definitionElementType, completeResults, ref useSiteInfo); if (expandedResult.IsValid || completeResults) { result = expandedResult; @@ -864,6 +864,7 @@ private MemberAnalysisResult IsConstructorApplicableInNormalForm( return IsApplicable( constructor, effectiveParameters, + definitionParamsElementTypeOpt: default, isExpanded: false, arguments, argumentAnalysis.ArgsToParamsOpt, @@ -878,6 +879,7 @@ private MemberAnalysisResult IsConstructorApplicableInNormalForm( private MemberAnalysisResult IsConstructorApplicableInExpandedForm( MethodSymbol constructor, AnalyzedArguments arguments, + TypeWithAnnotations definitionParamsElementType, bool completeResults, ref CompoundUseSiteInfo useSiteInfo) { @@ -906,6 +908,7 @@ private MemberAnalysisResult IsConstructorApplicableInExpandedForm( var result = IsApplicable( constructor, effectiveParameters, + definitionParamsElementTypeOpt: definitionParamsElementType, isExpanded: true, arguments, argumentAnalysis.ArgsToParamsOpt, @@ -1038,7 +1041,7 @@ private void AddMemberToCandidateSet( // Second, we need to determine if the method is applicable in its normal form or its expanded form. - var normalResult = ((options & Options.IgnoreNormalFormIfHasValidParamsParameter) != 0 && IsValidParams(_binder, leastOverriddenMember)) + var normalResult = ((options & Options.IgnoreNormalFormIfHasValidParamsParameter) != 0 && IsValidParams(_binder, leastOverriddenMember, out _)) ? default(MemberResolutionResult) : IsMemberApplicableInNormalForm( member, @@ -1057,13 +1060,14 @@ private void AddMemberToCandidateSet( // tricks you can pull to make overriding methods [indexers] inconsistent with overridden // methods [indexers] (or implementing methods [indexers] inconsistent with interfaces). - if ((options & Options.IsMethodGroupConversion) == 0 && IsValidParams(_binder, leastOverriddenMember)) + if ((options & Options.IsMethodGroupConversion) == 0 && IsValidParams(_binder, leastOverriddenMember, out TypeWithAnnotations definitionElementType)) { var expandedResult = IsMemberApplicableInExpandedForm( member, leastOverriddenMember, typeArguments, arguments, + definitionElementType, allowRefOmittedArguments: (options & Options.AllowRefOmittedArguments) != 0, completeResults: completeResults, dynamicConvertsToAnything: (options & Options.DynamicConvertsToAnything) != 0, @@ -1156,17 +1160,19 @@ static bool haveBadArgumentForLastParameter(MemberResolutionResult resu // We need to know if this is a valid formal parameter list with a parameter array // as the final formal parameter. We might be in an error recovery scenario // where the params array is not an array type. - public static bool IsValidParams(Binder binder, Symbol member) + public static bool IsValidParams(Binder binder, Symbol member, out TypeWithAnnotations definitionElementType) { // A varargs method is never a valid params method. if (member.GetIsVararg()) { + definitionElementType = default; return false; } int paramCount = member.GetParameterCount(); if (paramCount == 0) { + definitionElementType = default; return false; } @@ -1175,9 +1181,10 @@ public static bool IsValidParams(Binder binder, Symbol member) (final.IsParamsCollection && !final.Type.IsSZArray() && (binder.Compilation.LanguageVersion > LanguageVersion.CSharp12 || member.ContainingModule == binder.Compilation.SourceModule))) { - return TryInferParamsCollectionIterationType(binder, final.OriginalDefinition.Type, out _); + return TryInferParamsCollectionIterationType(binder, final.OriginalDefinition.Type, out definitionElementType); } + definitionElementType = default; return false; } @@ -1837,25 +1844,6 @@ private void RemoveWorseMembers(ArrayBuilder - /// Returns the parameter type (considering params). - /// - private static TypeSymbol GetParameterType(ParameterSymbol parameter, MemberAnalysisResult result, int parameterCount) - { - var type = parameter.Type; - if (result.Kind == MemberResolutionKind.ApplicableInExpandedForm && - parameter.Ordinal == parameterCount - 1) - { - Debug.Assert(result.ParamsElementTypeOpt.HasType); - Debug.Assert(result.ParamsElementTypeOpt.Type != (object)ErrorTypeSymbol.EmptyParamsCollectionElementTypeSentinel); - return result.ParamsElementTypeOpt.Type; - } - else - { - return type; - } - } - /// /// Returns the parameter corresponding to the given argument index. /// @@ -1955,11 +1943,9 @@ private BetterResult BetterFunctionMember( continue; } - var parameter1 = GetParameter(i, m1.Result, m1LeastOverriddenParameters); - var type1 = GetParameterType(parameter1, m1.Result, m1LeastOverriddenParameters.Length); + var type1 = getParameterTypeAndRefKind(i, m1.Result, m1LeastOverriddenParameters, m1.Result.ParamsElementTypeOpt, out RefKind parameter1RefKind); - var parameter2 = GetParameter(i, m2.Result, m2LeastOverriddenParameters); - var type2 = GetParameterType(parameter2, m2.Result, m2LeastOverriddenParameters.Length); + var type2 = getParameterTypeAndRefKind(i, m2.Result, m2LeastOverriddenParameters, m2.Result.ParamsElementTypeOpt, out RefKind parameter2RefKind); bool okToDowngradeToNeither; BetterResult r; @@ -1967,10 +1953,10 @@ private BetterResult BetterFunctionMember( r = BetterConversionFromExpression(arguments[i], type1, m1.Result.ConversionForArg(i), - parameter1.RefKind, + parameter1RefKind, type2, m2.Result.ConversionForArg(i), - parameter2.RefKind, + parameter2RefKind, considerRefKinds, ref useSiteInfo, out okToDowngradeToNeither); @@ -2099,11 +2085,9 @@ private BetterResult BetterFunctionMember( continue; } - var parameter1 = GetParameter(i, m1.Result, m1LeastOverriddenParameters); - var type1 = GetParameterType(parameter1, m1.Result, m1LeastOverriddenParameters.Length); + var type1 = getParameterTypeAndRefKind(i, m1.Result, m1LeastOverriddenParameters, m1.Result.ParamsElementTypeOpt, out _); - var parameter2 = GetParameter(i, m2.Result, m2LeastOverriddenParameters); - var type2 = GetParameterType(parameter2, m2.Result, m2LeastOverriddenParameters.Length); + var type2 = getParameterTypeAndRefKind(i, m2.Result, m2LeastOverriddenParameters, m2.Result.ParamsElementTypeOpt, out _); var type1Normalized = type1; var type2Normalized = type2; @@ -2248,8 +2232,8 @@ private BetterResult BetterFunctionMember( using (var uninst1 = TemporaryArray.Empty) using (var uninst2 = TemporaryArray.Empty) { - var m1Original = m1.LeastOverriddenMember.OriginalDefinition.GetParameters(); - var m2Original = m2.LeastOverriddenMember.OriginalDefinition.GetParameters(); + var m1DefinitionParameters = m1.LeastOverriddenMember.OriginalDefinition.GetParameters(); + var m2DefinitionParameters = m2.LeastOverriddenMember.OriginalDefinition.GetParameters(); for (i = 0; i < arguments.Count; ++i) { // If these are both applicable varargs methods and we're looking at the __arglist argument @@ -2261,11 +2245,9 @@ private BetterResult BetterFunctionMember( continue; } - var parameter1 = GetParameter(i, m1.Result, m1Original); - uninst1.Add(GetParameterType(parameter1, m1.Result, m1Original.Length)); + uninst1.Add(getParameterTypeAndRefKind(i, m1.Result, m1DefinitionParameters, m1.Result.DefinitionParamsElementTypeOpt, out _)); - var parameter2 = GetParameter(i, m2.Result, m2Original); - uninst2.Add(GetParameterType(parameter2, m2.Result, m2Original.Length)); + uninst2.Add(getParameterTypeAndRefKind(i, m2.Result, m2DefinitionParameters, m2.Result.DefinitionParamsElementTypeOpt, out _)); } result = MoreSpecificType(ref uninst1.AsRef(), ref uninst2.AsRef(), ref useSiteInfo); @@ -2353,6 +2335,26 @@ private BetterResult BetterFunctionMember( } return BetterResult.Neither; + + // Returns the parameter type (considering params). + static TypeSymbol getParameterTypeAndRefKind(int i, MemberAnalysisResult result, ImmutableArray parameters, TypeWithAnnotations paramsElementTypeOpt, out RefKind parameter1RefKind) + { + var parameter = GetParameter(i, result, parameters); + parameter1RefKind = parameter.RefKind; + + var type = parameter.Type; + if (result.Kind == MemberResolutionKind.ApplicableInExpandedForm && + parameter.Ordinal == parameters.Length - 1) + { + Debug.Assert(paramsElementTypeOpt.HasType); + Debug.Assert(paramsElementTypeOpt.Type != (object)ErrorTypeSymbol.EmptyParamsCollectionElementTypeSentinel); + return paramsElementTypeOpt.Type; + } + else + { + return type; + } + } } /// @@ -3691,7 +3693,7 @@ private MemberResolutionResult IsMemberApplicableInNormalForm( TMember leastOverriddenMemberConstructedFrom = GetConstructedFrom(leastOverriddenMember); bool hasAnyRefOmittedArgument; - EffectiveParameters originalEffectiveParameters = GetEffectiveParametersInNormalForm( + EffectiveParameters constructedFromEffectiveParameters = GetEffectiveParametersInNormalForm( leastOverriddenMemberConstructedFrom, arguments.Arguments.Count, argumentAnalysis.ArgsToParamsOpt, @@ -3706,7 +3708,8 @@ private MemberResolutionResult IsMemberApplicableInNormalForm( // The applicability is checked based on effective parameters passed in. var applicableResult = IsApplicable( member, leastOverriddenMemberConstructedFrom, - typeArguments, arguments, originalEffectiveParameters, + typeArguments, arguments, constructedFromEffectiveParameters, + definitionParamsElementTypeOpt: default, isExpanded: false, argumentAnalysis.ArgsToParamsOpt, hasAnyRefOmittedArgument: hasAnyRefOmittedArgument, @@ -3730,6 +3733,7 @@ private MemberResolutionResult IsMemberApplicableInExpandedForm typeArguments, AnalyzedArguments arguments, + TypeWithAnnotations definitionParamsElementType, bool allowRefOmittedArguments, bool completeResults, bool dynamicConvertsToAnything, @@ -3754,7 +3758,7 @@ private MemberResolutionResult IsMemberApplicableInExpandedForm IsMemberApplicableInExpandedForm IsApplicable( TMember leastOverriddenMember, // method or property ArrayBuilder typeArgumentsBuilder, AnalyzedArguments arguments, - EffectiveParameters originalEffectiveParameters, + EffectiveParameters constructedFromEffectiveParameters, + TypeWithAnnotations definitionParamsElementTypeOpt, bool isExpanded, ImmutableArray argsToParamsMap, bool hasAnyRefOmittedArgument, @@ -3836,7 +3842,7 @@ private MemberResolutionResult IsApplicable( typeArguments = InferMethodTypeArguments(method, leastOverriddenMethod.ConstructedFrom.TypeParameters, arguments, - originalEffectiveParameters, + constructedFromEffectiveParameters, out hasTypeArgumentsInferredFromFunctionType, out inferenceError, ref useSiteInfo); @@ -3892,19 +3898,20 @@ private MemberResolutionResult IsApplicable( var map = new TypeMap(leastOverriddenMethod.TypeParameters, typeArguments, allowAlpha: true); constructedEffectiveParameters = new EffectiveParameters( - map.SubstituteTypes(originalEffectiveParameters.ParameterTypes), - originalEffectiveParameters.ParameterRefKinds, - originalEffectiveParameters.FirstParamsElementIndex); + map.SubstituteTypes(constructedFromEffectiveParameters.ParameterTypes), + constructedFromEffectiveParameters.ParameterRefKinds, + constructedFromEffectiveParameters.FirstParamsElementIndex); } else { - constructedEffectiveParameters = originalEffectiveParameters; + constructedEffectiveParameters = constructedFromEffectiveParameters; ignoreOpenTypes = false; } var applicableResult = IsApplicable( member, constructedEffectiveParameters, + definitionParamsElementTypeOpt, isExpanded, arguments, argsToParamsMap, @@ -3975,6 +3982,7 @@ private ImmutableArray InferMethodTypeArguments( private MemberAnalysisResult IsApplicable( Symbol candidate, // method or property EffectiveParameters parameters, + TypeWithAnnotations definitionParamsElementTypeOpt, bool isExpanded, AnalyzedArguments arguments, ImmutableArray argsToParameters, @@ -4113,7 +4121,8 @@ private MemberAnalysisResult IsApplicable( // of overloads for the semantic model. Debug.Assert(badArguments.IsNull); Debug.Assert(conversions == null); - return MemberAnalysisResult.BadArgumentConversions(argsToParameters, MemberAnalysisResult.CreateBadArgumentsWithPosition(argumentPosition), ImmutableArray.Create(conversion), paramsElementTypeOpt); + return MemberAnalysisResult.BadArgumentConversions(argsToParameters, MemberAnalysisResult.CreateBadArgumentsWithPosition(argumentPosition), ImmutableArray.Create(conversion), + definitionParamsElementTypeOpt: definitionParamsElementTypeOpt, paramsElementTypeOpt: paramsElementTypeOpt); } if (!conversion.Exists) @@ -4148,12 +4157,16 @@ private MemberAnalysisResult IsApplicable( var conversionsArray = conversions != null ? conversions.ToImmutableAndFree() : default(ImmutableArray); if (!badArguments.IsNull) { - result = MemberAnalysisResult.BadArgumentConversions(argsToParameters, badArguments, conversionsArray, paramsElementTypeOpt); + result = MemberAnalysisResult.BadArgumentConversions(argsToParameters, badArguments, conversionsArray, + definitionParamsElementTypeOpt: definitionParamsElementTypeOpt, + paramsElementTypeOpt: paramsElementTypeOpt); } else if (isExpanded) { Debug.Assert(paramsElementTypeOpt.HasType); - result = MemberAnalysisResult.ExpandedForm(argsToParameters, conversionsArray, hasAnyRefOmittedArgument, paramsElementTypeOpt); + result = MemberAnalysisResult.ExpandedForm(argsToParameters, conversionsArray, hasAnyRefOmittedArgument, + definitionParamsElementType: definitionParamsElementTypeOpt, + paramsElementType: paramsElementTypeOpt); } else { diff --git a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution_ArgsToParameters.cs b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution_ArgsToParameters.cs index d5f3badcbd57c..3da8c76c13371 100644 --- a/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution_ArgsToParameters.cs +++ b/src/Compilers/CSharp/Portable/Binder/Semantics/OverloadResolution/OverloadResolution_ArgsToParameters.cs @@ -484,7 +484,7 @@ private static bool CanBeOptional(ParameterSymbol parameter, bool isMethodGroupC private static int? CheckForDuplicateNamedArgument(AnalyzedArguments arguments) { - if (arguments.Names.IsEmpty()) + if (arguments.Names.IsEmpty) { // No checks if there are no named arguments return null; diff --git a/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs b/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs index 775774fe0188c..8bf71321ff48f 100644 --- a/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/UsingStatementBinder.cs @@ -119,7 +119,7 @@ internal static BoundStatement BindUsingStatementOrDeclarationFromParts(SyntaxNo Debug.Assert(expressionOpt is not null); if (expressionOpt.Type is not null) { - CheckRestrictedTypeInAsyncMethod(originalBinder.ContainingMemberOrLambda, expressionOpt.Type, diagnostics, expressionOpt.Syntax, errorCode: ErrorCode.ERR_BadSpecialByRefUsing); + CheckRestrictedTypeInAsyncMethod(originalBinder.ContainingMemberOrLambda, expressionOpt.Type, diagnostics, expressionOpt.Syntax); } } else @@ -233,15 +233,12 @@ bool bindDisposable(bool fromExpression, out MethodArgumentInfo? patternDisposeI } // Interface binding - TypeSymbol disposableInterface = getDisposableInterface(hasAwait); + NamedTypeSymbol disposableInterface = getDisposableInterface(hasAwait); Debug.Assert((object)disposableInterface != null); - CompoundUseSiteInfo useSiteInfo = originalBinder.GetNewCompoundUseSiteInfo(diagnostics); - Conversion iDisposableConversion = classifyConversion(fromExpression, disposableInterface, ref useSiteInfo); - - diagnostics.Add(syntax, useSiteInfo); + bool implementsIDisposable = implementsInterface(fromExpression, disposableInterface, diagnostics); - if (iDisposableConversion.IsImplicit) + if (implementsIDisposable) { if (hasAwait) { @@ -254,12 +251,10 @@ bool bindDisposable(bool fromExpression, out MethodArgumentInfo? patternDisposeI if (type is null || !type.IsErrorType()) { // Retry with a different assumption about whether the `using` is async - TypeSymbol alternateInterface = getDisposableInterface(!hasAwait); - var discardedUseSiteInfo = CompoundUseSiteInfo.Discarded; - Conversion alternateConversion = classifyConversion(fromExpression, alternateInterface, ref discardedUseSiteInfo); + NamedTypeSymbol alternateInterface = getDisposableInterface(!hasAwait); + bool implementsAlternateIDisposable = implementsInterface(fromExpression, alternateInterface, BindingDiagnosticBag.Discarded); - bool wrongAsync = alternateConversion.IsImplicit; - ErrorCode errorCode = wrongAsync + ErrorCode errorCode = implementsAlternateIDisposable ? (hasAwait ? ErrorCode.ERR_NoConvToIAsyncDispWrongAsync : ErrorCode.ERR_NoConvToIDispWrongAsync) : (hasAwait ? ErrorCode.ERR_NoConvToIAsyncDisp : ErrorCode.ERR_NoConvToIDisp); @@ -269,28 +264,36 @@ bool bindDisposable(bool fromExpression, out MethodArgumentInfo? patternDisposeI return false; } - Conversion classifyConversion(bool fromExpression, TypeSymbol targetInterface, ref CompoundUseSiteInfo useSiteInfo) + bool implementsInterface(bool fromExpression, NamedTypeSymbol targetInterface, BindingDiagnosticBag diagnostics) { var conversions = originalBinder.Conversions; + CompoundUseSiteInfo useSiteInfo = originalBinder.GetNewCompoundUseSiteInfo(diagnostics); + bool result; + bool needSupportForRefStructInterfaces; + if (fromExpression) { Debug.Assert(expressionOpt is { }); - var result = conversions.ClassifyImplicitConversionFromExpression(expressionOpt, targetInterface, ref useSiteInfo); - - Debug.Assert(expressionOpt.Type?.IsDynamic() != true || result.Kind == ConversionKind.ImplicitDynamic); - return result; + result = conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(expressionOpt, targetInterface, ref useSiteInfo, out needSupportForRefStructInterfaces); } else { Debug.Assert(declarationTypeOpt is { }); - var result = conversions.ClassifyImplicitConversionFromType(declarationTypeOpt, targetInterface, ref useSiteInfo); + result = conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(declarationTypeOpt, targetInterface, ref useSiteInfo, out needSupportForRefStructInterfaces); + } + + diagnostics.Add(syntax, useSiteInfo); - Debug.Assert(!declarationTypeOpt.IsDynamic() || result.Kind == ConversionKind.ImplicitDynamic); - return result; + if (needSupportForRefStructInterfaces && + (fromExpression ? expressionOpt!.Type : declarationTypeOpt)!.ContainingModule != originalBinder.Compilation.SourceModule) + { + CheckFeatureAvailability(syntax, MessageID.IDS_FeatureRefStructInterfaces, diagnostics); } + + return result; } - TypeSymbol getDisposableInterface(bool isAsync) + NamedTypeSymbol getDisposableInterface(bool isAsync) { return isAsync ? originalBinder.Compilation.GetWellKnownType(WellKnownType.System_IAsyncDisposable) diff --git a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs index 9162afc9abc12..1447dff19215c 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs @@ -669,7 +669,7 @@ private static TypeWithAnnotations DelegateReturnTypeWithAnnotations(MethodSymbo getEffectiveScopeFromSymbol = true; } } - else if (type.IsRefLikeType() && ParameterSyntax(i)?.Modifiers.Any(SyntaxKind.ParamsKeyword) == true) + else if (type.IsRefLikeOrAllowsRefLikeType() && ParameterSyntax(i)?.Modifiers.Any(SyntaxKind.ParamsKeyword) == true) { scope = ScopedKind.ScopedValue; if (_unboundLambda.ParameterAttributes(i).Any()) diff --git a/src/Compilers/CSharp/Portable/BoundTree/VariablePendingInference.cs b/src/Compilers/CSharp/Portable/BoundTree/VariablePendingInference.cs index 9420a64c15052..987de3b5fd57f 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/VariablePendingInference.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/VariablePendingInference.cs @@ -64,7 +64,7 @@ internal BoundExpression SetInferredTypeWithAnnotations(TypeWithAnnotations type Binder.CheckRestrictedTypeInAsyncMethod(localSymbol.ContainingSymbol, type.Type, diagnosticsOpt, typeOrDesignationSyntax); - if (localSymbol.Scope == ScopedKind.ScopedValue && !type.Type.IsErrorTypeOrRefLikeType()) + if (localSymbol.Scope == ScopedKind.ScopedValue && !type.Type.IsErrorOrRefLikeOrAllowsRefLikeType()) { diagnosticsOpt.Add(ErrorCode.ERR_ScopedRefAndRefStructOnly, (typeOrDesignationSyntax is TypeSyntax typeSyntax ? typeSyntax.SkipScoped(out _).SkipRef() : typeOrDesignationSyntax).Location); diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 5d47bd91d0474..4c09a80debc1a 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -1279,7 +1279,7 @@ The type or namespace name '{0}' could not be found in the global namespace (are you missing an assembly reference?) - The new() constraint must be the last constraint specified + The new() constraint must be the last restrictive constraint specified '{0}': an entry point cannot be generic or in a generic type @@ -2105,9 +2105,6 @@ If such a class is used as a base class and if the deriving class defines a dest '{0}': static classes cannot implement interfaces - - '{0}': ref structs cannot implement interfaces - '{0}': static classes cannot contain user-defined operators @@ -2950,9 +2947,6 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep Cannot use ref, out, or in parameter '{0}' inside an anonymous method, lambda expression, query expression, or local function - - Unsafe code may not appear in iterators - Cannot yield a value in the body of a catch clause @@ -3810,7 +3804,7 @@ Give the compiler some way to differentiate the methods. For example, you can gi __arglist is not allowed in the parameter list of async methods - 'await' cannot be used in an expression containing the type '{0}' + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. Async methods cannot have pointer type parameters @@ -3851,14 +3845,11 @@ Give the compiler some way to differentiate the methods. For example, you can gi The 'async' modifier can only be used in methods that have a body. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. Security attribute '{0}' cannot be applied to an Async method. @@ -5290,12 +5281,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Cannot use ref local '{0}' inside an anonymous method, lambda expression, or query expression - - Iterators cannot have by-reference locals - - - Async methods cannot have by-reference locals - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. @@ -7486,10 +7471,10 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute cannot be applied to an interface implementation. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. '{0}' is defined in a module with an unrecognized RefSafetyRulesAttribute version, expecting '11'. @@ -7857,17 +7842,14 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Lock object params collections - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. Ambiguity between expanded and normal forms of non-array params collection parameter of '{0}', the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument. @@ -7929,4 +7911,49 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ The data argument to InterceptsLocationAttribute refers to an invalid position in file '{0}'. - + + 'yield return' should not be used in the body of a lock statement + + + 'yield return' should not be used in the body of a lock statement + + + ref and unsafe in async and iterator methods + + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + + Cannot use 'yield return' in an 'unsafe' block + + + The '&' operator cannot be used on parameters or local variables in iterator methods. + + + ref struct interfaces + + + Target runtime doesn't support by-ref-like generics. + + + 'ref struct' is already specified. + + + The 'allows' constraint clause must be the last constraint specified + + + Cannot allow ref structs for a type parameter known from other constraints to be a class + + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs index 80ca057d83076..8e90de620d901 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs @@ -372,6 +372,26 @@ private void EmitBinaryCondOperator(BoundBinaryOperator binOp, bool sense) { if (!constant.IsFloating) { + if (comparand is BoundConversion { Type.SpecialType: SpecialType.System_Object, ConversionKind: ConversionKind.Boxing, Operand.Type: TypeParameterSymbol { AllowsRefLikeType: true } } && + constant.IsNull) + { + // Boxing is not supported for ref like type parameters, therefore the code that we usually emit 'box; ldnull; ceq/cgt' + // is not going to work. There is, however, an exception for 'box; brtrue/brfalse' sequence (https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md#special-il-sequences). + EmitExpression(comparand, true); + + object falseLabel = new object(); + object endLabel = new object(); + _builder.EmitBranch(sense ? ILOpCode.Brtrue_s : ILOpCode.Brfalse_s, falseLabel); + _builder.EmitBoolConstant(true); + _builder.EmitBranch(ILOpCode.Br, endLabel); + + _builder.AdjustStack(-1); + _builder.MarkLabel(falseLabel); + _builder.EmitBoolConstant(false); + _builder.MarkLabel(endLabel); + return; + } + if (sense) { EmitIsNullOrZero(comparand, constant); diff --git a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs index 7e2ecb2809f45..7940f2df63ec4 100644 --- a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs +++ b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs @@ -281,10 +281,10 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul Debug.Assert(lazyVariableSlotAllocator is null); Debug.Assert(stateMachineTypeOpt is null); Debug.Assert(codeCoverageSpans.IsEmpty); - Debug.Assert(lambdaDebugInfoBuilder.IsEmpty()); - Debug.Assert(lambdaRuntimeRudeEditsBuilder.IsEmpty()); - Debug.Assert(closureDebugInfoBuilder.IsEmpty()); - Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty()); + Debug.Assert(lambdaDebugInfoBuilder.IsEmpty); + Debug.Assert(lambdaRuntimeRudeEditsBuilder.IsEmpty); + Debug.Assert(closureDebugInfoBuilder.IsEmpty); + Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty); lambdaDebugInfoBuilder.Free(); lambdaRuntimeRudeEditsBuilder.Free(); diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs index b704ada726b26..1787cd613877e 100644 --- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs +++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpSymbolMatcher.cs @@ -730,6 +730,7 @@ private static bool AreTypeParametersEqual(TypeParameterSymbol type, TypeParamet // edit. Furthermore, comparing constraint types might lead to a cycle. Debug.Assert(type.HasConstructorConstraint == other.HasConstructorConstraint); Debug.Assert(type.HasValueTypeConstraint == other.HasValueTypeConstraint); + Debug.Assert(type.AllowsRefLikeType == other.AllowsRefLikeType); Debug.Assert(type.HasUnmanagedTypeConstraint == other.HasUnmanagedTypeConstraint); Debug.Assert(type.HasReferenceTypeConstraint == other.HasReferenceTypeConstraint); Debug.Assert(type.ConstraintTypesNoUseSiteDiagnostics.Length == other.ConstraintTypesNoUseSiteDiagnostics.Length); diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs b/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs index 37ebf64dd7114..2a9ee5ba326ff 100644 --- a/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/Model/TypeParameterSymbolAdapter.cs @@ -302,6 +302,14 @@ bool Cci.IGenericParameter.MustBeValueType } } + bool Cci.IGenericParameter.AllowsRefLikeType + { + get + { + return AdaptedTypeParameterSymbol.AllowsRefLikeType; + } + } + bool Cci.IGenericParameter.MustHaveDefaultConstructor { get diff --git a/src/Compilers/CSharp/Portable/Emitter/NoPia/EmbeddedTypeParameter.cs b/src/Compilers/CSharp/Portable/Emitter/NoPia/EmbeddedTypeParameter.cs index 819b0c2e43f9b..dfde648cbffc8 100644 --- a/src/Compilers/CSharp/Portable/Emitter/NoPia/EmbeddedTypeParameter.cs +++ b/src/Compilers/CSharp/Portable/Emitter/NoPia/EmbeddedTypeParameter.cs @@ -45,6 +45,14 @@ protected override bool MustBeValueType } } + protected override bool AllowsRefLikeType + { + get + { + return UnderlyingTypeParameter.AdaptedTypeParameterSymbol.AllowsRefLikeType; + } + } + protected override bool MustHaveDefaultConstructor { get diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index d04040b6dff27..4f8a380ef0913 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -792,7 +792,7 @@ internal enum ErrorCode ERR_BadYieldInTryOfCatch = 1626, ERR_EmptyYield = 1627, ERR_AnonDelegateCantUse = 1628, - ERR_IllegalInnerUnsafe = 1629, + // ERR_IllegalInnerUnsafe = 1629, //ERR_BadWatsonMode = 1630, ERR_BadYieldInCatch = 1631, ERR_BadDelegateLeave = 1632, @@ -1111,7 +1111,7 @@ internal enum ErrorCode ERR_NonTaskMainCantBeAsync = 4009, ERR_CantConvAsyncAnonFuncReturns = 4010, ERR_BadAwaiterPattern = 4011, - ERR_BadSpecialByRefLocal = 4012, + ERR_BadSpecialByRefParameter = 4012, ERR_SpecialByRefInLambda = 4013, WRN_UnobservedAwaitableExpression = 4014, ERR_SynchronizedAsyncMethod = 4015, @@ -1429,8 +1429,8 @@ internal enum ErrorCode ERR_RefAssignmentMustHaveIdentityConversion = 8173, ERR_ByReferenceVariableMustBeInitialized = 8174, ERR_AnonDelegateCantUseLocal = 8175, - ERR_BadIteratorLocalType = 8176, - ERR_BadAsyncLocalType = 8177, + // ERR_BadIteratorLocalType = 8176, + // ERR_BadAsyncLocalType = 8177, ERR_RefReturningCallAndAwait = 8178, #endregion diagnostics for ref locals and ref returns introduced in C# 7 @@ -1528,7 +1528,7 @@ internal enum ErrorCode ERR_FieldsInRoStruct = 8340, ERR_AutoPropsInRoStruct = 8341, ERR_FieldlikeEventsInRoStruct = 8342, - ERR_RefStructInterfaceImpl = 8343, + // ERR_RefStructInterfaceImpl = 8343, ERR_BadSpecialByRefIterator = 8344, ERR_FieldAutoPropCantBeByRefLike = 8345, ERR_StackAllocConversionNotPossible = 8346, @@ -2161,7 +2161,7 @@ internal enum ErrorCode ERR_UnscopedRefAttributeUnsupportedMemberTarget = 9101, ERR_UnscopedRefAttributeInterfaceImplementation = 9102, ERR_UnrecognizedRefSafetyRulesAttributeVersion = 9103, - ERR_BadSpecialByRefUsing = 9104, + // ERR_BadSpecialByRefUsing = 9104, ERR_InvalidPrimaryConstructorParameterReference = 9105, ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver = 9106, @@ -2286,9 +2286,9 @@ internal enum ErrorCode ERR_CollectionExpressionMissingAdd = 9215, WRN_ConvertingLock = 9216, - ERR_BadSpecialByRefLock = 9217, + ERR_RefLocalAcrossAwait = 9217, - ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections = 9218, + ERR_DynamicDispatchToParamsCollection = 9218, ERR_ParamsCollectionAmbiguousDynamicArgument = 9219, WRN_DynamicDispatchToParamsCollectionMethod = 9220, WRN_DynamicDispatchToParamsCollectionIndexer = 9221, @@ -2312,6 +2312,19 @@ internal enum ErrorCode #endregion + WRN_BadYieldInLock = 9237, + ERR_BadYieldInUnsafe = 9238, + ERR_AddressOfInIterator = 9239, + + ERR_RuntimeDoesNotSupportByRefLikeGenerics = 9240, + ERR_RefStructConstraintAlreadySpecified = 9241, + ERR_AllowsClauseMustBeLast = 9242, + ERR_ClassIsCombinedWithRefStruct = 9243, + ERR_NotRefStructConstraintNotSatisfied = 9244, + ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember = 9245, + ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike = 9246, + ERR_BadAllowByRefLikeEnumerator = 9247, + // Note: you will need to do the following after adding errors: // 1) Update ErrorFacts.IsBuildOnlyDiagnostic (src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs) diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs index 6ca5b85258d76..03a75fda22f79 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs @@ -207,6 +207,10 @@ internal static int GetWarningLevel(ErrorCode code) // docs/compilers/CSharp/Warnversion Warning Waves.md switch (code) { + case ErrorCode.WRN_BadYieldInLock: + // Warning level 9 is exclusively for warnings introduced in the compiler + // shipped with dotnet 9 (C# 13) and that can be reported for pre-existing code. + return 9; case ErrorCode.WRN_AddressOfInAsync: case ErrorCode.WRN_ByValArraySizeConstRequired: // Warning level 8 is exclusively for warnings introduced in the compiler @@ -573,1877 +577,1882 @@ internal static int GetWarningLevel(ErrorCode code) /// internal static bool IsBuildOnlyDiagnostic(ErrorCode code) { - switch (code) +#pragma warning disable CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. + return code switch { - case ErrorCode.WRN_ALinkWarn: - case ErrorCode.WRN_UnreferencedField: - case ErrorCode.WRN_UnreferencedFieldAssg: - case ErrorCode.WRN_UnreferencedEvent: - case ErrorCode.WRN_UnassignedInternalField: - case ErrorCode.ERR_MissingPredefinedMember: - case ErrorCode.ERR_PredefinedTypeNotFound: - case ErrorCode.ERR_NoEntryPoint: - case ErrorCode.WRN_InvalidMainSig: - case ErrorCode.ERR_MultipleEntryPoints: - case ErrorCode.WRN_MainIgnored: - case ErrorCode.ERR_MainClassNotClass: - case ErrorCode.WRN_MainCantBeGeneric: - case ErrorCode.ERR_NoMainInClass: - case ErrorCode.ERR_MainClassNotFound: - case ErrorCode.WRN_SyncAndAsyncEntryPoints: - case ErrorCode.ERR_BadDelegateConstructor: - case ErrorCode.ERR_InsufficientStack: - case ErrorCode.ERR_ModuleEmitFailure: - case ErrorCode.ERR_TooManyLocals: - case ErrorCode.ERR_BindToBogus: - case ErrorCode.ERR_ExportedTypeConflictsWithDeclaration: - case ErrorCode.ERR_ForwardedTypeConflictsWithDeclaration: - case ErrorCode.ERR_ExportedTypesConflict: - case ErrorCode.ERR_ForwardedTypeConflictsWithExportedType: - case ErrorCode.ERR_ByRefTypeAndAwait: - case ErrorCode.ERR_RefReturningCallAndAwait: - case ErrorCode.ERR_SpecialByRefInLambda: - case ErrorCode.ERR_DynamicRequiredTypesMissing: - case ErrorCode.ERR_CannotBeConvertedToUtf8: - case ErrorCode.ERR_FileTypeNonUniquePath: - case ErrorCode.ERR_InterceptorSignatureMismatch: - case ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter: - case ErrorCode.ERR_InterceptorMustNotHaveThisParameter: - case ErrorCode.ERR_DuplicateInterceptor: - case ErrorCode.WRN_InterceptorSignatureMismatch: - case ErrorCode.ERR_InterceptorNotAccessible: - case ErrorCode.ERR_InterceptorScopedMismatch: - case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor: - case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor: - case ErrorCode.ERR_InterceptorCannotInterceptNameof: - case ErrorCode.ERR_SymbolDefinedInAssembly: - case ErrorCode.ERR_InterceptorArityNotCompatible: - case ErrorCode.ERR_InterceptorCannotBeGeneric: - case ErrorCode.ERR_InterceptableMethodMustBeOrdinary: - case ErrorCode.ERR_PossibleAsyncIteratorWithoutYield: - case ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait: + ErrorCode.WRN_ALinkWarn + or ErrorCode.WRN_UnreferencedField + or ErrorCode.WRN_UnreferencedFieldAssg + or ErrorCode.WRN_UnreferencedEvent + or ErrorCode.WRN_UnassignedInternalField + or ErrorCode.ERR_MissingPredefinedMember + or ErrorCode.ERR_PredefinedTypeNotFound + or ErrorCode.ERR_NoEntryPoint + or ErrorCode.WRN_InvalidMainSig + or ErrorCode.ERR_MultipleEntryPoints + or ErrorCode.WRN_MainIgnored + or ErrorCode.ERR_MainClassNotClass + or ErrorCode.WRN_MainCantBeGeneric + or ErrorCode.ERR_NoMainInClass + or ErrorCode.ERR_MainClassNotFound + or ErrorCode.WRN_SyncAndAsyncEntryPoints + or ErrorCode.ERR_BadDelegateConstructor + or ErrorCode.ERR_InsufficientStack + or ErrorCode.ERR_ModuleEmitFailure + or ErrorCode.ERR_TooManyLocals + or ErrorCode.ERR_BindToBogus + or ErrorCode.ERR_ExportedTypeConflictsWithDeclaration + or ErrorCode.ERR_ForwardedTypeConflictsWithDeclaration + or ErrorCode.ERR_ExportedTypesConflict + or ErrorCode.ERR_ForwardedTypeConflictsWithExportedType + or ErrorCode.ERR_ByRefTypeAndAwait + or ErrorCode.ERR_RefReturningCallAndAwait + or ErrorCode.ERR_SpecialByRefInLambda + or ErrorCode.ERR_DynamicRequiredTypesMissing + or ErrorCode.ERR_CannotBeConvertedToUtf8 + or ErrorCode.ERR_FileTypeNonUniquePath + or ErrorCode.ERR_InterceptorSignatureMismatch + or ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter + or ErrorCode.ERR_InterceptorMustNotHaveThisParameter + or ErrorCode.ERR_DuplicateInterceptor + or ErrorCode.WRN_InterceptorSignatureMismatch + or ErrorCode.ERR_InterceptorNotAccessible + or ErrorCode.ERR_InterceptorScopedMismatch + or ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor + or ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor + or ErrorCode.ERR_InterceptorCannotInterceptNameof + or ErrorCode.ERR_SymbolDefinedInAssembly + or ErrorCode.ERR_InterceptorArityNotCompatible + or ErrorCode.ERR_InterceptorCannotBeGeneric + or ErrorCode.ERR_InterceptableMethodMustBeOrdinary + or ErrorCode.ERR_PossibleAsyncIteratorWithoutYield + or ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait + or ErrorCode.ERR_RefLocalAcrossAwait // Update src\EditorFeatures\CSharp\LanguageServer\CSharpLspBuildOnlyDiagnostics.cs // whenever new values are added here. - return true; - case ErrorCode.Void: - case ErrorCode.Unknown: - case ErrorCode.ERR_NoMetadataFile: - case ErrorCode.FTL_MetadataCantOpenFile: - case ErrorCode.ERR_NoTypeDef: - case ErrorCode.ERR_OutputWriteFailed: - case ErrorCode.ERR_BadBinaryOps: - case ErrorCode.ERR_IntDivByZero: - case ErrorCode.ERR_BadIndexLHS: - case ErrorCode.ERR_BadIndexCount: - case ErrorCode.ERR_BadUnaryOp: - case ErrorCode.ERR_ThisInStaticMeth: - case ErrorCode.ERR_ThisInBadContext: - case ErrorCode.ERR_NoImplicitConv: - case ErrorCode.ERR_NoExplicitConv: - case ErrorCode.ERR_ConstOutOfRange: - case ErrorCode.ERR_AmbigBinaryOps: - case ErrorCode.ERR_AmbigUnaryOp: - case ErrorCode.ERR_InAttrOnOutParam: - case ErrorCode.ERR_ValueCantBeNull: - case ErrorCode.ERR_NoExplicitBuiltinConv: - case ErrorCode.FTL_DebugEmitFailure: - case ErrorCode.ERR_BadVisReturnType: - case ErrorCode.ERR_BadVisParamType: - case ErrorCode.ERR_BadVisFieldType: - case ErrorCode.ERR_BadVisPropertyType: - case ErrorCode.ERR_BadVisIndexerReturn: - case ErrorCode.ERR_BadVisIndexerParam: - case ErrorCode.ERR_BadVisOpReturn: - case ErrorCode.ERR_BadVisOpParam: - case ErrorCode.ERR_BadVisDelegateReturn: - case ErrorCode.ERR_BadVisDelegateParam: - case ErrorCode.ERR_BadVisBaseClass: - case ErrorCode.ERR_BadVisBaseInterface: - case ErrorCode.ERR_EventNeedsBothAccessors: - case ErrorCode.ERR_EventNotDelegate: - case ErrorCode.ERR_InterfaceEventInitializer: - case ErrorCode.ERR_BadEventUsage: - case ErrorCode.ERR_ExplicitEventFieldImpl: - case ErrorCode.ERR_CantOverrideNonEvent: - case ErrorCode.ERR_AddRemoveMustHaveBody: - case ErrorCode.ERR_AbstractEventInitializer: - case ErrorCode.ERR_PossibleBadNegCast: - case ErrorCode.ERR_ReservedEnumerator: - case ErrorCode.ERR_AsMustHaveReferenceType: - case ErrorCode.WRN_LowercaseEllSuffix: - case ErrorCode.ERR_BadEventUsageNoField: - case ErrorCode.ERR_ConstraintOnlyAllowedOnGenericDecl: - case ErrorCode.ERR_TypeParamMustBeIdentifier: - case ErrorCode.ERR_MemberReserved: - case ErrorCode.ERR_DuplicateParamName: - case ErrorCode.ERR_DuplicateNameInNS: - case ErrorCode.ERR_DuplicateNameInClass: - case ErrorCode.ERR_NameNotInContext: - case ErrorCode.ERR_AmbigContext: - case ErrorCode.WRN_DuplicateUsing: - case ErrorCode.ERR_BadMemberFlag: - case ErrorCode.ERR_BadMemberProtection: - case ErrorCode.WRN_NewRequired: - case ErrorCode.WRN_NewNotRequired: - case ErrorCode.ERR_CircConstValue: - case ErrorCode.ERR_MemberAlreadyExists: - case ErrorCode.ERR_StaticNotVirtual: - case ErrorCode.ERR_OverrideNotNew: - case ErrorCode.WRN_NewOrOverrideExpected: - case ErrorCode.ERR_OverrideNotExpected: - case ErrorCode.ERR_NamespaceUnexpected: - case ErrorCode.ERR_NoSuchMember: - case ErrorCode.ERR_BadSKknown: - case ErrorCode.ERR_BadSKunknown: - case ErrorCode.ERR_ObjectRequired: - case ErrorCode.ERR_AmbigCall: - case ErrorCode.ERR_BadAccess: - case ErrorCode.ERR_MethDelegateMismatch: - case ErrorCode.ERR_RetObjectRequired: - case ErrorCode.ERR_RetNoObjectRequired: - case ErrorCode.ERR_LocalDuplicate: - case ErrorCode.ERR_AssgLvalueExpected: - case ErrorCode.ERR_StaticConstParam: - case ErrorCode.ERR_NotConstantExpression: - case ErrorCode.ERR_NotNullConstRefField: - case ErrorCode.ERR_LocalIllegallyOverrides: - case ErrorCode.ERR_BadUsingNamespace: - case ErrorCode.ERR_NoBreakOrCont: - case ErrorCode.ERR_DuplicateLabel: - case ErrorCode.ERR_NoConstructors: - case ErrorCode.ERR_NoNewAbstract: - case ErrorCode.ERR_ConstValueRequired: - case ErrorCode.ERR_CircularBase: - case ErrorCode.ERR_MethodNameExpected: - case ErrorCode.ERR_ConstantExpected: - case ErrorCode.ERR_V6SwitchGoverningTypeValueExpected: - case ErrorCode.ERR_DuplicateCaseLabel: - case ErrorCode.ERR_InvalidGotoCase: - case ErrorCode.ERR_PropertyLacksGet: - case ErrorCode.ERR_BadExceptionType: - case ErrorCode.ERR_BadEmptyThrow: - case ErrorCode.ERR_BadFinallyLeave: - case ErrorCode.ERR_LabelShadow: - case ErrorCode.ERR_LabelNotFound: - case ErrorCode.ERR_UnreachableCatch: - case ErrorCode.ERR_ReturnExpected: - case ErrorCode.WRN_UnreachableCode: - case ErrorCode.ERR_SwitchFallThrough: - case ErrorCode.WRN_UnreferencedLabel: - case ErrorCode.ERR_UseDefViolation: - case ErrorCode.WRN_UnreferencedVar: - case ErrorCode.ERR_UseDefViolationField: - case ErrorCode.ERR_UnassignedThisUnsupportedVersion: - case ErrorCode.ERR_AmbigQM: - case ErrorCode.ERR_InvalidQM: - case ErrorCode.ERR_NoBaseClass: - case ErrorCode.ERR_BaseIllegal: - case ErrorCode.ERR_ObjectProhibited: - case ErrorCode.ERR_ParamUnassigned: - case ErrorCode.ERR_InvalidArray: - case ErrorCode.ERR_ExternHasBody: - case ErrorCode.ERR_AbstractAndExtern: - case ErrorCode.ERR_BadAttributeParamType: - case ErrorCode.ERR_BadAttributeArgument: - case ErrorCode.WRN_IsAlwaysTrue: - case ErrorCode.WRN_IsAlwaysFalse: - case ErrorCode.ERR_LockNeedsReference: - case ErrorCode.ERR_NullNotValid: - case ErrorCode.ERR_UseDefViolationThisUnsupportedVersion: - case ErrorCode.ERR_ArgsInvalid: - case ErrorCode.ERR_AssgReadonly: - case ErrorCode.ERR_RefReadonly: - case ErrorCode.ERR_PtrExpected: - case ErrorCode.ERR_PtrIndexSingle: - case ErrorCode.WRN_ByRefNonAgileField: - case ErrorCode.ERR_AssgReadonlyStatic: - case ErrorCode.ERR_RefReadonlyStatic: - case ErrorCode.ERR_AssgReadonlyProp: - case ErrorCode.ERR_IllegalStatement: - case ErrorCode.ERR_BadGetEnumerator: - case ErrorCode.ERR_AbstractBaseCall: - case ErrorCode.ERR_RefProperty: - case ErrorCode.ERR_ManagedAddr: - case ErrorCode.ERR_BadFixedInitType: - case ErrorCode.ERR_FixedMustInit: - case ErrorCode.ERR_InvalidAddrOp: - case ErrorCode.ERR_FixedNeeded: - case ErrorCode.ERR_FixedNotNeeded: - case ErrorCode.ERR_UnsafeNeeded: - case ErrorCode.ERR_OpTFRetType: - case ErrorCode.ERR_OperatorNeedsMatch: - case ErrorCode.ERR_BadBoolOp: - case ErrorCode.ERR_MustHaveOpTF: - case ErrorCode.WRN_UnreferencedVarAssg: - case ErrorCode.ERR_CheckedOverflow: - case ErrorCode.ERR_ConstOutOfRangeChecked: - case ErrorCode.ERR_BadVarargs: - case ErrorCode.ERR_ParamsMustBeCollection: - case ErrorCode.ERR_IllegalArglist: - case ErrorCode.ERR_IllegalUnsafe: - case ErrorCode.ERR_AmbigMember: - case ErrorCode.ERR_BadForeachDecl: - case ErrorCode.ERR_ParamsLast: - case ErrorCode.ERR_SizeofUnsafe: - case ErrorCode.ERR_DottedTypeNameNotFoundInNS: - case ErrorCode.ERR_FieldInitRefNonstatic: - case ErrorCode.ERR_SealedNonOverride: - case ErrorCode.ERR_CantOverrideSealed: - case ErrorCode.ERR_VoidError: - case ErrorCode.ERR_ConditionalOnOverride: - case ErrorCode.ERR_PointerInAsOrIs: - case ErrorCode.ERR_CallingFinalizeDeprecated: - case ErrorCode.ERR_SingleTypeNameNotFound: - case ErrorCode.ERR_NegativeStackAllocSize: - case ErrorCode.ERR_NegativeArraySize: - case ErrorCode.ERR_OverrideFinalizeDeprecated: - case ErrorCode.ERR_CallingBaseFinalizeDeprecated: - case ErrorCode.WRN_NegativeArrayIndex: - case ErrorCode.WRN_BadRefCompareLeft: - case ErrorCode.WRN_BadRefCompareRight: - case ErrorCode.ERR_BadCastInFixed: - case ErrorCode.ERR_StackallocInCatchFinally: - case ErrorCode.ERR_VarargsLast: - case ErrorCode.ERR_MissingPartial: - case ErrorCode.ERR_PartialTypeKindConflict: - case ErrorCode.ERR_PartialModifierConflict: - case ErrorCode.ERR_PartialMultipleBases: - case ErrorCode.ERR_PartialWrongTypeParams: - case ErrorCode.ERR_PartialWrongConstraints: - case ErrorCode.ERR_NoImplicitConvCast: - case ErrorCode.ERR_PartialMisplaced: - case ErrorCode.ERR_ImportedCircularBase: - case ErrorCode.ERR_UseDefViolationOut: - case ErrorCode.ERR_ArraySizeInDeclaration: - case ErrorCode.ERR_InaccessibleGetter: - case ErrorCode.ERR_InaccessibleSetter: - case ErrorCode.ERR_InvalidPropertyAccessMod: - case ErrorCode.ERR_DuplicatePropertyAccessMods: - case ErrorCode.ERR_AccessModMissingAccessor: - case ErrorCode.ERR_UnimplementedInterfaceAccessor: - case ErrorCode.WRN_PatternIsAmbiguous: - case ErrorCode.WRN_PatternNotPublicOrNotInstance: - case ErrorCode.WRN_PatternBadSignature: - case ErrorCode.ERR_FriendRefNotEqualToThis: - case ErrorCode.WRN_SequentialOnPartialClass: - case ErrorCode.ERR_BadConstType: - case ErrorCode.ERR_NoNewTyvar: - case ErrorCode.ERR_BadArity: - case ErrorCode.ERR_BadTypeArgument: - case ErrorCode.ERR_TypeArgsNotAllowed: - case ErrorCode.ERR_HasNoTypeVars: - case ErrorCode.ERR_NewConstraintNotSatisfied: - case ErrorCode.ERR_GenericConstraintNotSatisfiedRefType: - case ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum: - case ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface: - case ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar: - case ErrorCode.ERR_GenericConstraintNotSatisfiedValType: - case ErrorCode.ERR_DuplicateGeneratedName: - case ErrorCode.ERR_GlobalSingleTypeNameNotFound: - case ErrorCode.ERR_NewBoundMustBeLast: - case ErrorCode.ERR_TypeVarCantBeNull: - case ErrorCode.ERR_DuplicateBound: - case ErrorCode.ERR_ClassBoundNotFirst: - case ErrorCode.ERR_BadRetType: - case ErrorCode.ERR_DuplicateConstraintClause: - case ErrorCode.ERR_CantInferMethTypeArgs: - case ErrorCode.ERR_LocalSameNameAsTypeParam: - case ErrorCode.ERR_AsWithTypeVar: - case ErrorCode.ERR_BadIndexerNameAttr: - case ErrorCode.ERR_AttrArgWithTypeVars: - case ErrorCode.ERR_NewTyvarWithArgs: - case ErrorCode.ERR_AbstractSealedStatic: - case ErrorCode.WRN_AmbiguousXMLReference: - case ErrorCode.WRN_VolatileByRef: - case ErrorCode.ERR_ComImportWithImpl: - case ErrorCode.ERR_ComImportWithBase: - case ErrorCode.ERR_ImplBadConstraints: - case ErrorCode.ERR_DottedTypeNameNotFoundInAgg: - case ErrorCode.ERR_MethGrpToNonDel: - case ErrorCode.ERR_BadExternAlias: - case ErrorCode.ERR_ColColWithTypeAlias: - case ErrorCode.ERR_AliasNotFound: - case ErrorCode.ERR_SameFullNameAggAgg: - case ErrorCode.ERR_SameFullNameNsAgg: - case ErrorCode.WRN_SameFullNameThisNsAgg: - case ErrorCode.WRN_SameFullNameThisAggAgg: - case ErrorCode.WRN_SameFullNameThisAggNs: - case ErrorCode.ERR_SameFullNameThisAggThisNs: - case ErrorCode.ERR_ExternAfterElements: - case ErrorCode.WRN_GlobalAliasDefn: - case ErrorCode.ERR_SealedStaticClass: - case ErrorCode.ERR_PrivateAbstractAccessor: - case ErrorCode.ERR_ValueExpected: - case ErrorCode.ERR_UnboxNotLValue: - case ErrorCode.ERR_AnonMethGrpInForEach: - case ErrorCode.ERR_BadIncDecRetType: - case ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst: - case ErrorCode.ERR_RefValBoundWithClass: - case ErrorCode.ERR_NewBoundWithVal: - case ErrorCode.ERR_RefConstraintNotSatisfied: - case ErrorCode.ERR_ValConstraintNotSatisfied: - case ErrorCode.ERR_CircularConstraint: - case ErrorCode.ERR_BaseConstraintConflict: - case ErrorCode.ERR_ConWithValCon: - case ErrorCode.ERR_AmbigUDConv: - case ErrorCode.WRN_AlwaysNull: - case ErrorCode.ERR_OverrideWithConstraints: - case ErrorCode.ERR_AmbigOverride: - case ErrorCode.ERR_DecConstError: - case ErrorCode.WRN_CmpAlwaysFalse: - case ErrorCode.WRN_FinalizeMethod: - case ErrorCode.ERR_ExplicitImplParams: - case ErrorCode.WRN_GotoCaseShouldConvert: - case ErrorCode.ERR_MethodImplementingAccessor: - case ErrorCode.WRN_NubExprIsConstBool: - case ErrorCode.WRN_ExplicitImplCollision: - case ErrorCode.ERR_AbstractHasBody: - case ErrorCode.ERR_ConcreteMissingBody: - case ErrorCode.ERR_AbstractAndSealed: - case ErrorCode.ERR_AbstractNotVirtual: - case ErrorCode.ERR_StaticConstant: - case ErrorCode.ERR_CantOverrideNonFunction: - case ErrorCode.ERR_CantOverrideNonVirtual: - case ErrorCode.ERR_CantChangeAccessOnOverride: - case ErrorCode.ERR_CantChangeReturnTypeOnOverride: - case ErrorCode.ERR_CantDeriveFromSealedType: - case ErrorCode.ERR_AbstractInConcreteClass: - case ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall: - case ErrorCode.ERR_StaticConstructorWithAccessModifiers: - case ErrorCode.ERR_RecursiveConstructorCall: - case ErrorCode.ERR_ObjectCallingBaseConstructor: - case ErrorCode.ERR_StructWithBaseConstructorCall: - case ErrorCode.ERR_StructLayoutCycle: - case ErrorCode.ERR_InterfacesCantContainFields: - case ErrorCode.ERR_InterfacesCantContainConstructors: - case ErrorCode.ERR_NonInterfaceInInterfaceList: - case ErrorCode.ERR_DuplicateInterfaceInBaseList: - case ErrorCode.ERR_CycleInInterfaceInheritance: - case ErrorCode.ERR_HidingAbstractMethod: - case ErrorCode.ERR_UnimplementedAbstractMethod: - case ErrorCode.ERR_UnimplementedInterfaceMember: - case ErrorCode.ERR_ObjectCantHaveBases: - case ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface: - case ErrorCode.ERR_InterfaceMemberNotFound: - case ErrorCode.ERR_ClassDoesntImplementInterface: - case ErrorCode.ERR_ExplicitInterfaceImplementationInNonClassOrStruct: - case ErrorCode.ERR_MemberNameSameAsType: - case ErrorCode.ERR_EnumeratorOverflow: - case ErrorCode.ERR_CantOverrideNonProperty: - case ErrorCode.ERR_NoGetToOverride: - case ErrorCode.ERR_NoSetToOverride: - case ErrorCode.ERR_PropertyCantHaveVoidType: - case ErrorCode.ERR_PropertyWithNoAccessors: - case ErrorCode.ERR_NewVirtualInSealed: - case ErrorCode.ERR_ExplicitPropertyAddingAccessor: - case ErrorCode.ERR_ExplicitPropertyMissingAccessor: - case ErrorCode.ERR_ConversionWithInterface: - case ErrorCode.ERR_ConversionWithBase: - case ErrorCode.ERR_ConversionWithDerived: - case ErrorCode.ERR_IdentityConversion: - case ErrorCode.ERR_ConversionNotInvolvingContainedType: - case ErrorCode.ERR_DuplicateConversionInClass: - case ErrorCode.ERR_OperatorsMustBeStatic: - case ErrorCode.ERR_BadIncDecSignature: - case ErrorCode.ERR_BadUnaryOperatorSignature: - case ErrorCode.ERR_BadBinaryOperatorSignature: - case ErrorCode.ERR_BadShiftOperatorSignature: - case ErrorCode.ERR_InterfacesCantContainConversionOrEqualityOperators: - case ErrorCode.ERR_CantOverrideBogusMethod: - case ErrorCode.ERR_CantCallSpecialMethod: - case ErrorCode.ERR_BadTypeReference: - case ErrorCode.ERR_BadDestructorName: - case ErrorCode.ERR_OnlyClassesCanContainDestructors: - case ErrorCode.ERR_ConflictAliasAndMember: - case ErrorCode.ERR_ConditionalOnSpecialMethod: - case ErrorCode.ERR_ConditionalMustReturnVoid: - case ErrorCode.ERR_DuplicateAttribute: - case ErrorCode.ERR_ConditionalOnInterfaceMethod: - case ErrorCode.ERR_OperatorCantReturnVoid: - case ErrorCode.ERR_InvalidAttributeArgument: - case ErrorCode.ERR_AttributeOnBadSymbolType: - case ErrorCode.ERR_FloatOverflow: - case ErrorCode.ERR_InvalidReal: - case ErrorCode.ERR_ComImportWithoutUuidAttribute: - case ErrorCode.ERR_InvalidNamedArgument: - case ErrorCode.ERR_DllImportOnInvalidMethod: - case ErrorCode.ERR_FieldCantBeRefAny: - case ErrorCode.ERR_ArrayElementCantBeRefAny: - case ErrorCode.WRN_DeprecatedSymbol: - case ErrorCode.ERR_NotAnAttributeClass: - case ErrorCode.ERR_BadNamedAttributeArgument: - case ErrorCode.WRN_DeprecatedSymbolStr: - case ErrorCode.ERR_DeprecatedSymbolStr: - case ErrorCode.ERR_IndexerCantHaveVoidType: - case ErrorCode.ERR_VirtualPrivate: - case ErrorCode.ERR_ArrayInitToNonArrayType: - case ErrorCode.ERR_ArrayInitInBadPlace: - case ErrorCode.ERR_MissingStructOffset: - case ErrorCode.WRN_ExternMethodNoImplementation: - case ErrorCode.WRN_ProtectedInSealed: - case ErrorCode.ERR_InterfaceImplementedByConditional: - case ErrorCode.ERR_InterfaceImplementedImplicitlyByVariadic: - case ErrorCode.ERR_IllegalRefParam: - case ErrorCode.ERR_BadArgumentToAttribute: - case ErrorCode.ERR_StructOffsetOnBadStruct: - case ErrorCode.ERR_StructOffsetOnBadField: - case ErrorCode.ERR_AttributeUsageOnNonAttributeClass: - case ErrorCode.WRN_PossibleMistakenNullStatement: - case ErrorCode.ERR_DuplicateNamedAttributeArgument: - case ErrorCode.ERR_DeriveFromEnumOrValueType: - case ErrorCode.ERR_DefaultMemberOnIndexedType: - case ErrorCode.ERR_BogusType: - case ErrorCode.ERR_CStyleArray: - case ErrorCode.WRN_VacuousIntegralComp: - case ErrorCode.ERR_AbstractAttributeClass: - case ErrorCode.ERR_BadNamedAttributeArgumentType: - case ErrorCode.WRN_AttributeLocationOnBadDeclaration: - case ErrorCode.WRN_InvalidAttributeLocation: - case ErrorCode.WRN_EqualsWithoutGetHashCode: - case ErrorCode.WRN_EqualityOpWithoutEquals: - case ErrorCode.WRN_EqualityOpWithoutGetHashCode: - case ErrorCode.ERR_OutAttrOnRefParam: - case ErrorCode.ERR_OverloadRefKind: - case ErrorCode.ERR_LiteralDoubleCast: - case ErrorCode.WRN_IncorrectBooleanAssg: - case ErrorCode.ERR_ProtectedInStruct: - case ErrorCode.ERR_InconsistentIndexerNames: - case ErrorCode.ERR_ComImportWithUserCtor: - case ErrorCode.ERR_FieldCantHaveVoidType: - case ErrorCode.WRN_NonObsoleteOverridingObsolete: - case ErrorCode.ERR_SystemVoid: - case ErrorCode.ERR_ExplicitParamArrayOrCollection: - case ErrorCode.WRN_BitwiseOrSignExtend: - case ErrorCode.ERR_VolatileStruct: - case ErrorCode.ERR_VolatileAndReadonly: - case ErrorCode.ERR_AbstractField: - case ErrorCode.ERR_BogusExplicitImpl: - case ErrorCode.ERR_ExplicitMethodImplAccessor: - case ErrorCode.WRN_CoClassWithoutComImport: - case ErrorCode.ERR_ConditionalWithOutParam: - case ErrorCode.ERR_AccessorImplementingMethod: - case ErrorCode.ERR_AliasQualAsExpression: - case ErrorCode.ERR_DerivingFromATyVar: - case ErrorCode.ERR_DuplicateTypeParameter: - case ErrorCode.WRN_TypeParameterSameAsOuterTypeParameter: - case ErrorCode.ERR_TypeVariableSameAsParent: - case ErrorCode.ERR_UnifyingInterfaceInstantiations: - case ErrorCode.ERR_TyVarNotFoundInConstraint: - case ErrorCode.ERR_BadBoundType: - case ErrorCode.ERR_SpecialTypeAsBound: - case ErrorCode.ERR_BadVisBound: - case ErrorCode.ERR_LookupInTypeVariable: - case ErrorCode.ERR_BadConstraintType: - case ErrorCode.ERR_InstanceMemberInStaticClass: - case ErrorCode.ERR_StaticBaseClass: - case ErrorCode.ERR_ConstructorInStaticClass: - case ErrorCode.ERR_DestructorInStaticClass: - case ErrorCode.ERR_InstantiatingStaticClass: - case ErrorCode.ERR_StaticDerivedFromNonObject: - case ErrorCode.ERR_StaticClassInterfaceImpl: - case ErrorCode.ERR_OperatorInStaticClass: - case ErrorCode.ERR_ConvertToStaticClass: - case ErrorCode.ERR_ConstraintIsStaticClass: - case ErrorCode.ERR_GenericArgIsStaticClass: - case ErrorCode.ERR_ArrayOfStaticClass: - case ErrorCode.ERR_IndexerInStaticClass: - case ErrorCode.ERR_ParameterIsStaticClass: - case ErrorCode.ERR_ReturnTypeIsStaticClass: - case ErrorCode.ERR_VarDeclIsStaticClass: - case ErrorCode.ERR_BadEmptyThrowInFinally: - case ErrorCode.ERR_InvalidSpecifier: - case ErrorCode.WRN_AssignmentToLockOrDispose: - case ErrorCode.ERR_ForwardedTypeInThisAssembly: - case ErrorCode.ERR_ForwardedTypeIsNested: - case ErrorCode.ERR_CycleInTypeForwarder: - case ErrorCode.ERR_AssemblyNameOnNonModule: - case ErrorCode.ERR_InvalidFwdType: - case ErrorCode.ERR_CloseUnimplementedInterfaceMemberStatic: - case ErrorCode.ERR_CloseUnimplementedInterfaceMemberNotPublic: - case ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType: - case ErrorCode.ERR_DuplicateTypeForwarder: - case ErrorCode.ERR_ExpectedSelectOrGroup: - case ErrorCode.ERR_ExpectedContextualKeywordOn: - case ErrorCode.ERR_ExpectedContextualKeywordEquals: - case ErrorCode.ERR_ExpectedContextualKeywordBy: - case ErrorCode.ERR_InvalidAnonymousTypeMemberDeclarator: - case ErrorCode.ERR_InvalidInitializerElementInitializer: - case ErrorCode.ERR_InconsistentLambdaParameterUsage: - case ErrorCode.ERR_PartialMethodInvalidModifier: - case ErrorCode.ERR_PartialMethodOnlyInPartialClass: - case ErrorCode.ERR_PartialMethodNotExplicit: - case ErrorCode.ERR_PartialMethodExtensionDifference: - case ErrorCode.ERR_PartialMethodOnlyOneLatent: - case ErrorCode.ERR_PartialMethodOnlyOneActual: - case ErrorCode.ERR_PartialMethodParamsDifference: - case ErrorCode.ERR_PartialMethodMustHaveLatent: - case ErrorCode.ERR_PartialMethodInconsistentConstraints: - case ErrorCode.ERR_PartialMethodToDelegate: - case ErrorCode.ERR_PartialMethodStaticDifference: - case ErrorCode.ERR_PartialMethodUnsafeDifference: - case ErrorCode.ERR_PartialMethodInExpressionTree: - case ErrorCode.ERR_ExplicitImplCollisionOnRefOut: - case ErrorCode.ERR_IndirectRecursiveConstructorCall: - case ErrorCode.WRN_ObsoleteOverridingNonObsolete: - case ErrorCode.WRN_DebugFullNameTooLong: - case ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue: - case ErrorCode.ERR_ImplicitlyTypedVariableWithNoInitializer: - case ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator: - case ErrorCode.ERR_ImplicitlyTypedVariableAssignedArrayInitializer: - case ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed: - case ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst: - case ErrorCode.WRN_ExternCtorNoImplementation: - case ErrorCode.ERR_TypeVarNotFound: - case ErrorCode.ERR_ImplicitlyTypedArrayNoBestType: - case ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue: - case ErrorCode.ERR_ExpressionTreeContainsBaseAccess: - case ErrorCode.ERR_ExpressionTreeContainsAssignment: - case ErrorCode.ERR_AnonymousTypeDuplicatePropertyName: - case ErrorCode.ERR_StatementLambdaToExpressionTree: - case ErrorCode.ERR_ExpressionTreeMustHaveDelegate: - case ErrorCode.ERR_AnonymousTypeNotAvailable: - case ErrorCode.ERR_LambdaInIsAs: - case ErrorCode.ERR_ExpressionTreeContainsMultiDimensionalArrayInitializer: - case ErrorCode.ERR_MissingArgument: - case ErrorCode.ERR_VariableUsedBeforeDeclaration: - case ErrorCode.ERR_UnassignedThisAutoPropertyUnsupportedVersion: - case ErrorCode.ERR_VariableUsedBeforeDeclarationAndHidesField: - case ErrorCode.ERR_ExpressionTreeContainsBadCoalesce: - case ErrorCode.ERR_ArrayInitializerExpected: - case ErrorCode.ERR_ArrayInitializerIncorrectLength: - case ErrorCode.ERR_ExpressionTreeContainsNamedArgument: - case ErrorCode.ERR_ExpressionTreeContainsOptionalArgument: - case ErrorCode.ERR_ExpressionTreeContainsIndexedProperty: - case ErrorCode.ERR_IndexedPropertyRequiresParams: - case ErrorCode.ERR_IndexedPropertyMustHaveAllOptionalParams: - case ErrorCode.ERR_IdentifierExpected: - case ErrorCode.ERR_SemicolonExpected: - case ErrorCode.ERR_SyntaxError: - case ErrorCode.ERR_DuplicateModifier: - case ErrorCode.ERR_DuplicateAccessor: - case ErrorCode.ERR_IntegralTypeExpected: - case ErrorCode.ERR_IllegalEscape: - case ErrorCode.ERR_NewlineInConst: - case ErrorCode.ERR_EmptyCharConst: - case ErrorCode.ERR_TooManyCharsInConst: - case ErrorCode.ERR_InvalidNumber: - case ErrorCode.ERR_GetOrSetExpected: - case ErrorCode.ERR_ClassTypeExpected: - case ErrorCode.ERR_NamedArgumentExpected: - case ErrorCode.ERR_TooManyCatches: - case ErrorCode.ERR_ThisOrBaseExpected: - case ErrorCode.ERR_OvlUnaryOperatorExpected: - case ErrorCode.ERR_OvlBinaryOperatorExpected: - case ErrorCode.ERR_IntOverflow: - case ErrorCode.ERR_EOFExpected: - case ErrorCode.ERR_BadEmbeddedStmt: - case ErrorCode.ERR_PPDirectiveExpected: - case ErrorCode.ERR_EndOfPPLineExpected: - case ErrorCode.ERR_CloseParenExpected: - case ErrorCode.ERR_EndifDirectiveExpected: - case ErrorCode.ERR_UnexpectedDirective: - case ErrorCode.ERR_ErrorDirective: - case ErrorCode.WRN_WarningDirective: - case ErrorCode.ERR_TypeExpected: - case ErrorCode.ERR_PPDefFollowsToken: - case ErrorCode.ERR_OpenEndedComment: - case ErrorCode.ERR_OvlOperatorExpected: - case ErrorCode.ERR_EndRegionDirectiveExpected: - case ErrorCode.ERR_UnterminatedStringLit: - case ErrorCode.ERR_BadDirectivePlacement: - case ErrorCode.ERR_IdentifierExpectedKW: - case ErrorCode.ERR_SemiOrLBraceExpected: - case ErrorCode.ERR_MultiTypeInDeclaration: - case ErrorCode.ERR_AddOrRemoveExpected: - case ErrorCode.ERR_UnexpectedCharacter: - case ErrorCode.ERR_ProtectedInStatic: - case ErrorCode.WRN_UnreachableGeneralCatch: - case ErrorCode.ERR_IncrementLvalueExpected: - case ErrorCode.ERR_NoSuchMemberOrExtension: - case ErrorCode.WRN_DeprecatedCollectionInitAddStr: - case ErrorCode.ERR_DeprecatedCollectionInitAddStr: - case ErrorCode.WRN_DeprecatedCollectionInitAdd: - case ErrorCode.ERR_DefaultValueNotAllowed: - case ErrorCode.WRN_DefaultValueForUnconsumedLocation: - case ErrorCode.ERR_PartialWrongTypeParamsVariance: - case ErrorCode.ERR_GlobalSingleTypeNameNotFoundFwd: - case ErrorCode.ERR_DottedTypeNameNotFoundInNSFwd: - case ErrorCode.ERR_SingleTypeNameNotFoundFwd: - case ErrorCode.WRN_IdentifierOrNumericLiteralExpected: - case ErrorCode.ERR_UnexpectedToken: - case ErrorCode.ERR_BadThisParam: - case ErrorCode.ERR_BadTypeforThis: - case ErrorCode.ERR_BadParamModThis: - case ErrorCode.ERR_BadExtensionMeth: - case ErrorCode.ERR_BadExtensionAgg: - case ErrorCode.ERR_DupParamMod: - case ErrorCode.ERR_ExtensionMethodsDecl: - case ErrorCode.ERR_ExtensionAttrNotFound: - case ErrorCode.ERR_ExplicitExtension: - case ErrorCode.ERR_ValueTypeExtDelegate: - case ErrorCode.ERR_BadArgCount: - case ErrorCode.ERR_BadArgType: - case ErrorCode.ERR_NoSourceFile: - case ErrorCode.ERR_CantRefResource: - case ErrorCode.ERR_ResourceNotUnique: - case ErrorCode.ERR_ImportNonAssembly: - case ErrorCode.ERR_RefLvalueExpected: - case ErrorCode.ERR_BaseInStaticMeth: - case ErrorCode.ERR_BaseInBadContext: - case ErrorCode.ERR_RbraceExpected: - case ErrorCode.ERR_LbraceExpected: - case ErrorCode.ERR_InExpected: - case ErrorCode.ERR_InvalidPreprocExpr: - case ErrorCode.ERR_InvalidMemberDecl: - case ErrorCode.ERR_MemberNeedsType: - case ErrorCode.ERR_BadBaseType: - case ErrorCode.WRN_EmptySwitch: - case ErrorCode.ERR_ExpectedEndTry: - case ErrorCode.ERR_InvalidExprTerm: - case ErrorCode.ERR_BadNewExpr: - case ErrorCode.ERR_NoNamespacePrivate: - case ErrorCode.ERR_BadVarDecl: - case ErrorCode.ERR_UsingAfterElements: - case ErrorCode.ERR_BadBinOpArgs: - case ErrorCode.ERR_BadUnOpArgs: - case ErrorCode.ERR_NoVoidParameter: - case ErrorCode.ERR_DuplicateAlias: - case ErrorCode.ERR_BadProtectedAccess: - case ErrorCode.ERR_AddModuleAssembly: - case ErrorCode.ERR_BindToBogusProp2: - case ErrorCode.ERR_BindToBogusProp1: - case ErrorCode.ERR_NoVoidHere: - case ErrorCode.ERR_IndexerNeedsParam: - case ErrorCode.ERR_BadArraySyntax: - case ErrorCode.ERR_BadOperatorSyntax: - case ErrorCode.ERR_OutputNeedsName: - case ErrorCode.ERR_CantHaveWin32ResAndManifest: - case ErrorCode.ERR_CantHaveWin32ResAndIcon: - case ErrorCode.ERR_CantReadResource: - case ErrorCode.ERR_DocFileGen: - case ErrorCode.WRN_XMLParseError: - case ErrorCode.WRN_DuplicateParamTag: - case ErrorCode.WRN_UnmatchedParamTag: - case ErrorCode.WRN_MissingParamTag: - case ErrorCode.WRN_BadXMLRef: - case ErrorCode.ERR_BadStackAllocExpr: - case ErrorCode.ERR_InvalidLineNumber: - case ErrorCode.ERR_MissingPPFile: - case ErrorCode.ERR_ForEachMissingMember: - case ErrorCode.WRN_BadXMLRefParamType: - case ErrorCode.WRN_BadXMLRefReturnType: - case ErrorCode.ERR_BadWin32Res: - case ErrorCode.WRN_BadXMLRefSyntax: - case ErrorCode.ERR_BadModifierLocation: - case ErrorCode.ERR_MissingArraySize: - case ErrorCode.WRN_UnprocessedXMLComment: - case ErrorCode.WRN_FailedInclude: - case ErrorCode.WRN_InvalidInclude: - case ErrorCode.WRN_MissingXMLComment: - case ErrorCode.WRN_XMLParseIncludeError: - case ErrorCode.ERR_BadDelArgCount: - case ErrorCode.ERR_UnexpectedSemicolon: - case ErrorCode.ERR_MethodReturnCantBeRefAny: - case ErrorCode.ERR_CompileCancelled: - case ErrorCode.ERR_MethodArgCantBeRefAny: - case ErrorCode.ERR_AssgReadonlyLocal: - case ErrorCode.ERR_RefReadonlyLocal: - case ErrorCode.ERR_CantUseRequiredAttribute: - case ErrorCode.ERR_NoModifiersOnAccessor: - case ErrorCode.ERR_ParamsCantBeWithModifier: - case ErrorCode.ERR_ReturnNotLValue: - case ErrorCode.ERR_MissingCoClass: - case ErrorCode.ERR_AmbiguousAttribute: - case ErrorCode.ERR_BadArgExtraRef: - case ErrorCode.WRN_CmdOptionConflictsSource: - case ErrorCode.ERR_BadCompatMode: - case ErrorCode.ERR_DelegateOnConditional: - case ErrorCode.ERR_CantMakeTempFile: - case ErrorCode.ERR_BadArgRef: - case ErrorCode.ERR_YieldInAnonMeth: - case ErrorCode.ERR_ReturnInIterator: - case ErrorCode.ERR_BadIteratorArgType: - case ErrorCode.ERR_BadIteratorReturn: - case ErrorCode.ERR_BadYieldInFinally: - case ErrorCode.ERR_BadYieldInTryOfCatch: - case ErrorCode.ERR_EmptyYield: - case ErrorCode.ERR_AnonDelegateCantUse: - case ErrorCode.ERR_AnonDelegateCantUseRefLike: - case ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRef: - case ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefLike: - case ErrorCode.ERR_AnonDelegateCantUseStructPrimaryConstructorParameterInMember: - case ErrorCode.ERR_AnonDelegateCantUseStructPrimaryConstructorParameterCaptured: - case ErrorCode.ERR_IllegalInnerUnsafe: - case ErrorCode.ERR_BadYieldInCatch: - case ErrorCode.ERR_BadDelegateLeave: - case ErrorCode.WRN_IllegalPragma: - case ErrorCode.WRN_IllegalPPWarning: - case ErrorCode.WRN_BadRestoreNumber: - case ErrorCode.ERR_VarargsIterator: - case ErrorCode.ERR_UnsafeIteratorArgType: - case ErrorCode.ERR_BadCoClassSig: - case ErrorCode.ERR_MultipleIEnumOfT: - case ErrorCode.ERR_FixedDimsRequired: - case ErrorCode.ERR_FixedNotInStruct: - case ErrorCode.ERR_AnonymousReturnExpected: - case ErrorCode.WRN_NonECMAFeature: - case ErrorCode.ERR_ExpectedVerbatimLiteral: - case ErrorCode.ERR_AssgReadonly2: - case ErrorCode.ERR_RefReadonly2: - case ErrorCode.ERR_AssgReadonlyStatic2: - case ErrorCode.ERR_RefReadonlyStatic2: - case ErrorCode.ERR_AssgReadonlyLocal2Cause: - case ErrorCode.ERR_RefReadonlyLocal2Cause: - case ErrorCode.ERR_AssgReadonlyLocalCause: - case ErrorCode.ERR_RefReadonlyLocalCause: - case ErrorCode.WRN_ErrorOverride: - case ErrorCode.ERR_AnonMethToNonDel: - case ErrorCode.ERR_CantConvAnonMethParams: - case ErrorCode.ERR_CantConvAnonMethReturns: - case ErrorCode.ERR_IllegalFixedType: - case ErrorCode.ERR_FixedOverflow: - case ErrorCode.ERR_InvalidFixedArraySize: - case ErrorCode.ERR_FixedBufferNotFixed: - case ErrorCode.ERR_AttributeNotOnAccessor: - case ErrorCode.WRN_InvalidSearchPathDir: - case ErrorCode.ERR_IllegalVarArgs: - case ErrorCode.ERR_IllegalParams: - case ErrorCode.ERR_BadModifiersOnNamespace: - case ErrorCode.ERR_BadPlatformType: - case ErrorCode.ERR_ThisStructNotInAnonMeth: - case ErrorCode.ERR_NoConvToIDisp: - case ErrorCode.ERR_BadParamRef: - case ErrorCode.ERR_BadParamExtraRef: - case ErrorCode.ERR_BadParamType: - case ErrorCode.ERR_BadExternIdentifier: - case ErrorCode.ERR_AliasMissingFile: - case ErrorCode.ERR_GlobalExternAlias: - case ErrorCode.WRN_MultiplePredefTypes: - case ErrorCode.ERR_LocalCantBeFixedAndHoisted: - case ErrorCode.WRN_TooManyLinesForDebugger: - case ErrorCode.ERR_CantConvAnonMethNoParams: - case ErrorCode.ERR_ConditionalOnNonAttributeClass: - case ErrorCode.WRN_CallOnNonAgileField: - case ErrorCode.WRN_InvalidNumber: - case ErrorCode.WRN_IllegalPPChecksum: - case ErrorCode.WRN_EndOfPPLineExpected: - case ErrorCode.WRN_ConflictingChecksum: - case ErrorCode.WRN_InvalidAssemblyName: - case ErrorCode.WRN_UnifyReferenceMajMin: - case ErrorCode.WRN_UnifyReferenceBldRev: - case ErrorCode.ERR_DuplicateImport: - case ErrorCode.ERR_DuplicateImportSimple: - case ErrorCode.ERR_AssemblyMatchBadVersion: - case ErrorCode.ERR_FixedNeedsLvalue: - case ErrorCode.WRN_DuplicateTypeParamTag: - case ErrorCode.WRN_UnmatchedTypeParamTag: - case ErrorCode.WRN_MissingTypeParamTag: - case ErrorCode.ERR_CantChangeTypeOnOverride: - case ErrorCode.ERR_DoNotUseFixedBufferAttr: - case ErrorCode.WRN_AssignmentToSelf: - case ErrorCode.WRN_ComparisonToSelf: - case ErrorCode.ERR_CantOpenWin32Res: - case ErrorCode.WRN_DotOnDefault: - case ErrorCode.ERR_NoMultipleInheritance: - case ErrorCode.ERR_BaseClassMustBeFirst: - case ErrorCode.WRN_BadXMLRefTypeVar: - case ErrorCode.ERR_FriendAssemblyBadArgs: - case ErrorCode.ERR_FriendAssemblySNReq: - case ErrorCode.ERR_DelegateOnNullable: - case ErrorCode.ERR_BadCtorArgCount: - case ErrorCode.ERR_GlobalAttributesNotFirst: - case ErrorCode.ERR_ExpressionExpected: - case ErrorCode.WRN_UnmatchedParamRefTag: - case ErrorCode.WRN_UnmatchedTypeParamRefTag: - case ErrorCode.ERR_DefaultValueMustBeConstant: - case ErrorCode.ERR_DefaultValueBeforeRequiredValue: - case ErrorCode.ERR_NamedArgumentSpecificationBeforeFixedArgument: - case ErrorCode.ERR_BadNamedArgument: - case ErrorCode.ERR_DuplicateNamedArgument: - case ErrorCode.ERR_RefOutDefaultValue: - case ErrorCode.ERR_NamedArgumentForArray: - case ErrorCode.ERR_DefaultValueForExtensionParameter: - case ErrorCode.ERR_NamedArgumentUsedInPositional: - case ErrorCode.ERR_DefaultValueUsedWithAttributes: - case ErrorCode.ERR_BadNamedArgumentForDelegateInvoke: - case ErrorCode.ERR_NoPIAAssemblyMissingAttribute: - case ErrorCode.ERR_NoCanonicalView: - case ErrorCode.ERR_NoConversionForDefaultParam: - case ErrorCode.ERR_DefaultValueForParamsParameter: - case ErrorCode.ERR_NewCoClassOnLink: - case ErrorCode.ERR_NoPIANestedType: - case ErrorCode.ERR_InteropTypeMissingAttribute: - case ErrorCode.ERR_InteropStructContainsMethods: - case ErrorCode.ERR_InteropTypesWithSameNameAndGuid: - case ErrorCode.ERR_NoPIAAssemblyMissingAttributes: - case ErrorCode.ERR_AssemblySpecifiedForLinkAndRef: - case ErrorCode.ERR_LocalTypeNameClash: - case ErrorCode.WRN_ReferencedAssemblyReferencesLinkedPIA: - case ErrorCode.ERR_NotNullRefDefaultParameter: - case ErrorCode.ERR_FixedLocalInLambda: - case ErrorCode.ERR_MissingMethodOnSourceInterface: - case ErrorCode.ERR_MissingSourceInterface: - case ErrorCode.ERR_GenericsUsedInNoPIAType: - case ErrorCode.ERR_GenericsUsedAcrossAssemblies: - case ErrorCode.ERR_NoConversionForNubDefaultParam: - case ErrorCode.ERR_InvalidSubsystemVersion: - case ErrorCode.ERR_InteropMethodWithBody: - case ErrorCode.ERR_BadWarningLevel: - case ErrorCode.ERR_BadDebugType: - case ErrorCode.ERR_BadResourceVis: - case ErrorCode.ERR_DefaultValueTypeMustMatch: - case ErrorCode.ERR_DefaultValueBadValueType: - case ErrorCode.ERR_MemberAlreadyInitialized: - case ErrorCode.ERR_MemberCannotBeInitialized: - case ErrorCode.ERR_StaticMemberInObjectInitializer: - case ErrorCode.ERR_ReadonlyValueTypeInObjectInitializer: - case ErrorCode.ERR_ValueTypePropertyInObjectInitializer: - case ErrorCode.ERR_UnsafeTypeInObjectCreation: - case ErrorCode.ERR_EmptyElementInitializer: - case ErrorCode.ERR_InitializerAddHasWrongSignature: - case ErrorCode.ERR_CollectionInitRequiresIEnumerable: - case ErrorCode.ERR_CantOpenWin32Manifest: - case ErrorCode.WRN_CantHaveManifestForModule: - case ErrorCode.ERR_BadInstanceArgType: - case ErrorCode.ERR_QueryDuplicateRangeVariable: - case ErrorCode.ERR_QueryRangeVariableOverrides: - case ErrorCode.ERR_QueryRangeVariableAssignedBadValue: - case ErrorCode.ERR_QueryNoProviderCastable: - case ErrorCode.ERR_QueryNoProviderStandard: - case ErrorCode.ERR_QueryNoProvider: - case ErrorCode.ERR_QueryOuterKey: - case ErrorCode.ERR_QueryInnerKey: - case ErrorCode.ERR_QueryOutRefRangeVariable: - case ErrorCode.ERR_QueryMultipleProviders: - case ErrorCode.ERR_QueryTypeInferenceFailedMulti: - case ErrorCode.ERR_QueryTypeInferenceFailed: - case ErrorCode.ERR_QueryTypeInferenceFailedSelectMany: - case ErrorCode.ERR_ExpressionTreeContainsPointerOp: - case ErrorCode.ERR_ExpressionTreeContainsAnonymousMethod: - case ErrorCode.ERR_AnonymousMethodToExpressionTree: - case ErrorCode.ERR_QueryRangeVariableReadOnly: - case ErrorCode.ERR_QueryRangeVariableSameAsTypeParam: - case ErrorCode.ERR_TypeVarNotFoundRangeVariable: - case ErrorCode.ERR_BadArgTypesForCollectionAdd: - case ErrorCode.ERR_ByRefParameterInExpressionTree: - case ErrorCode.ERR_VarArgsInExpressionTree: - case ErrorCode.ERR_InitializerAddHasParamModifiers: - case ErrorCode.ERR_NonInvocableMemberCalled: - case ErrorCode.WRN_MultipleRuntimeImplementationMatches: - case ErrorCode.WRN_MultipleRuntimeOverrideMatches: - case ErrorCode.ERR_ObjectOrCollectionInitializerWithDelegateCreation: - case ErrorCode.ERR_InvalidConstantDeclarationType: - case ErrorCode.ERR_IllegalVarianceSyntax: - case ErrorCode.ERR_UnexpectedVariance: - case ErrorCode.ERR_BadDynamicTypeof: - case ErrorCode.ERR_ExpressionTreeContainsDynamicOperation: - case ErrorCode.ERR_BadDynamicConversion: - case ErrorCode.ERR_DeriveFromDynamic: - case ErrorCode.ERR_DeriveFromConstructedDynamic: - case ErrorCode.ERR_DynamicTypeAsBound: - case ErrorCode.ERR_ConstructedDynamicTypeAsBound: - case ErrorCode.ERR_ExplicitDynamicAttr: - case ErrorCode.ERR_NoDynamicPhantomOnBase: - case ErrorCode.ERR_NoDynamicPhantomOnBaseIndexer: - case ErrorCode.ERR_BadArgTypeDynamicExtension: - case ErrorCode.WRN_DynamicDispatchToConditionalMethod: - case ErrorCode.ERR_NoDynamicPhantomOnBaseCtor: - case ErrorCode.ERR_BadDynamicMethodArgMemgrp: - case ErrorCode.ERR_BadDynamicMethodArgLambda: - case ErrorCode.ERR_BadDynamicMethodArg: - case ErrorCode.ERR_BadDynamicQuery: - case ErrorCode.ERR_DynamicAttributeMissing: - case ErrorCode.WRN_IsDynamicIsConfusing: - case ErrorCode.ERR_BadAsyncReturn: - case ErrorCode.ERR_BadAwaitInFinally: - case ErrorCode.ERR_BadAwaitInCatch: - case ErrorCode.ERR_BadAwaitArg: - case ErrorCode.ERR_BadAsyncArgType: - case ErrorCode.ERR_BadAsyncExpressionTree: - case ErrorCode.ERR_MixingWinRTEventWithRegular: - case ErrorCode.ERR_BadAwaitWithoutAsync: - case ErrorCode.ERR_BadAsyncLacksBody: - case ErrorCode.ERR_BadAwaitInQuery: - case ErrorCode.ERR_BadAwaitInLock: - case ErrorCode.ERR_TaskRetNoObjectRequired: - case ErrorCode.WRN_AsyncLacksAwaits: - case ErrorCode.ERR_FileNotFound: - case ErrorCode.WRN_FileAlreadyIncluded: - case ErrorCode.ERR_NoFileSpec: - case ErrorCode.ERR_SwitchNeedsString: - case ErrorCode.ERR_BadSwitch: - case ErrorCode.WRN_NoSources: - case ErrorCode.ERR_OpenResponseFile: - case ErrorCode.ERR_CantOpenFileWrite: - case ErrorCode.ERR_BadBaseNumber: - case ErrorCode.ERR_BinaryFile: - case ErrorCode.FTL_BadCodepage: - case ErrorCode.ERR_NoMainOnDLL: - case ErrorCode.FTL_InvalidTarget: - case ErrorCode.FTL_InvalidInputFileName: - case ErrorCode.WRN_NoConfigNotOnCommandLine: - case ErrorCode.ERR_InvalidFileAlignment: - case ErrorCode.WRN_DefineIdentifierRequired: - case ErrorCode.FTL_OutputFileExists: - case ErrorCode.ERR_OneAliasPerReference: - case ErrorCode.ERR_SwitchNeedsNumber: - case ErrorCode.ERR_MissingDebugSwitch: - case ErrorCode.ERR_ComRefCallInExpressionTree: - case ErrorCode.WRN_BadUILang: - case ErrorCode.ERR_InvalidFormatForGuidForOption: - case ErrorCode.ERR_MissingGuidForOption: - case ErrorCode.ERR_InvalidOutputName: - case ErrorCode.ERR_InvalidDebugInformationFormat: - case ErrorCode.ERR_LegacyObjectIdSyntax: - case ErrorCode.ERR_SourceLinkRequiresPdb: - case ErrorCode.ERR_CannotEmbedWithoutPdb: - case ErrorCode.ERR_BadSwitchValue: - case ErrorCode.WRN_CLS_NoVarArgs: - case ErrorCode.WRN_CLS_BadArgType: - case ErrorCode.WRN_CLS_BadReturnType: - case ErrorCode.WRN_CLS_BadFieldPropType: - case ErrorCode.WRN_CLS_BadIdentifierCase: - case ErrorCode.WRN_CLS_OverloadRefOut: - case ErrorCode.WRN_CLS_OverloadUnnamed: - case ErrorCode.WRN_CLS_BadIdentifier: - case ErrorCode.WRN_CLS_BadBase: - case ErrorCode.WRN_CLS_BadInterfaceMember: - case ErrorCode.WRN_CLS_NoAbstractMembers: - case ErrorCode.WRN_CLS_NotOnModules: - case ErrorCode.WRN_CLS_ModuleMissingCLS: - case ErrorCode.WRN_CLS_AssemblyNotCLS: - case ErrorCode.WRN_CLS_BadAttributeType: - case ErrorCode.WRN_CLS_ArrayArgumentToAttribute: - case ErrorCode.WRN_CLS_NotOnModules2: - case ErrorCode.WRN_CLS_IllegalTrueInFalse: - case ErrorCode.WRN_CLS_MeaninglessOnPrivateType: - case ErrorCode.WRN_CLS_AssemblyNotCLS2: - case ErrorCode.WRN_CLS_MeaninglessOnParam: - case ErrorCode.WRN_CLS_MeaninglessOnReturn: - case ErrorCode.WRN_CLS_BadTypeVar: - case ErrorCode.WRN_CLS_VolatileField: - case ErrorCode.WRN_CLS_BadInterface: - case ErrorCode.FTL_BadChecksumAlgorithm: - case ErrorCode.ERR_BadAwaitArgIntrinsic: - case ErrorCode.ERR_BadAwaitAsIdentifier: - case ErrorCode.ERR_AwaitInUnsafeContext: - case ErrorCode.ERR_UnsafeAsyncArgType: - case ErrorCode.ERR_VarargsAsync: - case ErrorCode.ERR_BadAwaitArgVoidCall: - case ErrorCode.ERR_NonTaskMainCantBeAsync: - case ErrorCode.ERR_CantConvAsyncAnonFuncReturns: - case ErrorCode.ERR_BadAwaiterPattern: - case ErrorCode.ERR_BadSpecialByRefLocal: - case ErrorCode.WRN_UnobservedAwaitableExpression: - case ErrorCode.ERR_SynchronizedAsyncMethod: - case ErrorCode.ERR_BadAsyncReturnExpression: - case ErrorCode.ERR_NoConversionForCallerLineNumberParam: - case ErrorCode.ERR_NoConversionForCallerFilePathParam: - case ErrorCode.ERR_NoConversionForCallerMemberNameParam: - case ErrorCode.ERR_BadCallerLineNumberParamWithoutDefaultValue: - case ErrorCode.ERR_BadCallerFilePathParamWithoutDefaultValue: - case ErrorCode.ERR_BadCallerMemberNameParamWithoutDefaultValue: - case ErrorCode.ERR_BadPrefer32OnLib: - case ErrorCode.WRN_CallerLineNumberParamForUnconsumedLocation: - case ErrorCode.WRN_CallerFilePathParamForUnconsumedLocation: - case ErrorCode.WRN_CallerMemberNameParamForUnconsumedLocation: - case ErrorCode.ERR_DoesntImplementAwaitInterface: - case ErrorCode.ERR_BadAwaitArg_NeedSystem: - case ErrorCode.ERR_CantReturnVoid: - case ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync: - case ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct: - case ErrorCode.ERR_BadAwaitWithoutAsyncMethod: - case ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod: - case ErrorCode.ERR_BadAwaitWithoutAsyncLambda: - case ErrorCode.ERR_NoSuchMemberOrExtensionNeedUsing: - case ErrorCode.ERR_UnexpectedAliasedName: - case ErrorCode.ERR_UnexpectedGenericName: - case ErrorCode.ERR_UnexpectedUnboundGenericName: - case ErrorCode.ERR_GlobalStatement: - case ErrorCode.ERR_BadUsingType: - case ErrorCode.ERR_ReservedAssemblyName: - case ErrorCode.ERR_PPReferenceFollowsToken: - case ErrorCode.ERR_ExpectedPPFile: - case ErrorCode.ERR_ReferenceDirectiveOnlyAllowedInScripts: - case ErrorCode.ERR_NameNotInContextPossibleMissingReference: - case ErrorCode.ERR_MetadataNameTooLong: - case ErrorCode.ERR_AttributesNotAllowed: - case ErrorCode.ERR_ExternAliasNotAllowed: - case ErrorCode.ERR_ConflictingAliasAndDefinition: - case ErrorCode.ERR_GlobalDefinitionOrStatementExpected: - case ErrorCode.ERR_ExpectedSingleScript: - case ErrorCode.ERR_RecursivelyTypedVariable: - case ErrorCode.ERR_YieldNotAllowedInScript: - case ErrorCode.ERR_NamespaceNotAllowedInScript: - case ErrorCode.WRN_StaticInAsOrIs: - case ErrorCode.ERR_InvalidDelegateType: - case ErrorCode.ERR_BadVisEventType: - case ErrorCode.ERR_GlobalAttributesNotAllowed: - case ErrorCode.ERR_PublicKeyFileFailure: - case ErrorCode.ERR_PublicKeyContainerFailure: - case ErrorCode.ERR_FriendRefSigningMismatch: - case ErrorCode.ERR_CannotPassNullForFriendAssembly: - case ErrorCode.ERR_SignButNoPrivateKey: - case ErrorCode.WRN_DelaySignButNoKey: - case ErrorCode.ERR_InvalidVersionFormat: - case ErrorCode.WRN_InvalidVersionFormat: - case ErrorCode.ERR_NoCorrespondingArgument: - case ErrorCode.ERR_ResourceFileNameNotUnique: - case ErrorCode.ERR_DllImportOnGenericMethod: - case ErrorCode.ERR_EncUpdateFailedMissingAttribute: - case ErrorCode.ERR_ParameterNotValidForType: - case ErrorCode.ERR_AttributeParameterRequired1: - case ErrorCode.ERR_AttributeParameterRequired2: - case ErrorCode.ERR_SecurityAttributeMissingAction: - case ErrorCode.ERR_SecurityAttributeInvalidAction: - case ErrorCode.ERR_SecurityAttributeInvalidActionAssembly: - case ErrorCode.ERR_SecurityAttributeInvalidActionTypeOrMethod: - case ErrorCode.ERR_PrincipalPermissionInvalidAction: - case ErrorCode.ERR_FeatureNotValidInExpressionTree: - case ErrorCode.ERR_MarshalUnmanagedTypeNotValidForFields: - case ErrorCode.ERR_MarshalUnmanagedTypeOnlyValidForFields: - case ErrorCode.ERR_PermissionSetAttributeInvalidFile: - case ErrorCode.ERR_PermissionSetAttributeFileReadError: - case ErrorCode.ERR_InvalidVersionFormat2: - case ErrorCode.ERR_InvalidAssemblyCultureForExe: - case ErrorCode.ERR_DuplicateAttributeInNetModule: - case ErrorCode.ERR_CantOpenIcon: - case ErrorCode.ERR_ErrorBuildingWin32Resources: - case ErrorCode.ERR_BadAttributeParamDefaultArgument: - case ErrorCode.ERR_MissingTypeInSource: - case ErrorCode.ERR_MissingTypeInAssembly: - case ErrorCode.ERR_SecurityAttributeInvalidTarget: - case ErrorCode.ERR_InvalidAssemblyName: - case ErrorCode.ERR_NoTypeDefFromModule: - case ErrorCode.WRN_CallerFilePathPreferredOverCallerMemberName: - case ErrorCode.WRN_CallerLineNumberPreferredOverCallerMemberName: - case ErrorCode.WRN_CallerLineNumberPreferredOverCallerFilePath: - case ErrorCode.ERR_InvalidDynamicCondition: - case ErrorCode.ERR_WinRtEventPassedByRef: - case ErrorCode.ERR_NetModuleNameMismatch: - case ErrorCode.ERR_BadModuleName: - case ErrorCode.ERR_BadCompilationOptionValue: - case ErrorCode.ERR_BadAppConfigPath: - case ErrorCode.WRN_AssemblyAttributeFromModuleIsOverridden: - case ErrorCode.ERR_CmdOptionConflictsSource: - case ErrorCode.ERR_FixedBufferTooManyDimensions: - case ErrorCode.ERR_CantReadConfigFile: - case ErrorCode.ERR_BadAwaitInCatchFilter: - case ErrorCode.WRN_FilterIsConstantTrue: - case ErrorCode.ERR_EncNoPIAReference: - case ErrorCode.ERR_LinkedNetmoduleMetadataMustProvideFullPEImage: - case ErrorCode.ERR_MetadataReferencesNotSupported: - case ErrorCode.ERR_InvalidAssemblyCulture: - case ErrorCode.ERR_EncReferenceToAddedMember: - case ErrorCode.ERR_MutuallyExclusiveOptions: - case ErrorCode.ERR_InvalidDebugInfo: - case ErrorCode.WRN_UnimplementedCommandLineSwitch: - case ErrorCode.WRN_ReferencedAssemblyDoesNotHaveStrongName: - case ErrorCode.ERR_InvalidSignaturePublicKey: - case ErrorCode.ERR_ForwardedTypesConflict: - case ErrorCode.WRN_RefCultureMismatch: - case ErrorCode.ERR_AgnosticToMachineModule: - case ErrorCode.ERR_ConflictingMachineModule: - case ErrorCode.WRN_ConflictingMachineAssembly: - case ErrorCode.ERR_CryptoHashFailed: - case ErrorCode.ERR_MissingNetModuleReference: - case ErrorCode.ERR_NetModuleNameMustBeUnique: - case ErrorCode.ERR_UnsupportedTransparentIdentifierAccess: - case ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute: - case ErrorCode.WRN_UnqualifiedNestedTypeInCref: - case ErrorCode.HDN_UnusedUsingDirective: - case ErrorCode.HDN_UnusedExternAlias: - case ErrorCode.WRN_NoRuntimeMetadataVersion: - case ErrorCode.ERR_FeatureNotAvailableInVersion1: - case ErrorCode.ERR_FeatureNotAvailableInVersion2: - case ErrorCode.ERR_FeatureNotAvailableInVersion3: - case ErrorCode.ERR_FeatureNotAvailableInVersion4: - case ErrorCode.ERR_FeatureNotAvailableInVersion5: - case ErrorCode.ERR_FieldHasMultipleDistinctConstantValues: - case ErrorCode.ERR_ComImportWithInitializers: - case ErrorCode.WRN_PdbLocalNameTooLong: - case ErrorCode.ERR_RetNoObjectRequiredLambda: - case ErrorCode.ERR_TaskRetNoObjectRequiredLambda: - case ErrorCode.WRN_AnalyzerCannotBeCreated: - case ErrorCode.WRN_NoAnalyzerInAssembly: - case ErrorCode.WRN_UnableToLoadAnalyzer: - case ErrorCode.ERR_CantReadRulesetFile: - case ErrorCode.ERR_BadPdbData: - case ErrorCode.INF_UnableToLoadSomeTypesInAnalyzer: - case ErrorCode.ERR_InitializerOnNonAutoProperty: - case ErrorCode.ERR_AutoPropertyMustHaveGetAccessor: - case ErrorCode.ERR_InstancePropertyInitializerInInterface: - case ErrorCode.ERR_EnumsCantContainDefaultConstructor: - case ErrorCode.ERR_EncodinglessSyntaxTree: - case ErrorCode.ERR_BlockBodyAndExpressionBody: - case ErrorCode.ERR_FeatureIsExperimental: - case ErrorCode.ERR_FeatureNotAvailableInVersion6: - case ErrorCode.ERR_SwitchFallOut: - case ErrorCode.ERR_NullPropagatingOpInExpressionTree: - case ErrorCode.WRN_NubExprIsConstBool2: - case ErrorCode.ERR_DictionaryInitializerInExpressionTree: - case ErrorCode.ERR_ExtensionCollectionElementInitializerInExpressionTree: - case ErrorCode.ERR_UnclosedExpressionHole: - case ErrorCode.ERR_UseDefViolationProperty: - case ErrorCode.ERR_AutoPropertyMustOverrideSet: - case ErrorCode.ERR_ExpressionHasNoName: - case ErrorCode.ERR_SubexpressionNotInNameof: - case ErrorCode.ERR_AliasQualifiedNameNotAnExpression: - case ErrorCode.ERR_NameofMethodGroupWithTypeParameters: - case ErrorCode.ERR_NoAliasHere: - case ErrorCode.ERR_UnescapedCurly: - case ErrorCode.ERR_EscapedCurly: - case ErrorCode.ERR_TrailingWhitespaceInFormatSpecifier: - case ErrorCode.ERR_EmptyFormatSpecifier: - case ErrorCode.ERR_ErrorInReferencedAssembly: - case ErrorCode.ERR_ExternHasConstructorInitializer: - case ErrorCode.ERR_ExpressionOrDeclarationExpected: - case ErrorCode.ERR_NameofExtensionMethod: - case ErrorCode.WRN_AlignmentMagnitude: - case ErrorCode.ERR_ConstantStringTooLong: - case ErrorCode.ERR_DebugEntryPointNotSourceMethodDefinition: - case ErrorCode.ERR_LoadDirectiveOnlyAllowedInScripts: - case ErrorCode.ERR_PPLoadFollowsToken: - case ErrorCode.ERR_SourceFileReferencesNotSupported: - case ErrorCode.ERR_BadAwaitInStaticVariableInitializer: - case ErrorCode.ERR_InvalidPathMap: - case ErrorCode.ERR_PublicSignButNoKey: - case ErrorCode.ERR_TooManyUserStrings: - case ErrorCode.ERR_PeWritingFailure: - case ErrorCode.WRN_AttributeIgnoredWhenPublicSigning: - case ErrorCode.ERR_OptionMustBeAbsolutePath: - case ErrorCode.ERR_FeatureNotAvailableInVersion7: - case ErrorCode.ERR_DynamicLocalFunctionParamsParameter: - case ErrorCode.ERR_ExpressionTreeContainsLocalFunction: - case ErrorCode.ERR_InvalidInstrumentationKind: - case ErrorCode.ERR_LocalFunctionMissingBody: - case ErrorCode.ERR_InvalidHashAlgorithmName: - case ErrorCode.ERR_ThrowMisplaced: - case ErrorCode.ERR_PatternNullableType: - case ErrorCode.ERR_BadPatternExpression: - case ErrorCode.ERR_SwitchExpressionValueExpected: - case ErrorCode.ERR_SwitchCaseSubsumed: - case ErrorCode.ERR_PatternWrongType: - case ErrorCode.ERR_ExpressionTreeContainsIsMatch: - case ErrorCode.WRN_TupleLiteralNameMismatch: - case ErrorCode.ERR_TupleTooFewElements: - case ErrorCode.ERR_TupleReservedElementName: - case ErrorCode.ERR_TupleReservedElementNameAnyPosition: - case ErrorCode.ERR_TupleDuplicateElementName: - case ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly: - case ErrorCode.ERR_MissingDeconstruct: - case ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedDeconstructionVariable: - case ErrorCode.ERR_DeconstructRequiresExpression: - case ErrorCode.ERR_DeconstructWrongCardinality: - case ErrorCode.ERR_CannotDeconstructDynamic: - case ErrorCode.ERR_DeconstructTooFewElements: - case ErrorCode.ERR_ConversionNotTupleCompatible: - case ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType: - case ErrorCode.ERR_TupleElementNamesAttributeMissing: - case ErrorCode.ERR_ExplicitTupleElementNamesAttribute: - case ErrorCode.ERR_CantChangeTupleNamesOnOverride: - case ErrorCode.ERR_DuplicateInterfaceWithTupleNamesInBaseList: - case ErrorCode.ERR_ImplBadTupleNames: - case ErrorCode.ERR_PartialMethodInconsistentTupleNames: - case ErrorCode.ERR_ExpressionTreeContainsTupleLiteral: - case ErrorCode.ERR_ExpressionTreeContainsTupleConversion: - case ErrorCode.ERR_AutoPropertyCannotBeRefReturning: - case ErrorCode.ERR_RefPropertyMustHaveGetAccessor: - case ErrorCode.ERR_RefPropertyCannotHaveSetAccessor: - case ErrorCode.ERR_CantChangeRefReturnOnOverride: - case ErrorCode.ERR_MustNotHaveRefReturn: - case ErrorCode.ERR_MustHaveRefReturn: - case ErrorCode.ERR_RefReturnMustHaveIdentityConversion: - case ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn: - case ErrorCode.ERR_RefReturningCallInExpressionTree: - case ErrorCode.ERR_BadIteratorReturnRef: - case ErrorCode.ERR_BadRefReturnExpressionTree: - case ErrorCode.ERR_RefReturnLvalueExpected: - case ErrorCode.ERR_RefReturnNonreturnableLocal: - case ErrorCode.ERR_RefReturnNonreturnableLocal2: - case ErrorCode.ERR_RefReturnRangeVariable: - case ErrorCode.ERR_RefReturnReadonly: - case ErrorCode.ERR_RefReturnReadonlyStatic: - case ErrorCode.ERR_RefReturnReadonly2: - case ErrorCode.ERR_RefReturnReadonlyStatic2: - case ErrorCode.ERR_RefReturnParameter: - case ErrorCode.ERR_RefReturnParameter2: - case ErrorCode.ERR_RefReturnLocal: - case ErrorCode.ERR_RefReturnLocal2: - case ErrorCode.ERR_RefReturnStructThis: - case ErrorCode.ERR_InitializeByValueVariableWithReference: - case ErrorCode.ERR_InitializeByReferenceVariableWithValue: - case ErrorCode.ERR_RefAssignmentMustHaveIdentityConversion: - case ErrorCode.ERR_ByReferenceVariableMustBeInitialized: - case ErrorCode.ERR_AnonDelegateCantUseLocal: - case ErrorCode.ERR_BadIteratorLocalType: - case ErrorCode.ERR_BadAsyncLocalType: - case ErrorCode.ERR_PredefinedValueTupleTypeNotFound: - case ErrorCode.ERR_SemiOrLBraceOrArrowExpected: - case ErrorCode.ERR_NewWithTupleTypeSyntax: - case ErrorCode.ERR_PredefinedValueTupleTypeMustBeStruct: - case ErrorCode.ERR_DiscardTypeInferenceFailed: - case ErrorCode.ERR_DeclarationExpressionNotPermitted: - case ErrorCode.ERR_MustDeclareForeachIteration: - case ErrorCode.ERR_TupleElementNamesInDeconstruction: - case ErrorCode.ERR_ExpressionTreeContainsThrowExpression: - case ErrorCode.ERR_DelegateRefMismatch: - case ErrorCode.ERR_BadSourceCodeKind: - case ErrorCode.ERR_BadDocumentationMode: - case ErrorCode.ERR_BadLanguageVersion: - case ErrorCode.ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList: - case ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable: - case ErrorCode.ERR_ExpressionTreeContainsOutVariable: - case ErrorCode.ERR_VarInvocationLvalueReserved: - case ErrorCode.ERR_PublicSignNetModule: - case ErrorCode.ERR_BadAssemblyName: - case ErrorCode.ERR_BadAsyncMethodBuilderTaskProperty: - case ErrorCode.ERR_TypeForwardedToMultipleAssemblies: - case ErrorCode.ERR_ExpressionTreeContainsDiscard: - case ErrorCode.ERR_PatternDynamicType: - case ErrorCode.ERR_VoidAssignment: - case ErrorCode.ERR_VoidInTuple: - case ErrorCode.ERR_Merge_conflict_marker_encountered: - case ErrorCode.ERR_InvalidPreprocessingSymbol: - case ErrorCode.ERR_FeatureNotAvailableInVersion7_1: - case ErrorCode.ERR_LanguageVersionCannotHaveLeadingZeroes: - case ErrorCode.ERR_CompilerAndLanguageVersion: - case ErrorCode.WRN_WindowsExperimental: - case ErrorCode.ERR_TupleInferredNamesNotAvailable: - case ErrorCode.ERR_TypelessTupleInAs: - case ErrorCode.ERR_NoRefOutWhenRefOnly: - case ErrorCode.ERR_NoNetModuleOutputWhenRefOutOrRefOnly: - case ErrorCode.ERR_BadOpOnNullOrDefaultOrNew: - case ErrorCode.ERR_DefaultLiteralNotValid: - case ErrorCode.ERR_PatternWrongGenericTypeInVersion: - case ErrorCode.ERR_AmbigBinaryOpsOnDefault: - case ErrorCode.ERR_FeatureNotAvailableInVersion7_2: - case ErrorCode.WRN_UnreferencedLocalFunction: - case ErrorCode.ERR_DynamicLocalFunctionTypeParameter: - case ErrorCode.ERR_BadNonTrailingNamedArgument: - case ErrorCode.ERR_NamedArgumentSpecificationBeforeFixedArgumentInDynamicInvocation: - case ErrorCode.ERR_RefConditionalAndAwait: - case ErrorCode.ERR_RefConditionalNeedsTwoRefs: - case ErrorCode.ERR_RefConditionalDifferentTypes: - case ErrorCode.ERR_BadParameterModifiers: - case ErrorCode.ERR_RefReadonlyNotField: - case ErrorCode.ERR_RefReadonlyNotField2: - case ErrorCode.ERR_AssignReadonlyNotField: - case ErrorCode.ERR_AssignReadonlyNotField2: - case ErrorCode.ERR_RefReturnReadonlyNotField: - case ErrorCode.ERR_RefReturnReadonlyNotField2: - case ErrorCode.ERR_ExplicitReservedAttr: - case ErrorCode.ERR_TypeReserved: - case ErrorCode.ERR_RefExtensionMustBeValueTypeOrConstrainedToOne: - case ErrorCode.ERR_InExtensionMustBeValueType: - case ErrorCode.ERR_FieldsInRoStruct: - case ErrorCode.ERR_AutoPropsInRoStruct: - case ErrorCode.ERR_FieldlikeEventsInRoStruct: - case ErrorCode.ERR_RefStructInterfaceImpl: - case ErrorCode.ERR_BadSpecialByRefIterator: - case ErrorCode.ERR_FieldAutoPropCantBeByRefLike: - case ErrorCode.ERR_StackAllocConversionNotPossible: - case ErrorCode.ERR_EscapeCall: - case ErrorCode.ERR_EscapeCall2: - case ErrorCode.ERR_EscapeOther: - case ErrorCode.ERR_CallArgMixing: - case ErrorCode.ERR_MismatchedRefEscapeInTernary: - case ErrorCode.ERR_EscapeVariable: - case ErrorCode.ERR_EscapeStackAlloc: - case ErrorCode.ERR_RefReturnThis: - case ErrorCode.ERR_OutAttrOnInParam: - case ErrorCode.ERR_PredefinedValueTupleTypeAmbiguous3: - case ErrorCode.ERR_InvalidVersionFormatDeterministic: - case ErrorCode.ERR_AttributeCtorInParameter: - case ErrorCode.WRN_FilterIsConstantFalse: - case ErrorCode.WRN_FilterIsConstantFalseRedundantTryCatch: - case ErrorCode.ERR_ConditionalInInterpolation: - case ErrorCode.ERR_CantUseVoidInArglist: - case ErrorCode.ERR_InDynamicMethodArg: - case ErrorCode.ERR_FeatureNotAvailableInVersion7_3: - case ErrorCode.WRN_AttributesOnBackingFieldsNotAvailable: - case ErrorCode.ERR_DoNotUseFixedBufferAttrOnProperty: - case ErrorCode.ERR_RefLocalOrParamExpected: - case ErrorCode.ERR_RefAssignNarrower: - case ErrorCode.ERR_NewBoundWithUnmanaged: - case ErrorCode.ERR_UnmanagedConstraintNotSatisfied: - case ErrorCode.ERR_CantUseInOrOutInArglist: - case ErrorCode.ERR_ConWithUnmanagedCon: - case ErrorCode.ERR_UnmanagedBoundWithClass: - case ErrorCode.ERR_InvalidStackAllocArray: - case ErrorCode.ERR_ExpressionTreeContainsTupleBinOp: - case ErrorCode.WRN_TupleBinopLiteralNameMismatch: - case ErrorCode.ERR_TupleSizesMismatchForBinOps: - case ErrorCode.ERR_ExprCannotBeFixed: - case ErrorCode.ERR_InvalidObjectCreation: - case ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter: - case ErrorCode.ERR_OutVariableCannotBeByRef: - case ErrorCode.ERR_DeconstructVariableCannotBeByRef: - case ErrorCode.ERR_OmittedTypeArgument: - case ErrorCode.ERR_FeatureNotAvailableInVersion8: - case ErrorCode.ERR_AltInterpolatedVerbatimStringsNotAvailable: - case ErrorCode.ERR_IteratorMustBeAsync: - case ErrorCode.ERR_NoConvToIAsyncDisp: - case ErrorCode.ERR_AwaitForEachMissingMember: - case ErrorCode.ERR_BadGetAsyncEnumerator: - case ErrorCode.ERR_MultipleIAsyncEnumOfT: - case ErrorCode.ERR_ForEachMissingMemberWrongAsync: - case ErrorCode.ERR_AwaitForEachMissingMemberWrongAsync: - case ErrorCode.ERR_BadDynamicAwaitForEach: - case ErrorCode.ERR_NoConvToIAsyncDispWrongAsync: - case ErrorCode.ERR_NoConvToIDispWrongAsync: - case ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable: - case ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis: - case ErrorCode.ERR_AttributeNotOnEventAccessor: - case ErrorCode.WRN_UnconsumedEnumeratorCancellationAttributeUsage: - case ErrorCode.WRN_UndecoratedCancellationTokenParameter: - case ErrorCode.ERR_MultipleEnumeratorCancellationAttributes: - case ErrorCode.ERR_VarianceInterfaceNesting: - case ErrorCode.ERR_ImplicitIndexIndexerWithName: - case ErrorCode.ERR_ImplicitRangeIndexerWithName: - case ErrorCode.ERR_WrongNumberOfSubpatterns: - case ErrorCode.ERR_PropertyPatternNameMissing: - case ErrorCode.ERR_MissingPattern: - case ErrorCode.ERR_DefaultPattern: - case ErrorCode.ERR_SwitchExpressionNoBestType: - case ErrorCode.ERR_VarMayNotBindToType: - case ErrorCode.WRN_SwitchExpressionNotExhaustive: - case ErrorCode.ERR_SwitchArmSubsumed: - case ErrorCode.ERR_ConstantPatternVsOpenType: - case ErrorCode.WRN_CaseConstantNamedUnderscore: - case ErrorCode.WRN_IsTypeNamedUnderscore: - case ErrorCode.ERR_ExpressionTreeContainsSwitchExpression: - case ErrorCode.ERR_SwitchGoverningExpressionRequiresParens: - case ErrorCode.ERR_TupleElementNameMismatch: - case ErrorCode.ERR_DeconstructParameterNameMismatch: - case ErrorCode.ERR_IsPatternImpossible: - case ErrorCode.WRN_GivenExpressionNeverMatchesPattern: - case ErrorCode.WRN_GivenExpressionAlwaysMatchesConstant: - case ErrorCode.ERR_PointerTypeInPatternMatching: - case ErrorCode.ERR_ArgumentNameInITuplePattern: - case ErrorCode.ERR_DiscardPatternInSwitchStatement: - case ErrorCode.WRN_SwitchExpressionNotExhaustiveWithUnnamedEnumValue: - case ErrorCode.WRN_ThrowPossibleNull: - case ErrorCode.ERR_IllegalSuppression: - case ErrorCode.WRN_ConvertingNullableToNonNullable: - case ErrorCode.WRN_NullReferenceAssignment: - case ErrorCode.WRN_NullReferenceReceiver: - case ErrorCode.WRN_NullReferenceReturn: - case ErrorCode.WRN_NullReferenceArgument: - case ErrorCode.WRN_UnboxPossibleNull: - case ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment: - case ErrorCode.WRN_NullabilityMismatchInTypeOnOverride: - case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride: - case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride: - case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial: - case ErrorCode.WRN_NullabilityMismatchInTypeOnImplicitImplementation: - case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnImplicitImplementation: - case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnImplicitImplementation: - case ErrorCode.WRN_NullabilityMismatchInTypeOnExplicitImplementation: - case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation: - case ErrorCode.WRN_NullabilityMismatchInParameterTypeOnExplicitImplementation: - case ErrorCode.WRN_UninitializedNonNullableField: - case ErrorCode.WRN_NullabilityMismatchInAssignment: - case ErrorCode.WRN_NullabilityMismatchInArgument: - case ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate: - case ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate: - case ErrorCode.ERR_ExplicitNullableAttribute: - case ErrorCode.WRN_NullabilityMismatchInArgumentForOutput: - case ErrorCode.WRN_NullAsNonNullable: - case ErrorCode.ERR_NullableUnconstrainedTypeParameter: - case ErrorCode.ERR_AnnotationDisallowedInObjectCreation: - case ErrorCode.WRN_NullableValueTypeMayBeNull: - case ErrorCode.ERR_NullableOptionNotAvailable: - case ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint: - case ErrorCode.WRN_MissingNonNullTypesContextForAnnotation: - case ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation: - case ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint: - case ErrorCode.ERR_TripleDotNotAllowed: - case ErrorCode.ERR_BadNullableContextOption: - case ErrorCode.ERR_NullableDirectiveQualifierExpected: - case ErrorCode.ERR_BadNullableTypeof: - case ErrorCode.ERR_ExpressionTreeCantContainRefStruct: - case ErrorCode.ERR_ElseCannotStartStatement: - case ErrorCode.ERR_ExpressionTreeCantContainNullCoalescingAssignment: - case ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface: - case ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase: - case ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList: - case ErrorCode.ERR_DuplicateExplicitImpl: - case ErrorCode.ERR_UsingVarInSwitchCase: - case ErrorCode.ERR_GoToForwardJumpOverUsingVar: - case ErrorCode.ERR_GoToBackwardJumpOverUsingVar: - case ErrorCode.ERR_IsNullableType: - case ErrorCode.ERR_AsNullableType: - case ErrorCode.ERR_FeatureInPreview: - case ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull: - case ErrorCode.WRN_ImplicitCopyInReadOnlyMember: - case ErrorCode.ERR_StaticMemberCantBeReadOnly: - case ErrorCode.ERR_AutoSetterCantBeReadOnly: - case ErrorCode.ERR_AutoPropertyWithSetterCantBeReadOnly: - case ErrorCode.ERR_InvalidPropertyReadOnlyMods: - case ErrorCode.ERR_DuplicatePropertyReadOnlyMods: - case ErrorCode.ERR_FieldLikeEventCantBeReadOnly: - case ErrorCode.ERR_PartialMethodReadOnlyDifference: - case ErrorCode.ERR_ReadOnlyModMissingAccessor: - case ErrorCode.ERR_OverrideRefConstraintNotSatisfied: - case ErrorCode.ERR_OverrideValConstraintNotSatisfied: - case ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation: - case ErrorCode.ERR_NullableDirectiveTargetExpected: - case ErrorCode.WRN_MissingNonNullTypesContextForAnnotationInGeneratedCode: - case ErrorCode.WRN_NullReferenceInitializer: - case ErrorCode.ERR_MultipleAnalyzerConfigsInSameDir: - case ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation: - case ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember: - case ErrorCode.ERR_InvalidModifierForLanguageVersion: - case ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember: - case ErrorCode.ERR_MostSpecificImplementationIsNotFound: - case ErrorCode.ERR_LanguageVersionDoesNotSupportInterfaceImplementationForMember: - case ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember: - case ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType: - case ErrorCode.ERR_AbstractEventHasAccessors: - case ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint: - case ErrorCode.ERR_DuplicateNullSuppression: - case ErrorCode.ERR_DefaultLiteralNoTargetType: - case ErrorCode.ERR_ReAbstractionInNoPIAType: - case ErrorCode.ERR_InternalError: - case ErrorCode.ERR_ImplicitObjectCreationIllegalTargetType: - case ErrorCode.ERR_ImplicitObjectCreationNotValid: - case ErrorCode.ERR_ImplicitObjectCreationNoTargetType: - case ErrorCode.ERR_BadFuncPointerParamModifier: - case ErrorCode.ERR_BadFuncPointerArgCount: - case ErrorCode.ERR_MethFuncPtrMismatch: - case ErrorCode.ERR_FuncPtrRefMismatch: - case ErrorCode.ERR_FuncPtrMethMustBeStatic: - case ErrorCode.ERR_ExternEventInitializer: - case ErrorCode.ERR_AmbigBinaryOpsOnUnconstrainedDefault: - case ErrorCode.WRN_ParameterConditionallyDisallowsNull: - case ErrorCode.WRN_ShouldNotReturn: - case ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnOverride: - case ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride: - case ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnImplicitImplementation: - case ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation: - case ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnExplicitImplementation: - case ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation: - case ErrorCode.WRN_DoesNotReturnMismatch: - case ErrorCode.ERR_NoOutputDirectory: - case ErrorCode.ERR_StdInOptionProvidedButConsoleInputIsNotRedirected: - case ErrorCode.ERR_FeatureNotAvailableInVersion9: - case ErrorCode.WRN_MemberNotNull: - case ErrorCode.WRN_MemberNotNullWhen: - case ErrorCode.WRN_MemberNotNullBadMember: - case ErrorCode.WRN_ParameterDisallowsNull: - case ErrorCode.WRN_ConstOutOfRangeChecked: - case ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList: - case ErrorCode.ERR_DesignatorBeneathPatternCombinator: - case ErrorCode.ERR_UnsupportedTypeForRelationalPattern: - case ErrorCode.ERR_RelationalPatternWithNaN: - case ErrorCode.ERR_ConditionalOnLocalFunction: - case ErrorCode.WRN_GeneratorFailedDuringInitialization: - case ErrorCode.WRN_GeneratorFailedDuringGeneration: - case ErrorCode.ERR_WrongFuncPtrCallingConvention: - case ErrorCode.ERR_MissingAddressOf: - case ErrorCode.ERR_CannotUseReducedExtensionMethodInAddressOf: - case ErrorCode.ERR_CannotUseFunctionPointerAsFixedLocal: - case ErrorCode.ERR_ExpressionTreeContainsPatternImplicitIndexer: - case ErrorCode.ERR_ExpressionTreeContainsFromEndIndexExpression: - case ErrorCode.ERR_ExpressionTreeContainsRangeExpression: - case ErrorCode.WRN_GivenExpressionAlwaysMatchesPattern: - case ErrorCode.WRN_IsPatternAlways: - case ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation: - case ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods: - case ErrorCode.ERR_PartialMethodWithOutParamMustHaveAccessMods: - case ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods: - case ErrorCode.ERR_PartialMethodAccessibilityDifference: - case ErrorCode.ERR_PartialMethodExtendedModDifference: - case ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement: - case ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements: - case ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType: - case ErrorCode.ERR_SimpleProgramDisallowsMainType: - case ErrorCode.ERR_SimpleProgramNotAnExecutable: - case ErrorCode.ERR_UnsupportedCallingConvention: - case ErrorCode.ERR_InvalidFunctionPointerCallingConvention: - case ErrorCode.ERR_InvalidFuncPointerReturnTypeModifier: - case ErrorCode.ERR_DupReturnTypeMod: - case ErrorCode.ERR_AddressOfMethodGroupInExpressionTree: - case ErrorCode.ERR_CannotConvertAddressOfToDelegate: - case ErrorCode.ERR_AddressOfToNonFunctionPointer: - case ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary: - case ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType: - case ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid: - case ErrorCode.ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric: - case ErrorCode.ERR_PartialMethodReturnTypeDifference: - case ErrorCode.ERR_PartialMethodRefReturnDifference: - case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial: - case ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureVariable: - case ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureThis: - case ErrorCode.ERR_OverrideDefaultConstraintNotSatisfied: - case ErrorCode.ERR_DefaultConstraintOverrideOnly: - case ErrorCode.WRN_ParameterNotNullIfNotNull: - case ErrorCode.WRN_ReturnNotNullIfNotNull: - case ErrorCode.WRN_PartialMethodTypeDifference: - case ErrorCode.ERR_RuntimeDoesNotSupportCovariantReturnsOfClasses: - case ErrorCode.ERR_RuntimeDoesNotSupportCovariantPropertiesOfClasses: - case ErrorCode.WRN_SwitchExpressionNotExhaustiveWithWhen: - case ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen: - case ErrorCode.WRN_PrecedenceInversion: - case ErrorCode.ERR_ExpressionTreeContainsWithExpression: - case ErrorCode.WRN_AnalyzerReferencesFramework: - case ErrorCode.WRN_RecordEqualsWithoutGetHashCode: - case ErrorCode.ERR_AssignmentInitOnly: - case ErrorCode.ERR_CantChangeInitOnlyOnOverride: - case ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongInitOnly: - case ErrorCode.ERR_ExplicitPropertyMismatchInitOnly: - case ErrorCode.ERR_BadInitAccessor: - case ErrorCode.ERR_InvalidWithReceiverType: - case ErrorCode.ERR_CannotClone: - case ErrorCode.ERR_CloneDisallowedInRecord: - case ErrorCode.WRN_RecordNamedDisallowed: - case ErrorCode.ERR_UnexpectedArgumentList: - case ErrorCode.ERR_UnexpectedOrMissingConstructorInitializerInRecord: - case ErrorCode.ERR_MultipleRecordParameterLists: - case ErrorCode.ERR_BadRecordBase: - case ErrorCode.ERR_BadInheritanceFromRecord: - case ErrorCode.ERR_BadRecordMemberForPositionalParameter: - case ErrorCode.ERR_NoCopyConstructorInBaseType: - case ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor: - case ErrorCode.ERR_DoesNotOverrideMethodFromObject: - case ErrorCode.ERR_SealedAPIInRecord: - case ErrorCode.ERR_DoesNotOverrideBaseMethod: - case ErrorCode.ERR_NotOverridableAPIInRecord: - case ErrorCode.ERR_NonPublicAPIInRecord: - case ErrorCode.ERR_SignatureMismatchInRecord: - case ErrorCode.ERR_NonProtectedAPIInRecord: - case ErrorCode.ERR_DoesNotOverrideBaseEqualityContract: - case ErrorCode.ERR_StaticAPIInRecord: - case ErrorCode.ERR_CopyConstructorWrongAccessibility: - case ErrorCode.ERR_NonPrivateAPIInRecord: - case ErrorCode.WRN_UnassignedThisAutoPropertyUnsupportedVersion: - case ErrorCode.WRN_UnassignedThisUnsupportedVersion: - case ErrorCode.WRN_ParamUnassigned: - case ErrorCode.WRN_UseDefViolationProperty: - case ErrorCode.WRN_UseDefViolationField: - case ErrorCode.WRN_UseDefViolationThisUnsupportedVersion: - case ErrorCode.WRN_UseDefViolationOut: - case ErrorCode.WRN_UseDefViolation: - case ErrorCode.ERR_CannotSpecifyManagedWithUnmanagedSpecifiers: - case ErrorCode.ERR_RuntimeDoesNotSupportUnmanagedDefaultCallConv: - case ErrorCode.ERR_TypeNotFound: - case ErrorCode.ERR_TypeMustBePublic: - case ErrorCode.ERR_InvalidUnmanagedCallersOnlyCallConv: - case ErrorCode.ERR_CannotUseManagedTypeInUnmanagedCallersOnly: - case ErrorCode.ERR_UnmanagedCallersOnlyMethodOrTypeCannotBeGeneric: - case ErrorCode.ERR_UnmanagedCallersOnlyRequiresStatic: - case ErrorCode.WRN_ParameterIsStaticClass: - case ErrorCode.WRN_ReturnTypeIsStaticClass: - case ErrorCode.ERR_EntryPointCannotBeUnmanagedCallersOnly: - case ErrorCode.ERR_ModuleInitializerCannotBeUnmanagedCallersOnly: - case ErrorCode.ERR_UnmanagedCallersOnlyMethodsCannotBeCalledDirectly: - case ErrorCode.ERR_UnmanagedCallersOnlyMethodsCannotBeConvertedToDelegate: - case ErrorCode.ERR_InitCannotBeReadonly: - case ErrorCode.ERR_UnexpectedVarianceStaticMember: - case ErrorCode.ERR_FunctionPointersCannotBeCalledWithNamedArguments: - case ErrorCode.ERR_EqualityContractRequiresGetter: - case ErrorCode.WRN_UnreadRecordParameter: - case ErrorCode.ERR_BadFieldTypeInRecord: - case ErrorCode.WRN_DoNotCompareFunctionPointers: - case ErrorCode.ERR_RecordAmbigCtor: - case ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported: - case ErrorCode.ERR_InheritingFromRecordWithSealedToString: - case ErrorCode.ERR_HiddenPositionalMember: - case ErrorCode.ERR_GlobalUsingInNamespace: - case ErrorCode.ERR_GlobalUsingOutOfOrder: - case ErrorCode.ERR_AttributesRequireParenthesizedLambdaExpression: - case ErrorCode.ERR_CannotInferDelegateType: - case ErrorCode.ERR_InvalidNameInSubpattern: - case ErrorCode.ERR_RuntimeDoesNotSupportStaticAbstractMembersInInterfaces: - case ErrorCode.ERR_GenericConstraintNotSatisfiedInterfaceWithStaticAbstractMembers: - case ErrorCode.ERR_BadAbstractUnaryOperatorSignature: - case ErrorCode.ERR_BadAbstractIncDecSignature: - case ErrorCode.ERR_BadAbstractIncDecRetType: - case ErrorCode.ERR_BadAbstractBinaryOperatorSignature: - case ErrorCode.ERR_BadAbstractShiftOperatorSignature: - case ErrorCode.ERR_BadAbstractStaticMemberAccess: - case ErrorCode.ERR_ExpressionTreeContainsAbstractStaticMemberAccess: - case ErrorCode.ERR_CloseUnimplementedInterfaceMemberNotStatic: - case ErrorCode.ERR_RuntimeDoesNotSupportStaticAbstractMembersInInterfacesForMember: - case ErrorCode.ERR_ExplicitImplementationOfOperatorsMustBeStatic: - case ErrorCode.ERR_AbstractConversionNotInvolvingContainedType: - case ErrorCode.ERR_InterfaceImplementedByUnmanagedCallersOnlyMethod: - case ErrorCode.HDN_DuplicateWithGlobalUsing: - case ErrorCode.ERR_CantConvAnonMethReturnType: - case ErrorCode.ERR_BuilderAttributeDisallowed: - case ErrorCode.ERR_FeatureNotAvailableInVersion10: - case ErrorCode.ERR_SimpleProgramIsEmpty: - case ErrorCode.ERR_LineSpanDirectiveInvalidValue: - case ErrorCode.ERR_LineSpanDirectiveEndLessThanStart: - case ErrorCode.ERR_WrongArityAsyncReturn: - case ErrorCode.ERR_InterpolatedStringHandlerMethodReturnMalformed: - case ErrorCode.ERR_InterpolatedStringHandlerMethodReturnInconsistent: - case ErrorCode.ERR_NullInvalidInterpolatedStringHandlerArgumentName: - case ErrorCode.ERR_NotInstanceInvalidInterpolatedStringHandlerArgumentName: - case ErrorCode.ERR_InvalidInterpolatedStringHandlerArgumentName: - case ErrorCode.ERR_TypeIsNotAnInterpolatedStringHandlerType: - case ErrorCode.WRN_ParameterOccursAfterInterpolatedStringHandlerParameter: - case ErrorCode.ERR_CannotUseSelfAsInterpolatedStringHandlerArgument: - case ErrorCode.ERR_InterpolatedStringHandlerArgumentAttributeMalformed: - case ErrorCode.ERR_InterpolatedStringHandlerArgumentLocatedAfterInterpolatedString: - case ErrorCode.ERR_InterpolatedStringHandlerArgumentOptionalNotSpecified: - case ErrorCode.ERR_ExpressionTreeContainsInterpolatedStringHandlerConversion: - case ErrorCode.ERR_InterpolatedStringHandlerCreationCannotUseDynamic: - case ErrorCode.ERR_MultipleFileScopedNamespace: - case ErrorCode.ERR_FileScopedAndNormalNamespace: - case ErrorCode.ERR_FileScopedNamespaceNotBeforeAllMembers: - case ErrorCode.ERR_NoImplicitConvTargetTypedConditional: - case ErrorCode.ERR_NonPublicParameterlessStructConstructor: - case ErrorCode.ERR_NoConversionForCallerArgumentExpressionParam: - case ErrorCode.WRN_CallerLineNumberPreferredOverCallerArgumentExpression: - case ErrorCode.WRN_CallerFilePathPreferredOverCallerArgumentExpression: - case ErrorCode.WRN_CallerMemberNamePreferredOverCallerArgumentExpression: - case ErrorCode.WRN_CallerArgumentExpressionAttributeHasInvalidParameterName: - case ErrorCode.ERR_BadCallerArgumentExpressionParamWithoutDefaultValue: - case ErrorCode.WRN_CallerArgumentExpressionAttributeSelfReferential: - case ErrorCode.WRN_CallerArgumentExpressionParamForUnconsumedLocation: - case ErrorCode.ERR_NewlinesAreNotAllowedInsideANonVerbatimInterpolatedString: - case ErrorCode.ERR_AttrTypeArgCannotBeTypeVar: - case ErrorCode.ERR_AttrDependentTypeNotAllowed: - case ErrorCode.WRN_InterpolatedStringHandlerArgumentAttributeIgnoredOnLambdaParameters: - case ErrorCode.ERR_LambdaWithAttributesToExpressionTree: - case ErrorCode.WRN_CompileTimeCheckedOverflow: - case ErrorCode.WRN_MethGrpToNonDel: - case ErrorCode.ERR_LambdaExplicitReturnTypeVar: - case ErrorCode.ERR_InterpolatedStringsReferencingInstanceCannotBeInObjectInitializers: - case ErrorCode.ERR_CannotUseRefInUnmanagedCallersOnly: - case ErrorCode.ERR_CannotBeMadeNullable: - case ErrorCode.ERR_UnsupportedTypeForListPattern: - case ErrorCode.ERR_MisplacedSlicePattern: - case ErrorCode.WRN_LowerCaseTypeName: - case ErrorCode.ERR_RecordStructConstructorCallsDefaultConstructor: - case ErrorCode.ERR_StructHasInitializersAndNoDeclaredConstructor: - case ErrorCode.ERR_ListPatternRequiresLength: - case ErrorCode.ERR_ScopedMismatchInParameterOfTarget: - case ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation: - case ErrorCode.ERR_ScopedMismatchInParameterOfPartial: - case ErrorCode.ERR_ParameterNullCheckingNotSupported: - case ErrorCode.ERR_RawStringNotInDirectives: - case ErrorCode.ERR_UnterminatedRawString: - case ErrorCode.ERR_TooManyQuotesForRawString: - case ErrorCode.ERR_LineDoesNotStartWithSameWhitespace: - case ErrorCode.ERR_RawStringDelimiterOnOwnLine: - case ErrorCode.ERR_RawStringInVerbatimInterpolatedStrings: - case ErrorCode.ERR_RawStringMustContainContent: - case ErrorCode.ERR_LineContainsDifferentWhitespace: - case ErrorCode.ERR_NotEnoughQuotesForRawString: - case ErrorCode.ERR_NotEnoughCloseBracesForRawString: - case ErrorCode.ERR_TooManyOpenBracesForRawString: - case ErrorCode.ERR_TooManyCloseBracesForRawString: - case ErrorCode.ERR_IllegalAtSequence: - case ErrorCode.ERR_StringMustStartWithQuoteCharacter: - case ErrorCode.ERR_NoEnumConstraint: - case ErrorCode.ERR_NoDelegateConstraint: - case ErrorCode.ERR_MisplacedRecord: - case ErrorCode.ERR_PatternSpanCharCannotBeStringNull: - case ErrorCode.ERR_UseDefViolationPropertyUnsupportedVersion: - case ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion: - case ErrorCode.WRN_UseDefViolationPropertyUnsupportedVersion: - case ErrorCode.WRN_UseDefViolationFieldUnsupportedVersion: - case ErrorCode.WRN_UseDefViolationPropertySupportedVersion: - case ErrorCode.WRN_UseDefViolationFieldSupportedVersion: - case ErrorCode.WRN_UseDefViolationThisSupportedVersion: - case ErrorCode.WRN_UnassignedThisAutoPropertySupportedVersion: - case ErrorCode.WRN_UnassignedThisSupportedVersion: - case ErrorCode.ERR_OperatorCantBeChecked: - case ErrorCode.ERR_ImplicitConversionOperatorCantBeChecked: - case ErrorCode.ERR_CheckedOperatorNeedsMatch: - case ErrorCode.ERR_MisplacedUnchecked: - case ErrorCode.ERR_LineSpanDirectiveRequiresSpace: - case ErrorCode.ERR_RequiredNameDisallowed: - case ErrorCode.ERR_OverrideMustHaveRequired: - case ErrorCode.ERR_RequiredMemberCannotBeHidden: - case ErrorCode.ERR_RequiredMemberCannotBeLessVisibleThanContainingType: - case ErrorCode.ERR_ExplicitRequiredMember: - case ErrorCode.ERR_RequiredMemberMustBeSettable: - case ErrorCode.ERR_RequiredMemberMustBeSet: - case ErrorCode.ERR_RequiredMembersMustBeAssignedValue: - case ErrorCode.ERR_RequiredMembersInvalid: - case ErrorCode.ERR_RequiredMembersBaseTypeInvalid: - case ErrorCode.ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers: - case ErrorCode.ERR_NewConstraintCannotHaveRequiredMembers: - case ErrorCode.ERR_UnsupportedCompilerFeature: - case ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired: - case ErrorCode.ERR_RefReturningPropertiesCannotBeRequired: - case ErrorCode.ERR_ImplicitImplementationOfInaccessibleInterfaceMember: - case ErrorCode.ERR_ScriptsAndSubmissionsCannotHaveRequiredMembers: - case ErrorCode.ERR_BadAbstractEqualityOperatorSignature: - case ErrorCode.ERR_BadBinaryReadOnlySpanConcatenation: - case ErrorCode.ERR_ScopedRefAndRefStructOnly: - case ErrorCode.ERR_ScopedDiscard: - case ErrorCode.ERR_FixedFieldMustNotBeRef: - case ErrorCode.ERR_RefFieldCannotReferToRefStruct: - case ErrorCode.ERR_FileTypeDisallowedInSignature: - case ErrorCode.ERR_FileTypeNoExplicitAccessibility: - case ErrorCode.ERR_FileTypeBase: - case ErrorCode.ERR_FileTypeNested: - case ErrorCode.ERR_GlobalUsingStaticFileType: - case ErrorCode.ERR_FileTypeNameDisallowed: - case ErrorCode.ERR_FeatureNotAvailableInVersion11: - case ErrorCode.ERR_RefFieldInNonRefStruct: - case ErrorCode.WRN_AnalyzerReferencesNewerCompiler: - case ErrorCode.ERR_CannotMatchOnINumberBase: - case ErrorCode.ERR_ScopedTypeNameDisallowed: - case ErrorCode.ERR_ImplicitlyTypedDefaultParameter: - case ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget: - case ErrorCode.ERR_RuntimeDoesNotSupportRefFields: - case ErrorCode.ERR_ExplicitScopedRef: - case ErrorCode.ERR_UnscopedScoped: - case ErrorCode.WRN_DuplicateAnalyzerReference: - case ErrorCode.ERR_FilePathCannotBeConvertedToUtf8: - case ErrorCode.ERR_FileLocalDuplicateNameInNS: - case ErrorCode.WRN_ScopedMismatchInParameterOfTarget: - case ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation: - case ErrorCode.ERR_RefReturnScopedParameter: - case ErrorCode.ERR_RefReturnScopedParameter2: - case ErrorCode.ERR_RefReturnOnlyParameter: - case ErrorCode.ERR_RefReturnOnlyParameter2: - case ErrorCode.ERR_RefAssignReturnOnly: - case ErrorCode.WRN_ManagedAddr: - case ErrorCode.WRN_EscapeVariable: - case ErrorCode.WRN_EscapeStackAlloc: - case ErrorCode.WRN_RefReturnNonreturnableLocal: - case ErrorCode.WRN_RefReturnNonreturnableLocal2: - case ErrorCode.WRN_RefReturnStructThis: - case ErrorCode.WRN_RefAssignNarrower: - case ErrorCode.WRN_MismatchedRefEscapeInTernary: - case ErrorCode.WRN_RefReturnParameter: - case ErrorCode.WRN_RefReturnScopedParameter: - case ErrorCode.WRN_RefReturnParameter2: - case ErrorCode.WRN_RefReturnScopedParameter2: - case ErrorCode.WRN_RefReturnLocal: - case ErrorCode.WRN_RefReturnLocal2: - case ErrorCode.WRN_RefAssignReturnOnly: - case ErrorCode.WRN_RefReturnOnlyParameter: - case ErrorCode.WRN_RefReturnOnlyParameter2: - case ErrorCode.ERR_RefAssignValEscapeWider: - case ErrorCode.WRN_RefAssignValEscapeWider: - case ErrorCode.WRN_OptionalParamValueMismatch: - case ErrorCode.WRN_ParamsArrayInLambdaOnly: - case ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget: - case ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation: - case ErrorCode.ERR_UnrecognizedRefSafetyRulesAttributeVersion: - case ErrorCode.ERR_BadSpecialByRefUsing: - case ErrorCode.ERR_InvalidPrimaryConstructorParameterReference: - case ErrorCode.ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver: - case ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase: - case ErrorCode.WRN_UnreadPrimaryConstructorParameter: - case ErrorCode.ERR_AssgReadonlyPrimaryConstructorParameter: - case ErrorCode.ERR_RefReturnReadonlyPrimaryConstructorParameter: - case ErrorCode.ERR_RefReadonlyPrimaryConstructorParameter: - case ErrorCode.ERR_AssgReadonlyPrimaryConstructorParameter2: - case ErrorCode.ERR_RefReturnReadonlyPrimaryConstructorParameter2: - case ErrorCode.ERR_RefReadonlyPrimaryConstructorParameter2: - case ErrorCode.ERR_RefReturnPrimaryConstructorParameter: - case ErrorCode.ERR_StructLayoutCyclePrimaryConstructorParameter: - case ErrorCode.ERR_UnexpectedParameterList: - case ErrorCode.WRN_AddressOfInAsync: - case ErrorCode.ERR_BadRefInUsingAlias: - case ErrorCode.ERR_BadUnsafeInUsingDirective: - case ErrorCode.ERR_BadNullableReferenceTypeInUsingAlias: - case ErrorCode.ERR_BadStaticAfterUnsafe: - case ErrorCode.ERR_BadCaseInSwitchArm: - case ErrorCode.ERR_InterceptorsFeatureNotEnabled: - case ErrorCode.ERR_InterceptorContainingTypeCannotBeGeneric: - case ErrorCode.ERR_InterceptorPathNotInCompilation: - case ErrorCode.ERR_InterceptorPathNotInCompilationWithCandidate: - case ErrorCode.ERR_InterceptorPositionBadToken: - case ErrorCode.ERR_InterceptorLineOutOfRange: - case ErrorCode.ERR_InterceptorCharacterOutOfRange: - case ErrorCode.ERR_InterceptorMethodMustBeOrdinary: - case ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition: - case ErrorCode.ERR_InterceptorFilePathCannotBeNull: - case ErrorCode.ERR_InterceptorNameNotInvoked: - case ErrorCode.ERR_InterceptorNonUniquePath: - case ErrorCode.ERR_InterceptorLineCharacterMustBePositive: - case ErrorCode.ERR_ConstantValueOfTypeExpected: - case ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefAny: - case ErrorCode.ERR_InterceptorCannotUseUnmanagedCallersOnly: - case ErrorCode.ERR_BadUsingStaticType: - case ErrorCode.WRN_CapturedPrimaryConstructorParameterInFieldInitializer: - case ErrorCode.ERR_InlineArrayConversionToSpanNotSupported: - case ErrorCode.ERR_InlineArrayConversionToReadOnlySpanNotSupported: - case ErrorCode.ERR_InlineArrayIndexOutOfRange: - case ErrorCode.ERR_InvalidInlineArrayLength: - case ErrorCode.ERR_InvalidInlineArrayLayout: - case ErrorCode.ERR_InvalidInlineArrayFields: - case ErrorCode.ERR_ExpressionTreeContainsInlineArrayOperation: - case ErrorCode.ERR_RuntimeDoesNotSupportInlineArrayTypes: - case ErrorCode.ERR_InlineArrayBadIndex: - case ErrorCode.ERR_NamedArgumentForInlineArray: - case ErrorCode.ERR_CollectionExpressionTargetTypeNotConstructible: - case ErrorCode.ERR_ExpressionTreeContainsCollectionExpression: - case ErrorCode.ERR_CollectionExpressionNoTargetType: - case ErrorCode.WRN_PrimaryConstructorParameterIsShadowedAndNotPassedToBase: - case ErrorCode.ERR_InlineArrayUnsupportedElementFieldModifier: - case ErrorCode.WRN_InlineArrayIndexerNotUsed: - case ErrorCode.WRN_InlineArraySliceNotUsed: - case ErrorCode.WRN_InlineArrayConversionOperatorNotUsed: - case ErrorCode.WRN_InlineArrayNotSupportedByLanguage: - case ErrorCode.ERR_CollectionBuilderAttributeMethodNotFound: - case ErrorCode.ERR_CollectionBuilderAttributeInvalidType: - case ErrorCode.ERR_CollectionBuilderAttributeInvalidMethodName: - case ErrorCode.ERR_CollectionBuilderNoElementType: - case ErrorCode.ERR_InlineArrayForEachNotSupported: - case ErrorCode.ERR_RefReadOnlyWrongOrdering: - case ErrorCode.WRN_BadArgRef: - case ErrorCode.WRN_ArgExpectedRefOrIn: - case ErrorCode.WRN_RefReadonlyNotVariable: - case ErrorCode.ERR_BadArgExtraRefLangVersion: - case ErrorCode.WRN_ArgExpectedIn: - case ErrorCode.WRN_OverridingDifferentRefness: - case ErrorCode.WRN_HidingDifferentRefness: - case ErrorCode.WRN_TargetDifferentRefness: - case ErrorCode.ERR_OutAttrOnRefReadonlyParam: - case ErrorCode.WRN_RefReadonlyParameterDefaultValue: - case ErrorCode.WRN_ByValArraySizeConstRequired: - case ErrorCode.WRN_UseDefViolationRefField: - case ErrorCode.ERR_FeatureNotAvailableInVersion12: - case ErrorCode.ERR_CollectionExpressionEscape: - case ErrorCode.WRN_Experimental: - case ErrorCode.ERR_ExpectedInterpolatedString: - case ErrorCode.ERR_InterceptorGlobalNamespace: - case ErrorCode.WRN_CollectionExpressionRefStructMayAllocate: - case ErrorCode.WRN_CollectionExpressionRefStructSpreadMayAllocate: - case ErrorCode.ERR_CollectionExpressionImmutableArray: - case ErrorCode.ERR_InvalidExperimentalDiagID: - case ErrorCode.ERR_SpreadMissingMember: - case ErrorCode.ERR_CollectionExpressionTargetNoElementType: - case ErrorCode.ERR_CollectionExpressionMissingConstructor: - case ErrorCode.ERR_CollectionExpressionMissingAdd: - case ErrorCode.WRN_ConvertingLock: - case ErrorCode.ERR_BadSpecialByRefLock: - case ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections: - case ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument: - case ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod: - case ErrorCode.WRN_DynamicDispatchToParamsCollectionIndexer: - case ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor: - case ErrorCode.ERR_ParamsCollectionInfiniteChainOfConstructorCalls: - case ErrorCode.ERR_ParamsMemberCannotBeLessVisibleThanDeclaringMember: - case ErrorCode.ERR_ParamsCollectionConstructorDoesntInitializeRequiredMember: - case ErrorCode.ERR_ParamsCollectionExpressionTree: - case ErrorCode.ERR_ParamsCollectionExtensionAddMethod: - case ErrorCode.ERR_ParamsCollectionMissingConstructor: - case ErrorCode.ERR_NoModifiersOnUsing: - case ErrorCode.ERR_CannotDynamicInvokeOnExpression: - case ErrorCode.ERR_InterceptsLocationDataInvalidFormat: - case ErrorCode.ERR_InterceptsLocationUnsupportedVersion: - case ErrorCode.ERR_InterceptsLocationDuplicateFile: - case ErrorCode.ERR_InterceptsLocationFileNotFound: - case ErrorCode.ERR_InterceptsLocationDataInvalidPosition: - case ErrorCode.INF_TooManyBoundLambdas: - return false; - default: - // NOTE: All error codes must be explicitly handled in this switch statement - // to ensure that we correctly classify all error codes as build-only or not. - throw new NotImplementedException($"ErrorCode.{code}"); - } + => true, + + ErrorCode.Void + or ErrorCode.Unknown + or ErrorCode.ERR_NoMetadataFile + or ErrorCode.FTL_MetadataCantOpenFile + or ErrorCode.ERR_NoTypeDef + or ErrorCode.ERR_OutputWriteFailed + or ErrorCode.ERR_BadBinaryOps + or ErrorCode.ERR_IntDivByZero + or ErrorCode.ERR_BadIndexLHS + or ErrorCode.ERR_BadIndexCount + or ErrorCode.ERR_BadUnaryOp + or ErrorCode.ERR_ThisInStaticMeth + or ErrorCode.ERR_ThisInBadContext + or ErrorCode.ERR_NoImplicitConv + or ErrorCode.ERR_NoExplicitConv + or ErrorCode.ERR_ConstOutOfRange + or ErrorCode.ERR_AmbigBinaryOps + or ErrorCode.ERR_AmbigUnaryOp + or ErrorCode.ERR_InAttrOnOutParam + or ErrorCode.ERR_ValueCantBeNull + or ErrorCode.ERR_NoExplicitBuiltinConv + or ErrorCode.FTL_DebugEmitFailure + or ErrorCode.ERR_BadVisReturnType + or ErrorCode.ERR_BadVisParamType + or ErrorCode.ERR_BadVisFieldType + or ErrorCode.ERR_BadVisPropertyType + or ErrorCode.ERR_BadVisIndexerReturn + or ErrorCode.ERR_BadVisIndexerParam + or ErrorCode.ERR_BadVisOpReturn + or ErrorCode.ERR_BadVisOpParam + or ErrorCode.ERR_BadVisDelegateReturn + or ErrorCode.ERR_BadVisDelegateParam + or ErrorCode.ERR_BadVisBaseClass + or ErrorCode.ERR_BadVisBaseInterface + or ErrorCode.ERR_EventNeedsBothAccessors + or ErrorCode.ERR_EventNotDelegate + or ErrorCode.ERR_InterfaceEventInitializer + or ErrorCode.ERR_BadEventUsage + or ErrorCode.ERR_ExplicitEventFieldImpl + or ErrorCode.ERR_CantOverrideNonEvent + or ErrorCode.ERR_AddRemoveMustHaveBody + or ErrorCode.ERR_AbstractEventInitializer + or ErrorCode.ERR_PossibleBadNegCast + or ErrorCode.ERR_ReservedEnumerator + or ErrorCode.ERR_AsMustHaveReferenceType + or ErrorCode.WRN_LowercaseEllSuffix + or ErrorCode.ERR_BadEventUsageNoField + or ErrorCode.ERR_ConstraintOnlyAllowedOnGenericDecl + or ErrorCode.ERR_TypeParamMustBeIdentifier + or ErrorCode.ERR_MemberReserved + or ErrorCode.ERR_DuplicateParamName + or ErrorCode.ERR_DuplicateNameInNS + or ErrorCode.ERR_DuplicateNameInClass + or ErrorCode.ERR_NameNotInContext + or ErrorCode.ERR_AmbigContext + or ErrorCode.WRN_DuplicateUsing + or ErrorCode.ERR_BadMemberFlag + or ErrorCode.ERR_BadMemberProtection + or ErrorCode.WRN_NewRequired + or ErrorCode.WRN_NewNotRequired + or ErrorCode.ERR_CircConstValue + or ErrorCode.ERR_MemberAlreadyExists + or ErrorCode.ERR_StaticNotVirtual + or ErrorCode.ERR_OverrideNotNew + or ErrorCode.WRN_NewOrOverrideExpected + or ErrorCode.ERR_OverrideNotExpected + or ErrorCode.ERR_NamespaceUnexpected + or ErrorCode.ERR_NoSuchMember + or ErrorCode.ERR_BadSKknown + or ErrorCode.ERR_BadSKunknown + or ErrorCode.ERR_ObjectRequired + or ErrorCode.ERR_AmbigCall + or ErrorCode.ERR_BadAccess + or ErrorCode.ERR_MethDelegateMismatch + or ErrorCode.ERR_RetObjectRequired + or ErrorCode.ERR_RetNoObjectRequired + or ErrorCode.ERR_LocalDuplicate + or ErrorCode.ERR_AssgLvalueExpected + or ErrorCode.ERR_StaticConstParam + or ErrorCode.ERR_NotConstantExpression + or ErrorCode.ERR_NotNullConstRefField + or ErrorCode.ERR_LocalIllegallyOverrides + or ErrorCode.ERR_BadUsingNamespace + or ErrorCode.ERR_NoBreakOrCont + or ErrorCode.ERR_DuplicateLabel + or ErrorCode.ERR_NoConstructors + or ErrorCode.ERR_NoNewAbstract + or ErrorCode.ERR_ConstValueRequired + or ErrorCode.ERR_CircularBase + or ErrorCode.ERR_MethodNameExpected + or ErrorCode.ERR_ConstantExpected + or ErrorCode.ERR_V6SwitchGoverningTypeValueExpected + or ErrorCode.ERR_DuplicateCaseLabel + or ErrorCode.ERR_InvalidGotoCase + or ErrorCode.ERR_PropertyLacksGet + or ErrorCode.ERR_BadExceptionType + or ErrorCode.ERR_BadEmptyThrow + or ErrorCode.ERR_BadFinallyLeave + or ErrorCode.ERR_LabelShadow + or ErrorCode.ERR_LabelNotFound + or ErrorCode.ERR_UnreachableCatch + or ErrorCode.ERR_ReturnExpected + or ErrorCode.WRN_UnreachableCode + or ErrorCode.ERR_SwitchFallThrough + or ErrorCode.WRN_UnreferencedLabel + or ErrorCode.ERR_UseDefViolation + or ErrorCode.WRN_UnreferencedVar + or ErrorCode.ERR_UseDefViolationField + or ErrorCode.ERR_UnassignedThisUnsupportedVersion + or ErrorCode.ERR_AmbigQM + or ErrorCode.ERR_InvalidQM + or ErrorCode.ERR_NoBaseClass + or ErrorCode.ERR_BaseIllegal + or ErrorCode.ERR_ObjectProhibited + or ErrorCode.ERR_ParamUnassigned + or ErrorCode.ERR_InvalidArray + or ErrorCode.ERR_ExternHasBody + or ErrorCode.ERR_AbstractAndExtern + or ErrorCode.ERR_BadAttributeParamType + or ErrorCode.ERR_BadAttributeArgument + or ErrorCode.WRN_IsAlwaysTrue + or ErrorCode.WRN_IsAlwaysFalse + or ErrorCode.ERR_LockNeedsReference + or ErrorCode.ERR_NullNotValid + or ErrorCode.ERR_UseDefViolationThisUnsupportedVersion + or ErrorCode.ERR_ArgsInvalid + or ErrorCode.ERR_AssgReadonly + or ErrorCode.ERR_RefReadonly + or ErrorCode.ERR_PtrExpected + or ErrorCode.ERR_PtrIndexSingle + or ErrorCode.WRN_ByRefNonAgileField + or ErrorCode.ERR_AssgReadonlyStatic + or ErrorCode.ERR_RefReadonlyStatic + or ErrorCode.ERR_AssgReadonlyProp + or ErrorCode.ERR_IllegalStatement + or ErrorCode.ERR_BadGetEnumerator + or ErrorCode.ERR_AbstractBaseCall + or ErrorCode.ERR_RefProperty + or ErrorCode.ERR_ManagedAddr + or ErrorCode.ERR_BadFixedInitType + or ErrorCode.ERR_FixedMustInit + or ErrorCode.ERR_InvalidAddrOp + or ErrorCode.ERR_FixedNeeded + or ErrorCode.ERR_FixedNotNeeded + or ErrorCode.ERR_UnsafeNeeded + or ErrorCode.ERR_OpTFRetType + or ErrorCode.ERR_OperatorNeedsMatch + or ErrorCode.ERR_BadBoolOp + or ErrorCode.ERR_MustHaveOpTF + or ErrorCode.WRN_UnreferencedVarAssg + or ErrorCode.ERR_CheckedOverflow + or ErrorCode.ERR_ConstOutOfRangeChecked + or ErrorCode.ERR_BadVarargs + or ErrorCode.ERR_ParamsMustBeCollection + or ErrorCode.ERR_IllegalArglist + or ErrorCode.ERR_IllegalUnsafe + or ErrorCode.ERR_AmbigMember + or ErrorCode.ERR_BadForeachDecl + or ErrorCode.ERR_ParamsLast + or ErrorCode.ERR_SizeofUnsafe + or ErrorCode.ERR_DottedTypeNameNotFoundInNS + or ErrorCode.ERR_FieldInitRefNonstatic + or ErrorCode.ERR_SealedNonOverride + or ErrorCode.ERR_CantOverrideSealed + or ErrorCode.ERR_VoidError + or ErrorCode.ERR_ConditionalOnOverride + or ErrorCode.ERR_PointerInAsOrIs + or ErrorCode.ERR_CallingFinalizeDeprecated + or ErrorCode.ERR_SingleTypeNameNotFound + or ErrorCode.ERR_NegativeStackAllocSize + or ErrorCode.ERR_NegativeArraySize + or ErrorCode.ERR_OverrideFinalizeDeprecated + or ErrorCode.ERR_CallingBaseFinalizeDeprecated + or ErrorCode.WRN_NegativeArrayIndex + or ErrorCode.WRN_BadRefCompareLeft + or ErrorCode.WRN_BadRefCompareRight + or ErrorCode.ERR_BadCastInFixed + or ErrorCode.ERR_StackallocInCatchFinally + or ErrorCode.ERR_VarargsLast + or ErrorCode.ERR_MissingPartial + or ErrorCode.ERR_PartialTypeKindConflict + or ErrorCode.ERR_PartialModifierConflict + or ErrorCode.ERR_PartialMultipleBases + or ErrorCode.ERR_PartialWrongTypeParams + or ErrorCode.ERR_PartialWrongConstraints + or ErrorCode.ERR_NoImplicitConvCast + or ErrorCode.ERR_PartialMisplaced + or ErrorCode.ERR_ImportedCircularBase + or ErrorCode.ERR_UseDefViolationOut + or ErrorCode.ERR_ArraySizeInDeclaration + or ErrorCode.ERR_InaccessibleGetter + or ErrorCode.ERR_InaccessibleSetter + or ErrorCode.ERR_InvalidPropertyAccessMod + or ErrorCode.ERR_DuplicatePropertyAccessMods + or ErrorCode.ERR_AccessModMissingAccessor + or ErrorCode.ERR_UnimplementedInterfaceAccessor + or ErrorCode.WRN_PatternIsAmbiguous + or ErrorCode.WRN_PatternNotPublicOrNotInstance + or ErrorCode.WRN_PatternBadSignature + or ErrorCode.ERR_FriendRefNotEqualToThis + or ErrorCode.WRN_SequentialOnPartialClass + or ErrorCode.ERR_BadConstType + or ErrorCode.ERR_NoNewTyvar + or ErrorCode.ERR_BadArity + or ErrorCode.ERR_BadTypeArgument + or ErrorCode.ERR_TypeArgsNotAllowed + or ErrorCode.ERR_HasNoTypeVars + or ErrorCode.ERR_NewConstraintNotSatisfied + or ErrorCode.ERR_GenericConstraintNotSatisfiedRefType + or ErrorCode.ERR_GenericConstraintNotSatisfiedNullableEnum + or ErrorCode.ERR_GenericConstraintNotSatisfiedNullableInterface + or ErrorCode.ERR_GenericConstraintNotSatisfiedTyVar + or ErrorCode.ERR_GenericConstraintNotSatisfiedValType + or ErrorCode.ERR_DuplicateGeneratedName + or ErrorCode.ERR_GlobalSingleTypeNameNotFound + or ErrorCode.ERR_NewBoundMustBeLast + or ErrorCode.ERR_TypeVarCantBeNull + or ErrorCode.ERR_DuplicateBound + or ErrorCode.ERR_ClassBoundNotFirst + or ErrorCode.ERR_BadRetType + or ErrorCode.ERR_DuplicateConstraintClause + or ErrorCode.ERR_CantInferMethTypeArgs + or ErrorCode.ERR_LocalSameNameAsTypeParam + or ErrorCode.ERR_AsWithTypeVar + or ErrorCode.ERR_BadIndexerNameAttr + or ErrorCode.ERR_AttrArgWithTypeVars + or ErrorCode.ERR_NewTyvarWithArgs + or ErrorCode.ERR_AbstractSealedStatic + or ErrorCode.WRN_AmbiguousXMLReference + or ErrorCode.WRN_VolatileByRef + or ErrorCode.ERR_ComImportWithImpl + or ErrorCode.ERR_ComImportWithBase + or ErrorCode.ERR_ImplBadConstraints + or ErrorCode.ERR_DottedTypeNameNotFoundInAgg + or ErrorCode.ERR_MethGrpToNonDel + or ErrorCode.ERR_BadExternAlias + or ErrorCode.ERR_ColColWithTypeAlias + or ErrorCode.ERR_AliasNotFound + or ErrorCode.ERR_SameFullNameAggAgg + or ErrorCode.ERR_SameFullNameNsAgg + or ErrorCode.WRN_SameFullNameThisNsAgg + or ErrorCode.WRN_SameFullNameThisAggAgg + or ErrorCode.WRN_SameFullNameThisAggNs + or ErrorCode.ERR_SameFullNameThisAggThisNs + or ErrorCode.ERR_ExternAfterElements + or ErrorCode.WRN_GlobalAliasDefn + or ErrorCode.ERR_SealedStaticClass + or ErrorCode.ERR_PrivateAbstractAccessor + or ErrorCode.ERR_ValueExpected + or ErrorCode.ERR_UnboxNotLValue + or ErrorCode.ERR_AnonMethGrpInForEach + or ErrorCode.ERR_BadIncDecRetType + or ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst + or ErrorCode.ERR_RefValBoundWithClass + or ErrorCode.ERR_NewBoundWithVal + or ErrorCode.ERR_RefConstraintNotSatisfied + or ErrorCode.ERR_ValConstraintNotSatisfied + or ErrorCode.ERR_CircularConstraint + or ErrorCode.ERR_BaseConstraintConflict + or ErrorCode.ERR_ConWithValCon + or ErrorCode.ERR_AmbigUDConv + or ErrorCode.WRN_AlwaysNull + or ErrorCode.ERR_OverrideWithConstraints + or ErrorCode.ERR_AmbigOverride + or ErrorCode.ERR_DecConstError + or ErrorCode.WRN_CmpAlwaysFalse + or ErrorCode.WRN_FinalizeMethod + or ErrorCode.ERR_ExplicitImplParams + or ErrorCode.WRN_GotoCaseShouldConvert + or ErrorCode.ERR_MethodImplementingAccessor + or ErrorCode.WRN_NubExprIsConstBool + or ErrorCode.WRN_ExplicitImplCollision + or ErrorCode.ERR_AbstractHasBody + or ErrorCode.ERR_ConcreteMissingBody + or ErrorCode.ERR_AbstractAndSealed + or ErrorCode.ERR_AbstractNotVirtual + or ErrorCode.ERR_StaticConstant + or ErrorCode.ERR_CantOverrideNonFunction + or ErrorCode.ERR_CantOverrideNonVirtual + or ErrorCode.ERR_CantChangeAccessOnOverride + or ErrorCode.ERR_CantChangeReturnTypeOnOverride + or ErrorCode.ERR_CantDeriveFromSealedType + or ErrorCode.ERR_AbstractInConcreteClass + or ErrorCode.ERR_StaticConstructorWithExplicitConstructorCall + or ErrorCode.ERR_StaticConstructorWithAccessModifiers + or ErrorCode.ERR_RecursiveConstructorCall + or ErrorCode.ERR_ObjectCallingBaseConstructor + or ErrorCode.ERR_StructWithBaseConstructorCall + or ErrorCode.ERR_StructLayoutCycle + or ErrorCode.ERR_InterfacesCantContainFields + or ErrorCode.ERR_InterfacesCantContainConstructors + or ErrorCode.ERR_NonInterfaceInInterfaceList + or ErrorCode.ERR_DuplicateInterfaceInBaseList + or ErrorCode.ERR_CycleInInterfaceInheritance + or ErrorCode.ERR_HidingAbstractMethod + or ErrorCode.ERR_UnimplementedAbstractMethod + or ErrorCode.ERR_UnimplementedInterfaceMember + or ErrorCode.ERR_ObjectCantHaveBases + or ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface + or ErrorCode.ERR_InterfaceMemberNotFound + or ErrorCode.ERR_ClassDoesntImplementInterface + or ErrorCode.ERR_ExplicitInterfaceImplementationInNonClassOrStruct + or ErrorCode.ERR_MemberNameSameAsType + or ErrorCode.ERR_EnumeratorOverflow + or ErrorCode.ERR_CantOverrideNonProperty + or ErrorCode.ERR_NoGetToOverride + or ErrorCode.ERR_NoSetToOverride + or ErrorCode.ERR_PropertyCantHaveVoidType + or ErrorCode.ERR_PropertyWithNoAccessors + or ErrorCode.ERR_NewVirtualInSealed + or ErrorCode.ERR_ExplicitPropertyAddingAccessor + or ErrorCode.ERR_ExplicitPropertyMissingAccessor + or ErrorCode.ERR_ConversionWithInterface + or ErrorCode.ERR_ConversionWithBase + or ErrorCode.ERR_ConversionWithDerived + or ErrorCode.ERR_IdentityConversion + or ErrorCode.ERR_ConversionNotInvolvingContainedType + or ErrorCode.ERR_DuplicateConversionInClass + or ErrorCode.ERR_OperatorsMustBeStatic + or ErrorCode.ERR_BadIncDecSignature + or ErrorCode.ERR_BadUnaryOperatorSignature + or ErrorCode.ERR_BadBinaryOperatorSignature + or ErrorCode.ERR_BadShiftOperatorSignature + or ErrorCode.ERR_InterfacesCantContainConversionOrEqualityOperators + or ErrorCode.ERR_CantOverrideBogusMethod + or ErrorCode.ERR_CantCallSpecialMethod + or ErrorCode.ERR_BadTypeReference + or ErrorCode.ERR_BadDestructorName + or ErrorCode.ERR_OnlyClassesCanContainDestructors + or ErrorCode.ERR_ConflictAliasAndMember + or ErrorCode.ERR_ConditionalOnSpecialMethod + or ErrorCode.ERR_ConditionalMustReturnVoid + or ErrorCode.ERR_DuplicateAttribute + or ErrorCode.ERR_ConditionalOnInterfaceMethod + or ErrorCode.ERR_OperatorCantReturnVoid + or ErrorCode.ERR_InvalidAttributeArgument + or ErrorCode.ERR_AttributeOnBadSymbolType + or ErrorCode.ERR_FloatOverflow + or ErrorCode.ERR_InvalidReal + or ErrorCode.ERR_ComImportWithoutUuidAttribute + or ErrorCode.ERR_InvalidNamedArgument + or ErrorCode.ERR_DllImportOnInvalidMethod + or ErrorCode.ERR_FieldCantBeRefAny + or ErrorCode.ERR_ArrayElementCantBeRefAny + or ErrorCode.WRN_DeprecatedSymbol + or ErrorCode.ERR_NotAnAttributeClass + or ErrorCode.ERR_BadNamedAttributeArgument + or ErrorCode.WRN_DeprecatedSymbolStr + or ErrorCode.ERR_DeprecatedSymbolStr + or ErrorCode.ERR_IndexerCantHaveVoidType + or ErrorCode.ERR_VirtualPrivate + or ErrorCode.ERR_ArrayInitToNonArrayType + or ErrorCode.ERR_ArrayInitInBadPlace + or ErrorCode.ERR_MissingStructOffset + or ErrorCode.WRN_ExternMethodNoImplementation + or ErrorCode.WRN_ProtectedInSealed + or ErrorCode.ERR_InterfaceImplementedByConditional + or ErrorCode.ERR_InterfaceImplementedImplicitlyByVariadic + or ErrorCode.ERR_IllegalRefParam + or ErrorCode.ERR_BadArgumentToAttribute + or ErrorCode.ERR_StructOffsetOnBadStruct + or ErrorCode.ERR_StructOffsetOnBadField + or ErrorCode.ERR_AttributeUsageOnNonAttributeClass + or ErrorCode.WRN_PossibleMistakenNullStatement + or ErrorCode.ERR_DuplicateNamedAttributeArgument + or ErrorCode.ERR_DeriveFromEnumOrValueType + or ErrorCode.ERR_DefaultMemberOnIndexedType + or ErrorCode.ERR_BogusType + or ErrorCode.ERR_CStyleArray + or ErrorCode.WRN_VacuousIntegralComp + or ErrorCode.ERR_AbstractAttributeClass + or ErrorCode.ERR_BadNamedAttributeArgumentType + or ErrorCode.WRN_AttributeLocationOnBadDeclaration + or ErrorCode.WRN_InvalidAttributeLocation + or ErrorCode.WRN_EqualsWithoutGetHashCode + or ErrorCode.WRN_EqualityOpWithoutEquals + or ErrorCode.WRN_EqualityOpWithoutGetHashCode + or ErrorCode.ERR_OutAttrOnRefParam + or ErrorCode.ERR_OverloadRefKind + or ErrorCode.ERR_LiteralDoubleCast + or ErrorCode.WRN_IncorrectBooleanAssg + or ErrorCode.ERR_ProtectedInStruct + or ErrorCode.ERR_InconsistentIndexerNames + or ErrorCode.ERR_ComImportWithUserCtor + or ErrorCode.ERR_FieldCantHaveVoidType + or ErrorCode.WRN_NonObsoleteOverridingObsolete + or ErrorCode.ERR_SystemVoid + or ErrorCode.ERR_ExplicitParamArrayOrCollection + or ErrorCode.WRN_BitwiseOrSignExtend + or ErrorCode.ERR_VolatileStruct + or ErrorCode.ERR_VolatileAndReadonly + or ErrorCode.ERR_AbstractField + or ErrorCode.ERR_BogusExplicitImpl + or ErrorCode.ERR_ExplicitMethodImplAccessor + or ErrorCode.WRN_CoClassWithoutComImport + or ErrorCode.ERR_ConditionalWithOutParam + or ErrorCode.ERR_AccessorImplementingMethod + or ErrorCode.ERR_AliasQualAsExpression + or ErrorCode.ERR_DerivingFromATyVar + or ErrorCode.ERR_DuplicateTypeParameter + or ErrorCode.WRN_TypeParameterSameAsOuterTypeParameter + or ErrorCode.ERR_TypeVariableSameAsParent + or ErrorCode.ERR_UnifyingInterfaceInstantiations + or ErrorCode.ERR_TyVarNotFoundInConstraint + or ErrorCode.ERR_BadBoundType + or ErrorCode.ERR_SpecialTypeAsBound + or ErrorCode.ERR_BadVisBound + or ErrorCode.ERR_LookupInTypeVariable + or ErrorCode.ERR_BadConstraintType + or ErrorCode.ERR_InstanceMemberInStaticClass + or ErrorCode.ERR_StaticBaseClass + or ErrorCode.ERR_ConstructorInStaticClass + or ErrorCode.ERR_DestructorInStaticClass + or ErrorCode.ERR_InstantiatingStaticClass + or ErrorCode.ERR_StaticDerivedFromNonObject + or ErrorCode.ERR_StaticClassInterfaceImpl + or ErrorCode.ERR_OperatorInStaticClass + or ErrorCode.ERR_ConvertToStaticClass + or ErrorCode.ERR_ConstraintIsStaticClass + or ErrorCode.ERR_GenericArgIsStaticClass + or ErrorCode.ERR_ArrayOfStaticClass + or ErrorCode.ERR_IndexerInStaticClass + or ErrorCode.ERR_ParameterIsStaticClass + or ErrorCode.ERR_ReturnTypeIsStaticClass + or ErrorCode.ERR_VarDeclIsStaticClass + or ErrorCode.ERR_BadEmptyThrowInFinally + or ErrorCode.ERR_InvalidSpecifier + or ErrorCode.WRN_AssignmentToLockOrDispose + or ErrorCode.ERR_ForwardedTypeInThisAssembly + or ErrorCode.ERR_ForwardedTypeIsNested + or ErrorCode.ERR_CycleInTypeForwarder + or ErrorCode.ERR_AssemblyNameOnNonModule + or ErrorCode.ERR_InvalidFwdType + or ErrorCode.ERR_CloseUnimplementedInterfaceMemberStatic + or ErrorCode.ERR_CloseUnimplementedInterfaceMemberNotPublic + or ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType + or ErrorCode.ERR_DuplicateTypeForwarder + or ErrorCode.ERR_ExpectedSelectOrGroup + or ErrorCode.ERR_ExpectedContextualKeywordOn + or ErrorCode.ERR_ExpectedContextualKeywordEquals + or ErrorCode.ERR_ExpectedContextualKeywordBy + or ErrorCode.ERR_InvalidAnonymousTypeMemberDeclarator + or ErrorCode.ERR_InvalidInitializerElementInitializer + or ErrorCode.ERR_InconsistentLambdaParameterUsage + or ErrorCode.ERR_PartialMethodInvalidModifier + or ErrorCode.ERR_PartialMethodOnlyInPartialClass + or ErrorCode.ERR_PartialMethodNotExplicit + or ErrorCode.ERR_PartialMethodExtensionDifference + or ErrorCode.ERR_PartialMethodOnlyOneLatent + or ErrorCode.ERR_PartialMethodOnlyOneActual + or ErrorCode.ERR_PartialMethodParamsDifference + or ErrorCode.ERR_PartialMethodMustHaveLatent + or ErrorCode.ERR_PartialMethodInconsistentConstraints + or ErrorCode.ERR_PartialMethodToDelegate + or ErrorCode.ERR_PartialMethodStaticDifference + or ErrorCode.ERR_PartialMethodUnsafeDifference + or ErrorCode.ERR_PartialMethodInExpressionTree + or ErrorCode.ERR_ExplicitImplCollisionOnRefOut + or ErrorCode.ERR_IndirectRecursiveConstructorCall + or ErrorCode.WRN_ObsoleteOverridingNonObsolete + or ErrorCode.WRN_DebugFullNameTooLong + or ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue + or ErrorCode.ERR_ImplicitlyTypedVariableWithNoInitializer + or ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator + or ErrorCode.ERR_ImplicitlyTypedVariableAssignedArrayInitializer + or ErrorCode.ERR_ImplicitlyTypedLocalCannotBeFixed + or ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst + or ErrorCode.WRN_ExternCtorNoImplementation + or ErrorCode.ERR_TypeVarNotFound + or ErrorCode.ERR_ImplicitlyTypedArrayNoBestType + or ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue + or ErrorCode.ERR_ExpressionTreeContainsBaseAccess + or ErrorCode.ERR_ExpressionTreeContainsAssignment + or ErrorCode.ERR_AnonymousTypeDuplicatePropertyName + or ErrorCode.ERR_StatementLambdaToExpressionTree + or ErrorCode.ERR_ExpressionTreeMustHaveDelegate + or ErrorCode.ERR_AnonymousTypeNotAvailable + or ErrorCode.ERR_LambdaInIsAs + or ErrorCode.ERR_ExpressionTreeContainsMultiDimensionalArrayInitializer + or ErrorCode.ERR_MissingArgument + or ErrorCode.ERR_VariableUsedBeforeDeclaration + or ErrorCode.ERR_UnassignedThisAutoPropertyUnsupportedVersion + or ErrorCode.ERR_VariableUsedBeforeDeclarationAndHidesField + or ErrorCode.ERR_ExpressionTreeContainsBadCoalesce + or ErrorCode.ERR_ArrayInitializerExpected + or ErrorCode.ERR_ArrayInitializerIncorrectLength + or ErrorCode.ERR_ExpressionTreeContainsNamedArgument + or ErrorCode.ERR_ExpressionTreeContainsOptionalArgument + or ErrorCode.ERR_ExpressionTreeContainsIndexedProperty + or ErrorCode.ERR_IndexedPropertyRequiresParams + or ErrorCode.ERR_IndexedPropertyMustHaveAllOptionalParams + or ErrorCode.ERR_IdentifierExpected + or ErrorCode.ERR_SemicolonExpected + or ErrorCode.ERR_SyntaxError + or ErrorCode.ERR_DuplicateModifier + or ErrorCode.ERR_DuplicateAccessor + or ErrorCode.ERR_IntegralTypeExpected + or ErrorCode.ERR_IllegalEscape + or ErrorCode.ERR_NewlineInConst + or ErrorCode.ERR_EmptyCharConst + or ErrorCode.ERR_TooManyCharsInConst + or ErrorCode.ERR_InvalidNumber + or ErrorCode.ERR_GetOrSetExpected + or ErrorCode.ERR_ClassTypeExpected + or ErrorCode.ERR_NamedArgumentExpected + or ErrorCode.ERR_TooManyCatches + or ErrorCode.ERR_ThisOrBaseExpected + or ErrorCode.ERR_OvlUnaryOperatorExpected + or ErrorCode.ERR_OvlBinaryOperatorExpected + or ErrorCode.ERR_IntOverflow + or ErrorCode.ERR_EOFExpected + or ErrorCode.ERR_BadEmbeddedStmt + or ErrorCode.ERR_PPDirectiveExpected + or ErrorCode.ERR_EndOfPPLineExpected + or ErrorCode.ERR_CloseParenExpected + or ErrorCode.ERR_EndifDirectiveExpected + or ErrorCode.ERR_UnexpectedDirective + or ErrorCode.ERR_ErrorDirective + or ErrorCode.WRN_WarningDirective + or ErrorCode.ERR_TypeExpected + or ErrorCode.ERR_PPDefFollowsToken + or ErrorCode.ERR_OpenEndedComment + or ErrorCode.ERR_OvlOperatorExpected + or ErrorCode.ERR_EndRegionDirectiveExpected + or ErrorCode.ERR_UnterminatedStringLit + or ErrorCode.ERR_BadDirectivePlacement + or ErrorCode.ERR_IdentifierExpectedKW + or ErrorCode.ERR_SemiOrLBraceExpected + or ErrorCode.ERR_MultiTypeInDeclaration + or ErrorCode.ERR_AddOrRemoveExpected + or ErrorCode.ERR_UnexpectedCharacter + or ErrorCode.ERR_ProtectedInStatic + or ErrorCode.WRN_UnreachableGeneralCatch + or ErrorCode.ERR_IncrementLvalueExpected + or ErrorCode.ERR_NoSuchMemberOrExtension + or ErrorCode.WRN_DeprecatedCollectionInitAddStr + or ErrorCode.ERR_DeprecatedCollectionInitAddStr + or ErrorCode.WRN_DeprecatedCollectionInitAdd + or ErrorCode.ERR_DefaultValueNotAllowed + or ErrorCode.WRN_DefaultValueForUnconsumedLocation + or ErrorCode.ERR_PartialWrongTypeParamsVariance + or ErrorCode.ERR_GlobalSingleTypeNameNotFoundFwd + or ErrorCode.ERR_DottedTypeNameNotFoundInNSFwd + or ErrorCode.ERR_SingleTypeNameNotFoundFwd + or ErrorCode.WRN_IdentifierOrNumericLiteralExpected + or ErrorCode.ERR_UnexpectedToken + or ErrorCode.ERR_BadThisParam + or ErrorCode.ERR_BadTypeforThis + or ErrorCode.ERR_BadParamModThis + or ErrorCode.ERR_BadExtensionMeth + or ErrorCode.ERR_BadExtensionAgg + or ErrorCode.ERR_DupParamMod + or ErrorCode.ERR_ExtensionMethodsDecl + or ErrorCode.ERR_ExtensionAttrNotFound + or ErrorCode.ERR_ExplicitExtension + or ErrorCode.ERR_ValueTypeExtDelegate + or ErrorCode.ERR_BadArgCount + or ErrorCode.ERR_BadArgType + or ErrorCode.ERR_NoSourceFile + or ErrorCode.ERR_CantRefResource + or ErrorCode.ERR_ResourceNotUnique + or ErrorCode.ERR_ImportNonAssembly + or ErrorCode.ERR_RefLvalueExpected + or ErrorCode.ERR_BaseInStaticMeth + or ErrorCode.ERR_BaseInBadContext + or ErrorCode.ERR_RbraceExpected + or ErrorCode.ERR_LbraceExpected + or ErrorCode.ERR_InExpected + or ErrorCode.ERR_InvalidPreprocExpr + or ErrorCode.ERR_InvalidMemberDecl + or ErrorCode.ERR_MemberNeedsType + or ErrorCode.ERR_BadBaseType + or ErrorCode.WRN_EmptySwitch + or ErrorCode.ERR_ExpectedEndTry + or ErrorCode.ERR_InvalidExprTerm + or ErrorCode.ERR_BadNewExpr + or ErrorCode.ERR_NoNamespacePrivate + or ErrorCode.ERR_BadVarDecl + or ErrorCode.ERR_UsingAfterElements + or ErrorCode.ERR_BadBinOpArgs + or ErrorCode.ERR_BadUnOpArgs + or ErrorCode.ERR_NoVoidParameter + or ErrorCode.ERR_DuplicateAlias + or ErrorCode.ERR_BadProtectedAccess + or ErrorCode.ERR_AddModuleAssembly + or ErrorCode.ERR_BindToBogusProp2 + or ErrorCode.ERR_BindToBogusProp1 + or ErrorCode.ERR_NoVoidHere + or ErrorCode.ERR_IndexerNeedsParam + or ErrorCode.ERR_BadArraySyntax + or ErrorCode.ERR_BadOperatorSyntax + or ErrorCode.ERR_OutputNeedsName + or ErrorCode.ERR_CantHaveWin32ResAndManifest + or ErrorCode.ERR_CantHaveWin32ResAndIcon + or ErrorCode.ERR_CantReadResource + or ErrorCode.ERR_DocFileGen + or ErrorCode.WRN_XMLParseError + or ErrorCode.WRN_DuplicateParamTag + or ErrorCode.WRN_UnmatchedParamTag + or ErrorCode.WRN_MissingParamTag + or ErrorCode.WRN_BadXMLRef + or ErrorCode.ERR_BadStackAllocExpr + or ErrorCode.ERR_InvalidLineNumber + or ErrorCode.ERR_MissingPPFile + or ErrorCode.ERR_ForEachMissingMember + or ErrorCode.WRN_BadXMLRefParamType + or ErrorCode.WRN_BadXMLRefReturnType + or ErrorCode.ERR_BadWin32Res + or ErrorCode.WRN_BadXMLRefSyntax + or ErrorCode.ERR_BadModifierLocation + or ErrorCode.ERR_MissingArraySize + or ErrorCode.WRN_UnprocessedXMLComment + or ErrorCode.WRN_FailedInclude + or ErrorCode.WRN_InvalidInclude + or ErrorCode.WRN_MissingXMLComment + or ErrorCode.WRN_XMLParseIncludeError + or ErrorCode.ERR_BadDelArgCount + or ErrorCode.ERR_UnexpectedSemicolon + or ErrorCode.ERR_MethodReturnCantBeRefAny + or ErrorCode.ERR_CompileCancelled + or ErrorCode.ERR_MethodArgCantBeRefAny + or ErrorCode.ERR_AssgReadonlyLocal + or ErrorCode.ERR_RefReadonlyLocal + or ErrorCode.ERR_CantUseRequiredAttribute + or ErrorCode.ERR_NoModifiersOnAccessor + or ErrorCode.ERR_ParamsCantBeWithModifier + or ErrorCode.ERR_ReturnNotLValue + or ErrorCode.ERR_MissingCoClass + or ErrorCode.ERR_AmbiguousAttribute + or ErrorCode.ERR_BadArgExtraRef + or ErrorCode.WRN_CmdOptionConflictsSource + or ErrorCode.ERR_BadCompatMode + or ErrorCode.ERR_DelegateOnConditional + or ErrorCode.ERR_CantMakeTempFile + or ErrorCode.ERR_BadArgRef + or ErrorCode.ERR_YieldInAnonMeth + or ErrorCode.ERR_ReturnInIterator + or ErrorCode.ERR_BadIteratorArgType + or ErrorCode.ERR_BadIteratorReturn + or ErrorCode.ERR_BadYieldInFinally + or ErrorCode.ERR_BadYieldInTryOfCatch + or ErrorCode.ERR_EmptyYield + or ErrorCode.ERR_AnonDelegateCantUse + or ErrorCode.ERR_AnonDelegateCantUseRefLike + or ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRef + or ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefLike + or ErrorCode.ERR_AnonDelegateCantUseStructPrimaryConstructorParameterInMember + or ErrorCode.ERR_AnonDelegateCantUseStructPrimaryConstructorParameterCaptured + or ErrorCode.ERR_BadYieldInCatch + or ErrorCode.ERR_BadDelegateLeave + or ErrorCode.WRN_IllegalPragma + or ErrorCode.WRN_IllegalPPWarning + or ErrorCode.WRN_BadRestoreNumber + or ErrorCode.ERR_VarargsIterator + or ErrorCode.ERR_UnsafeIteratorArgType + or ErrorCode.ERR_BadCoClassSig + or ErrorCode.ERR_MultipleIEnumOfT + or ErrorCode.ERR_FixedDimsRequired + or ErrorCode.ERR_FixedNotInStruct + or ErrorCode.ERR_AnonymousReturnExpected + or ErrorCode.WRN_NonECMAFeature + or ErrorCode.ERR_ExpectedVerbatimLiteral + or ErrorCode.ERR_AssgReadonly2 + or ErrorCode.ERR_RefReadonly2 + or ErrorCode.ERR_AssgReadonlyStatic2 + or ErrorCode.ERR_RefReadonlyStatic2 + or ErrorCode.ERR_AssgReadonlyLocal2Cause + or ErrorCode.ERR_RefReadonlyLocal2Cause + or ErrorCode.ERR_AssgReadonlyLocalCause + or ErrorCode.ERR_RefReadonlyLocalCause + or ErrorCode.WRN_ErrorOverride + or ErrorCode.ERR_AnonMethToNonDel + or ErrorCode.ERR_CantConvAnonMethParams + or ErrorCode.ERR_CantConvAnonMethReturns + or ErrorCode.ERR_IllegalFixedType + or ErrorCode.ERR_FixedOverflow + or ErrorCode.ERR_InvalidFixedArraySize + or ErrorCode.ERR_FixedBufferNotFixed + or ErrorCode.ERR_AttributeNotOnAccessor + or ErrorCode.WRN_InvalidSearchPathDir + or ErrorCode.ERR_IllegalVarArgs + or ErrorCode.ERR_IllegalParams + or ErrorCode.ERR_BadModifiersOnNamespace + or ErrorCode.ERR_BadPlatformType + or ErrorCode.ERR_ThisStructNotInAnonMeth + or ErrorCode.ERR_NoConvToIDisp + or ErrorCode.ERR_BadParamRef + or ErrorCode.ERR_BadParamExtraRef + or ErrorCode.ERR_BadParamType + or ErrorCode.ERR_BadExternIdentifier + or ErrorCode.ERR_AliasMissingFile + or ErrorCode.ERR_GlobalExternAlias + or ErrorCode.WRN_MultiplePredefTypes + or ErrorCode.ERR_LocalCantBeFixedAndHoisted + or ErrorCode.WRN_TooManyLinesForDebugger + or ErrorCode.ERR_CantConvAnonMethNoParams + or ErrorCode.ERR_ConditionalOnNonAttributeClass + or ErrorCode.WRN_CallOnNonAgileField + or ErrorCode.WRN_InvalidNumber + or ErrorCode.WRN_IllegalPPChecksum + or ErrorCode.WRN_EndOfPPLineExpected + or ErrorCode.WRN_ConflictingChecksum + or ErrorCode.WRN_InvalidAssemblyName + or ErrorCode.WRN_UnifyReferenceMajMin + or ErrorCode.WRN_UnifyReferenceBldRev + or ErrorCode.ERR_DuplicateImport + or ErrorCode.ERR_DuplicateImportSimple + or ErrorCode.ERR_AssemblyMatchBadVersion + or ErrorCode.ERR_FixedNeedsLvalue + or ErrorCode.WRN_DuplicateTypeParamTag + or ErrorCode.WRN_UnmatchedTypeParamTag + or ErrorCode.WRN_MissingTypeParamTag + or ErrorCode.ERR_CantChangeTypeOnOverride + or ErrorCode.ERR_DoNotUseFixedBufferAttr + or ErrorCode.WRN_AssignmentToSelf + or ErrorCode.WRN_ComparisonToSelf + or ErrorCode.ERR_CantOpenWin32Res + or ErrorCode.WRN_DotOnDefault + or ErrorCode.ERR_NoMultipleInheritance + or ErrorCode.ERR_BaseClassMustBeFirst + or ErrorCode.WRN_BadXMLRefTypeVar + or ErrorCode.ERR_FriendAssemblyBadArgs + or ErrorCode.ERR_FriendAssemblySNReq + or ErrorCode.ERR_DelegateOnNullable + or ErrorCode.ERR_BadCtorArgCount + or ErrorCode.ERR_GlobalAttributesNotFirst + or ErrorCode.ERR_ExpressionExpected + or ErrorCode.WRN_UnmatchedParamRefTag + or ErrorCode.WRN_UnmatchedTypeParamRefTag + or ErrorCode.ERR_DefaultValueMustBeConstant + or ErrorCode.ERR_DefaultValueBeforeRequiredValue + or ErrorCode.ERR_NamedArgumentSpecificationBeforeFixedArgument + or ErrorCode.ERR_BadNamedArgument + or ErrorCode.ERR_DuplicateNamedArgument + or ErrorCode.ERR_RefOutDefaultValue + or ErrorCode.ERR_NamedArgumentForArray + or ErrorCode.ERR_DefaultValueForExtensionParameter + or ErrorCode.ERR_NamedArgumentUsedInPositional + or ErrorCode.ERR_DefaultValueUsedWithAttributes + or ErrorCode.ERR_BadNamedArgumentForDelegateInvoke + or ErrorCode.ERR_NoPIAAssemblyMissingAttribute + or ErrorCode.ERR_NoCanonicalView + or ErrorCode.ERR_NoConversionForDefaultParam + or ErrorCode.ERR_DefaultValueForParamsParameter + or ErrorCode.ERR_NewCoClassOnLink + or ErrorCode.ERR_NoPIANestedType + or ErrorCode.ERR_InteropTypeMissingAttribute + or ErrorCode.ERR_InteropStructContainsMethods + or ErrorCode.ERR_InteropTypesWithSameNameAndGuid + or ErrorCode.ERR_NoPIAAssemblyMissingAttributes + or ErrorCode.ERR_AssemblySpecifiedForLinkAndRef + or ErrorCode.ERR_LocalTypeNameClash + or ErrorCode.WRN_ReferencedAssemblyReferencesLinkedPIA + or ErrorCode.ERR_NotNullRefDefaultParameter + or ErrorCode.ERR_FixedLocalInLambda + or ErrorCode.ERR_MissingMethodOnSourceInterface + or ErrorCode.ERR_MissingSourceInterface + or ErrorCode.ERR_GenericsUsedInNoPIAType + or ErrorCode.ERR_GenericsUsedAcrossAssemblies + or ErrorCode.ERR_NoConversionForNubDefaultParam + or ErrorCode.ERR_InvalidSubsystemVersion + or ErrorCode.ERR_InteropMethodWithBody + or ErrorCode.ERR_BadWarningLevel + or ErrorCode.ERR_BadDebugType + or ErrorCode.ERR_BadResourceVis + or ErrorCode.ERR_DefaultValueTypeMustMatch + or ErrorCode.ERR_DefaultValueBadValueType + or ErrorCode.ERR_MemberAlreadyInitialized + or ErrorCode.ERR_MemberCannotBeInitialized + or ErrorCode.ERR_StaticMemberInObjectInitializer + or ErrorCode.ERR_ReadonlyValueTypeInObjectInitializer + or ErrorCode.ERR_ValueTypePropertyInObjectInitializer + or ErrorCode.ERR_UnsafeTypeInObjectCreation + or ErrorCode.ERR_EmptyElementInitializer + or ErrorCode.ERR_InitializerAddHasWrongSignature + or ErrorCode.ERR_CollectionInitRequiresIEnumerable + or ErrorCode.ERR_CantOpenWin32Manifest + or ErrorCode.WRN_CantHaveManifestForModule + or ErrorCode.ERR_BadInstanceArgType + or ErrorCode.ERR_QueryDuplicateRangeVariable + or ErrorCode.ERR_QueryRangeVariableOverrides + or ErrorCode.ERR_QueryRangeVariableAssignedBadValue + or ErrorCode.ERR_QueryNoProviderCastable + or ErrorCode.ERR_QueryNoProviderStandard + or ErrorCode.ERR_QueryNoProvider + or ErrorCode.ERR_QueryOuterKey + or ErrorCode.ERR_QueryInnerKey + or ErrorCode.ERR_QueryOutRefRangeVariable + or ErrorCode.ERR_QueryMultipleProviders + or ErrorCode.ERR_QueryTypeInferenceFailedMulti + or ErrorCode.ERR_QueryTypeInferenceFailed + or ErrorCode.ERR_QueryTypeInferenceFailedSelectMany + or ErrorCode.ERR_ExpressionTreeContainsPointerOp + or ErrorCode.ERR_ExpressionTreeContainsAnonymousMethod + or ErrorCode.ERR_AnonymousMethodToExpressionTree + or ErrorCode.ERR_QueryRangeVariableReadOnly + or ErrorCode.ERR_QueryRangeVariableSameAsTypeParam + or ErrorCode.ERR_TypeVarNotFoundRangeVariable + or ErrorCode.ERR_BadArgTypesForCollectionAdd + or ErrorCode.ERR_ByRefParameterInExpressionTree + or ErrorCode.ERR_VarArgsInExpressionTree + or ErrorCode.ERR_InitializerAddHasParamModifiers + or ErrorCode.ERR_NonInvocableMemberCalled + or ErrorCode.WRN_MultipleRuntimeImplementationMatches + or ErrorCode.WRN_MultipleRuntimeOverrideMatches + or ErrorCode.ERR_ObjectOrCollectionInitializerWithDelegateCreation + or ErrorCode.ERR_InvalidConstantDeclarationType + or ErrorCode.ERR_IllegalVarianceSyntax + or ErrorCode.ERR_UnexpectedVariance + or ErrorCode.ERR_BadDynamicTypeof + or ErrorCode.ERR_ExpressionTreeContainsDynamicOperation + or ErrorCode.ERR_BadDynamicConversion + or ErrorCode.ERR_DeriveFromDynamic + or ErrorCode.ERR_DeriveFromConstructedDynamic + or ErrorCode.ERR_DynamicTypeAsBound + or ErrorCode.ERR_ConstructedDynamicTypeAsBound + or ErrorCode.ERR_ExplicitDynamicAttr + or ErrorCode.ERR_NoDynamicPhantomOnBase + or ErrorCode.ERR_NoDynamicPhantomOnBaseIndexer + or ErrorCode.ERR_BadArgTypeDynamicExtension + or ErrorCode.WRN_DynamicDispatchToConditionalMethod + or ErrorCode.ERR_NoDynamicPhantomOnBaseCtor + or ErrorCode.ERR_BadDynamicMethodArgMemgrp + or ErrorCode.ERR_BadDynamicMethodArgLambda + or ErrorCode.ERR_BadDynamicMethodArg + or ErrorCode.ERR_BadDynamicQuery + or ErrorCode.ERR_DynamicAttributeMissing + or ErrorCode.WRN_IsDynamicIsConfusing + or ErrorCode.ERR_BadAsyncReturn + or ErrorCode.ERR_BadAwaitInFinally + or ErrorCode.ERR_BadAwaitInCatch + or ErrorCode.ERR_BadAwaitArg + or ErrorCode.ERR_BadAsyncArgType + or ErrorCode.ERR_BadAsyncExpressionTree + or ErrorCode.ERR_MixingWinRTEventWithRegular + or ErrorCode.ERR_BadAwaitWithoutAsync + or ErrorCode.ERR_BadAsyncLacksBody + or ErrorCode.ERR_BadAwaitInQuery + or ErrorCode.ERR_BadAwaitInLock + or ErrorCode.ERR_TaskRetNoObjectRequired + or ErrorCode.WRN_AsyncLacksAwaits + or ErrorCode.ERR_FileNotFound + or ErrorCode.WRN_FileAlreadyIncluded + or ErrorCode.ERR_NoFileSpec + or ErrorCode.ERR_SwitchNeedsString + or ErrorCode.ERR_BadSwitch + or ErrorCode.WRN_NoSources + or ErrorCode.ERR_OpenResponseFile + or ErrorCode.ERR_CantOpenFileWrite + or ErrorCode.ERR_BadBaseNumber + or ErrorCode.ERR_BinaryFile + or ErrorCode.FTL_BadCodepage + or ErrorCode.ERR_NoMainOnDLL + or ErrorCode.FTL_InvalidTarget + or ErrorCode.FTL_InvalidInputFileName + or ErrorCode.WRN_NoConfigNotOnCommandLine + or ErrorCode.ERR_InvalidFileAlignment + or ErrorCode.WRN_DefineIdentifierRequired + or ErrorCode.FTL_OutputFileExists + or ErrorCode.ERR_OneAliasPerReference + or ErrorCode.ERR_SwitchNeedsNumber + or ErrorCode.ERR_MissingDebugSwitch + or ErrorCode.ERR_ComRefCallInExpressionTree + or ErrorCode.WRN_BadUILang + or ErrorCode.ERR_InvalidFormatForGuidForOption + or ErrorCode.ERR_MissingGuidForOption + or ErrorCode.ERR_InvalidOutputName + or ErrorCode.ERR_InvalidDebugInformationFormat + or ErrorCode.ERR_LegacyObjectIdSyntax + or ErrorCode.ERR_SourceLinkRequiresPdb + or ErrorCode.ERR_CannotEmbedWithoutPdb + or ErrorCode.ERR_BadSwitchValue + or ErrorCode.WRN_CLS_NoVarArgs + or ErrorCode.WRN_CLS_BadArgType + or ErrorCode.WRN_CLS_BadReturnType + or ErrorCode.WRN_CLS_BadFieldPropType + or ErrorCode.WRN_CLS_BadIdentifierCase + or ErrorCode.WRN_CLS_OverloadRefOut + or ErrorCode.WRN_CLS_OverloadUnnamed + or ErrorCode.WRN_CLS_BadIdentifier + or ErrorCode.WRN_CLS_BadBase + or ErrorCode.WRN_CLS_BadInterfaceMember + or ErrorCode.WRN_CLS_NoAbstractMembers + or ErrorCode.WRN_CLS_NotOnModules + or ErrorCode.WRN_CLS_ModuleMissingCLS + or ErrorCode.WRN_CLS_AssemblyNotCLS + or ErrorCode.WRN_CLS_BadAttributeType + or ErrorCode.WRN_CLS_ArrayArgumentToAttribute + or ErrorCode.WRN_CLS_NotOnModules2 + or ErrorCode.WRN_CLS_IllegalTrueInFalse + or ErrorCode.WRN_CLS_MeaninglessOnPrivateType + or ErrorCode.WRN_CLS_AssemblyNotCLS2 + or ErrorCode.WRN_CLS_MeaninglessOnParam + or ErrorCode.WRN_CLS_MeaninglessOnReturn + or ErrorCode.WRN_CLS_BadTypeVar + or ErrorCode.WRN_CLS_VolatileField + or ErrorCode.WRN_CLS_BadInterface + or ErrorCode.FTL_BadChecksumAlgorithm + or ErrorCode.ERR_BadAwaitArgIntrinsic + or ErrorCode.ERR_BadAwaitAsIdentifier + or ErrorCode.ERR_AwaitInUnsafeContext + or ErrorCode.ERR_UnsafeAsyncArgType + or ErrorCode.ERR_VarargsAsync + or ErrorCode.ERR_BadAwaitArgVoidCall + or ErrorCode.ERR_NonTaskMainCantBeAsync + or ErrorCode.ERR_CantConvAsyncAnonFuncReturns + or ErrorCode.ERR_BadAwaiterPattern + or ErrorCode.ERR_BadSpecialByRefParameter + or ErrorCode.WRN_UnobservedAwaitableExpression + or ErrorCode.ERR_SynchronizedAsyncMethod + or ErrorCode.ERR_BadAsyncReturnExpression + or ErrorCode.ERR_NoConversionForCallerLineNumberParam + or ErrorCode.ERR_NoConversionForCallerFilePathParam + or ErrorCode.ERR_NoConversionForCallerMemberNameParam + or ErrorCode.ERR_BadCallerLineNumberParamWithoutDefaultValue + or ErrorCode.ERR_BadCallerFilePathParamWithoutDefaultValue + or ErrorCode.ERR_BadCallerMemberNameParamWithoutDefaultValue + or ErrorCode.ERR_BadPrefer32OnLib + or ErrorCode.WRN_CallerLineNumberParamForUnconsumedLocation + or ErrorCode.WRN_CallerFilePathParamForUnconsumedLocation + or ErrorCode.WRN_CallerMemberNameParamForUnconsumedLocation + or ErrorCode.ERR_DoesntImplementAwaitInterface + or ErrorCode.ERR_BadAwaitArg_NeedSystem + or ErrorCode.ERR_CantReturnVoid + or ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsync + or ErrorCode.ERR_SecurityCriticalOrSecuritySafeCriticalOnAsyncInClassOrStruct + or ErrorCode.ERR_BadAwaitWithoutAsyncMethod + or ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod + or ErrorCode.ERR_BadAwaitWithoutAsyncLambda + or ErrorCode.ERR_NoSuchMemberOrExtensionNeedUsing + or ErrorCode.ERR_UnexpectedAliasedName + or ErrorCode.ERR_UnexpectedGenericName + or ErrorCode.ERR_UnexpectedUnboundGenericName + or ErrorCode.ERR_GlobalStatement + or ErrorCode.ERR_BadUsingType + or ErrorCode.ERR_ReservedAssemblyName + or ErrorCode.ERR_PPReferenceFollowsToken + or ErrorCode.ERR_ExpectedPPFile + or ErrorCode.ERR_ReferenceDirectiveOnlyAllowedInScripts + or ErrorCode.ERR_NameNotInContextPossibleMissingReference + or ErrorCode.ERR_MetadataNameTooLong + or ErrorCode.ERR_AttributesNotAllowed + or ErrorCode.ERR_ExternAliasNotAllowed + or ErrorCode.ERR_ConflictingAliasAndDefinition + or ErrorCode.ERR_GlobalDefinitionOrStatementExpected + or ErrorCode.ERR_ExpectedSingleScript + or ErrorCode.ERR_RecursivelyTypedVariable + or ErrorCode.ERR_YieldNotAllowedInScript + or ErrorCode.ERR_NamespaceNotAllowedInScript + or ErrorCode.WRN_StaticInAsOrIs + or ErrorCode.ERR_InvalidDelegateType + or ErrorCode.ERR_BadVisEventType + or ErrorCode.ERR_GlobalAttributesNotAllowed + or ErrorCode.ERR_PublicKeyFileFailure + or ErrorCode.ERR_PublicKeyContainerFailure + or ErrorCode.ERR_FriendRefSigningMismatch + or ErrorCode.ERR_CannotPassNullForFriendAssembly + or ErrorCode.ERR_SignButNoPrivateKey + or ErrorCode.WRN_DelaySignButNoKey + or ErrorCode.ERR_InvalidVersionFormat + or ErrorCode.WRN_InvalidVersionFormat + or ErrorCode.ERR_NoCorrespondingArgument + or ErrorCode.ERR_ResourceFileNameNotUnique + or ErrorCode.ERR_DllImportOnGenericMethod + or ErrorCode.ERR_EncUpdateFailedMissingAttribute + or ErrorCode.ERR_ParameterNotValidForType + or ErrorCode.ERR_AttributeParameterRequired1 + or ErrorCode.ERR_AttributeParameterRequired2 + or ErrorCode.ERR_SecurityAttributeMissingAction + or ErrorCode.ERR_SecurityAttributeInvalidAction + or ErrorCode.ERR_SecurityAttributeInvalidActionAssembly + or ErrorCode.ERR_SecurityAttributeInvalidActionTypeOrMethod + or ErrorCode.ERR_PrincipalPermissionInvalidAction + or ErrorCode.ERR_FeatureNotValidInExpressionTree + or ErrorCode.ERR_MarshalUnmanagedTypeNotValidForFields + or ErrorCode.ERR_MarshalUnmanagedTypeOnlyValidForFields + or ErrorCode.ERR_PermissionSetAttributeInvalidFile + or ErrorCode.ERR_PermissionSetAttributeFileReadError + or ErrorCode.ERR_InvalidVersionFormat2 + or ErrorCode.ERR_InvalidAssemblyCultureForExe + or ErrorCode.ERR_DuplicateAttributeInNetModule + or ErrorCode.ERR_CantOpenIcon + or ErrorCode.ERR_ErrorBuildingWin32Resources + or ErrorCode.ERR_BadAttributeParamDefaultArgument + or ErrorCode.ERR_MissingTypeInSource + or ErrorCode.ERR_MissingTypeInAssembly + or ErrorCode.ERR_SecurityAttributeInvalidTarget + or ErrorCode.ERR_InvalidAssemblyName + or ErrorCode.ERR_NoTypeDefFromModule + or ErrorCode.WRN_CallerFilePathPreferredOverCallerMemberName + or ErrorCode.WRN_CallerLineNumberPreferredOverCallerMemberName + or ErrorCode.WRN_CallerLineNumberPreferredOverCallerFilePath + or ErrorCode.ERR_InvalidDynamicCondition + or ErrorCode.ERR_WinRtEventPassedByRef + or ErrorCode.ERR_NetModuleNameMismatch + or ErrorCode.ERR_BadModuleName + or ErrorCode.ERR_BadCompilationOptionValue + or ErrorCode.ERR_BadAppConfigPath + or ErrorCode.WRN_AssemblyAttributeFromModuleIsOverridden + or ErrorCode.ERR_CmdOptionConflictsSource + or ErrorCode.ERR_FixedBufferTooManyDimensions + or ErrorCode.ERR_CantReadConfigFile + or ErrorCode.ERR_BadAwaitInCatchFilter + or ErrorCode.WRN_FilterIsConstantTrue + or ErrorCode.ERR_EncNoPIAReference + or ErrorCode.ERR_LinkedNetmoduleMetadataMustProvideFullPEImage + or ErrorCode.ERR_MetadataReferencesNotSupported + or ErrorCode.ERR_InvalidAssemblyCulture + or ErrorCode.ERR_EncReferenceToAddedMember + or ErrorCode.ERR_MutuallyExclusiveOptions + or ErrorCode.ERR_InvalidDebugInfo + or ErrorCode.WRN_UnimplementedCommandLineSwitch + or ErrorCode.WRN_ReferencedAssemblyDoesNotHaveStrongName + or ErrorCode.ERR_InvalidSignaturePublicKey + or ErrorCode.ERR_ForwardedTypesConflict + or ErrorCode.WRN_RefCultureMismatch + or ErrorCode.ERR_AgnosticToMachineModule + or ErrorCode.ERR_ConflictingMachineModule + or ErrorCode.WRN_ConflictingMachineAssembly + or ErrorCode.ERR_CryptoHashFailed + or ErrorCode.ERR_MissingNetModuleReference + or ErrorCode.ERR_NetModuleNameMustBeUnique + or ErrorCode.ERR_UnsupportedTransparentIdentifierAccess + or ErrorCode.ERR_ParamDefaultValueDiffersFromAttribute + or ErrorCode.WRN_UnqualifiedNestedTypeInCref + or ErrorCode.HDN_UnusedUsingDirective + or ErrorCode.HDN_UnusedExternAlias + or ErrorCode.WRN_NoRuntimeMetadataVersion + or ErrorCode.ERR_FeatureNotAvailableInVersion1 + or ErrorCode.ERR_FeatureNotAvailableInVersion2 + or ErrorCode.ERR_FeatureNotAvailableInVersion3 + or ErrorCode.ERR_FeatureNotAvailableInVersion4 + or ErrorCode.ERR_FeatureNotAvailableInVersion5 + or ErrorCode.ERR_FieldHasMultipleDistinctConstantValues + or ErrorCode.ERR_ComImportWithInitializers + or ErrorCode.WRN_PdbLocalNameTooLong + or ErrorCode.ERR_RetNoObjectRequiredLambda + or ErrorCode.ERR_TaskRetNoObjectRequiredLambda + or ErrorCode.WRN_AnalyzerCannotBeCreated + or ErrorCode.WRN_NoAnalyzerInAssembly + or ErrorCode.WRN_UnableToLoadAnalyzer + or ErrorCode.ERR_CantReadRulesetFile + or ErrorCode.ERR_BadPdbData + or ErrorCode.INF_UnableToLoadSomeTypesInAnalyzer + or ErrorCode.ERR_InitializerOnNonAutoProperty + or ErrorCode.ERR_AutoPropertyMustHaveGetAccessor + or ErrorCode.ERR_InstancePropertyInitializerInInterface + or ErrorCode.ERR_EnumsCantContainDefaultConstructor + or ErrorCode.ERR_EncodinglessSyntaxTree + or ErrorCode.ERR_BlockBodyAndExpressionBody + or ErrorCode.ERR_FeatureIsExperimental + or ErrorCode.ERR_FeatureNotAvailableInVersion6 + or ErrorCode.ERR_SwitchFallOut + or ErrorCode.ERR_NullPropagatingOpInExpressionTree + or ErrorCode.WRN_NubExprIsConstBool2 + or ErrorCode.ERR_DictionaryInitializerInExpressionTree + or ErrorCode.ERR_ExtensionCollectionElementInitializerInExpressionTree + or ErrorCode.ERR_UnclosedExpressionHole + or ErrorCode.ERR_UseDefViolationProperty + or ErrorCode.ERR_AutoPropertyMustOverrideSet + or ErrorCode.ERR_ExpressionHasNoName + or ErrorCode.ERR_SubexpressionNotInNameof + or ErrorCode.ERR_AliasQualifiedNameNotAnExpression + or ErrorCode.ERR_NameofMethodGroupWithTypeParameters + or ErrorCode.ERR_NoAliasHere + or ErrorCode.ERR_UnescapedCurly + or ErrorCode.ERR_EscapedCurly + or ErrorCode.ERR_TrailingWhitespaceInFormatSpecifier + or ErrorCode.ERR_EmptyFormatSpecifier + or ErrorCode.ERR_ErrorInReferencedAssembly + or ErrorCode.ERR_ExternHasConstructorInitializer + or ErrorCode.ERR_ExpressionOrDeclarationExpected + or ErrorCode.ERR_NameofExtensionMethod + or ErrorCode.WRN_AlignmentMagnitude + or ErrorCode.ERR_ConstantStringTooLong + or ErrorCode.ERR_DebugEntryPointNotSourceMethodDefinition + or ErrorCode.ERR_LoadDirectiveOnlyAllowedInScripts + or ErrorCode.ERR_PPLoadFollowsToken + or ErrorCode.ERR_SourceFileReferencesNotSupported + or ErrorCode.ERR_BadAwaitInStaticVariableInitializer + or ErrorCode.ERR_InvalidPathMap + or ErrorCode.ERR_PublicSignButNoKey + or ErrorCode.ERR_TooManyUserStrings + or ErrorCode.ERR_PeWritingFailure + or ErrorCode.WRN_AttributeIgnoredWhenPublicSigning + or ErrorCode.ERR_OptionMustBeAbsolutePath + or ErrorCode.ERR_FeatureNotAvailableInVersion7 + or ErrorCode.ERR_DynamicLocalFunctionParamsParameter + or ErrorCode.ERR_ExpressionTreeContainsLocalFunction + or ErrorCode.ERR_InvalidInstrumentationKind + or ErrorCode.ERR_LocalFunctionMissingBody + or ErrorCode.ERR_InvalidHashAlgorithmName + or ErrorCode.ERR_ThrowMisplaced + or ErrorCode.ERR_PatternNullableType + or ErrorCode.ERR_BadPatternExpression + or ErrorCode.ERR_SwitchExpressionValueExpected + or ErrorCode.ERR_SwitchCaseSubsumed + or ErrorCode.ERR_PatternWrongType + or ErrorCode.ERR_ExpressionTreeContainsIsMatch + or ErrorCode.WRN_TupleLiteralNameMismatch + or ErrorCode.ERR_TupleTooFewElements + or ErrorCode.ERR_TupleReservedElementName + or ErrorCode.ERR_TupleReservedElementNameAnyPosition + or ErrorCode.ERR_TupleDuplicateElementName + or ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly + or ErrorCode.ERR_MissingDeconstruct + or ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedDeconstructionVariable + or ErrorCode.ERR_DeconstructRequiresExpression + or ErrorCode.ERR_DeconstructWrongCardinality + or ErrorCode.ERR_CannotDeconstructDynamic + or ErrorCode.ERR_DeconstructTooFewElements + or ErrorCode.ERR_ConversionNotTupleCompatible + or ErrorCode.ERR_DeconstructionVarFormDisallowsSpecificType + or ErrorCode.ERR_TupleElementNamesAttributeMissing + or ErrorCode.ERR_ExplicitTupleElementNamesAttribute + or ErrorCode.ERR_CantChangeTupleNamesOnOverride + or ErrorCode.ERR_DuplicateInterfaceWithTupleNamesInBaseList + or ErrorCode.ERR_ImplBadTupleNames + or ErrorCode.ERR_PartialMethodInconsistentTupleNames + or ErrorCode.ERR_ExpressionTreeContainsTupleLiteral + or ErrorCode.ERR_ExpressionTreeContainsTupleConversion + or ErrorCode.ERR_AutoPropertyCannotBeRefReturning + or ErrorCode.ERR_RefPropertyMustHaveGetAccessor + or ErrorCode.ERR_RefPropertyCannotHaveSetAccessor + or ErrorCode.ERR_CantChangeRefReturnOnOverride + or ErrorCode.ERR_MustNotHaveRefReturn + or ErrorCode.ERR_MustHaveRefReturn + or ErrorCode.ERR_RefReturnMustHaveIdentityConversion + or ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongRefReturn + or ErrorCode.ERR_RefReturningCallInExpressionTree + or ErrorCode.ERR_BadIteratorReturnRef + or ErrorCode.ERR_BadRefReturnExpressionTree + or ErrorCode.ERR_RefReturnLvalueExpected + or ErrorCode.ERR_RefReturnNonreturnableLocal + or ErrorCode.ERR_RefReturnNonreturnableLocal2 + or ErrorCode.ERR_RefReturnRangeVariable + or ErrorCode.ERR_RefReturnReadonly + or ErrorCode.ERR_RefReturnReadonlyStatic + or ErrorCode.ERR_RefReturnReadonly2 + or ErrorCode.ERR_RefReturnReadonlyStatic2 + or ErrorCode.ERR_RefReturnParameter + or ErrorCode.ERR_RefReturnParameter2 + or ErrorCode.ERR_RefReturnLocal + or ErrorCode.ERR_RefReturnLocal2 + or ErrorCode.ERR_RefReturnStructThis + or ErrorCode.ERR_InitializeByValueVariableWithReference + or ErrorCode.ERR_InitializeByReferenceVariableWithValue + or ErrorCode.ERR_RefAssignmentMustHaveIdentityConversion + or ErrorCode.ERR_ByReferenceVariableMustBeInitialized + or ErrorCode.ERR_AnonDelegateCantUseLocal + or ErrorCode.ERR_PredefinedValueTupleTypeNotFound + or ErrorCode.ERR_SemiOrLBraceOrArrowExpected + or ErrorCode.ERR_NewWithTupleTypeSyntax + or ErrorCode.ERR_PredefinedValueTupleTypeMustBeStruct + or ErrorCode.ERR_DiscardTypeInferenceFailed + or ErrorCode.ERR_DeclarationExpressionNotPermitted + or ErrorCode.ERR_MustDeclareForeachIteration + or ErrorCode.ERR_TupleElementNamesInDeconstruction + or ErrorCode.ERR_ExpressionTreeContainsThrowExpression + or ErrorCode.ERR_DelegateRefMismatch + or ErrorCode.ERR_BadSourceCodeKind + or ErrorCode.ERR_BadDocumentationMode + or ErrorCode.ERR_BadLanguageVersion + or ErrorCode.ERR_ImplicitlyTypedOutVariableUsedInTheSameArgumentList + or ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable + or ErrorCode.ERR_ExpressionTreeContainsOutVariable + or ErrorCode.ERR_VarInvocationLvalueReserved + or ErrorCode.ERR_PublicSignNetModule + or ErrorCode.ERR_BadAssemblyName + or ErrorCode.ERR_BadAsyncMethodBuilderTaskProperty + or ErrorCode.ERR_TypeForwardedToMultipleAssemblies + or ErrorCode.ERR_ExpressionTreeContainsDiscard + or ErrorCode.ERR_PatternDynamicType + or ErrorCode.ERR_VoidAssignment + or ErrorCode.ERR_VoidInTuple + or ErrorCode.ERR_Merge_conflict_marker_encountered + or ErrorCode.ERR_InvalidPreprocessingSymbol + or ErrorCode.ERR_FeatureNotAvailableInVersion7_1 + or ErrorCode.ERR_LanguageVersionCannotHaveLeadingZeroes + or ErrorCode.ERR_CompilerAndLanguageVersion + or ErrorCode.WRN_WindowsExperimental + or ErrorCode.ERR_TupleInferredNamesNotAvailable + or ErrorCode.ERR_TypelessTupleInAs + or ErrorCode.ERR_NoRefOutWhenRefOnly + or ErrorCode.ERR_NoNetModuleOutputWhenRefOutOrRefOnly + or ErrorCode.ERR_BadOpOnNullOrDefaultOrNew + or ErrorCode.ERR_DefaultLiteralNotValid + or ErrorCode.ERR_PatternWrongGenericTypeInVersion + or ErrorCode.ERR_AmbigBinaryOpsOnDefault + or ErrorCode.ERR_FeatureNotAvailableInVersion7_2 + or ErrorCode.WRN_UnreferencedLocalFunction + or ErrorCode.ERR_DynamicLocalFunctionTypeParameter + or ErrorCode.ERR_BadNonTrailingNamedArgument + or ErrorCode.ERR_NamedArgumentSpecificationBeforeFixedArgumentInDynamicInvocation + or ErrorCode.ERR_RefConditionalAndAwait + or ErrorCode.ERR_RefConditionalNeedsTwoRefs + or ErrorCode.ERR_RefConditionalDifferentTypes + or ErrorCode.ERR_BadParameterModifiers + or ErrorCode.ERR_RefReadonlyNotField + or ErrorCode.ERR_RefReadonlyNotField2 + or ErrorCode.ERR_AssignReadonlyNotField + or ErrorCode.ERR_AssignReadonlyNotField2 + or ErrorCode.ERR_RefReturnReadonlyNotField + or ErrorCode.ERR_RefReturnReadonlyNotField2 + or ErrorCode.ERR_ExplicitReservedAttr + or ErrorCode.ERR_TypeReserved + or ErrorCode.ERR_RefExtensionMustBeValueTypeOrConstrainedToOne + or ErrorCode.ERR_InExtensionMustBeValueType + or ErrorCode.ERR_FieldsInRoStruct + or ErrorCode.ERR_AutoPropsInRoStruct + or ErrorCode.ERR_FieldlikeEventsInRoStruct + or ErrorCode.ERR_BadSpecialByRefIterator + or ErrorCode.ERR_FieldAutoPropCantBeByRefLike + or ErrorCode.ERR_StackAllocConversionNotPossible + or ErrorCode.ERR_EscapeCall + or ErrorCode.ERR_EscapeCall2 + or ErrorCode.ERR_EscapeOther + or ErrorCode.ERR_CallArgMixing + or ErrorCode.ERR_MismatchedRefEscapeInTernary + or ErrorCode.ERR_EscapeVariable + or ErrorCode.ERR_EscapeStackAlloc + or ErrorCode.ERR_RefReturnThis + or ErrorCode.ERR_OutAttrOnInParam + or ErrorCode.ERR_PredefinedValueTupleTypeAmbiguous3 + or ErrorCode.ERR_InvalidVersionFormatDeterministic + or ErrorCode.ERR_AttributeCtorInParameter + or ErrorCode.WRN_FilterIsConstantFalse + or ErrorCode.WRN_FilterIsConstantFalseRedundantTryCatch + or ErrorCode.ERR_ConditionalInInterpolation + or ErrorCode.ERR_CantUseVoidInArglist + or ErrorCode.ERR_InDynamicMethodArg + or ErrorCode.ERR_FeatureNotAvailableInVersion7_3 + or ErrorCode.WRN_AttributesOnBackingFieldsNotAvailable + or ErrorCode.ERR_DoNotUseFixedBufferAttrOnProperty + or ErrorCode.ERR_RefLocalOrParamExpected + or ErrorCode.ERR_RefAssignNarrower + or ErrorCode.ERR_NewBoundWithUnmanaged + or ErrorCode.ERR_UnmanagedConstraintNotSatisfied + or ErrorCode.ERR_CantUseInOrOutInArglist + or ErrorCode.ERR_ConWithUnmanagedCon + or ErrorCode.ERR_UnmanagedBoundWithClass + or ErrorCode.ERR_InvalidStackAllocArray + or ErrorCode.ERR_ExpressionTreeContainsTupleBinOp + or ErrorCode.WRN_TupleBinopLiteralNameMismatch + or ErrorCode.ERR_TupleSizesMismatchForBinOps + or ErrorCode.ERR_ExprCannotBeFixed + or ErrorCode.ERR_InvalidObjectCreation + or ErrorCode.WRN_TypeParameterSameAsOuterMethodTypeParameter + or ErrorCode.ERR_OutVariableCannotBeByRef + or ErrorCode.ERR_DeconstructVariableCannotBeByRef + or ErrorCode.ERR_OmittedTypeArgument + or ErrorCode.ERR_FeatureNotAvailableInVersion8 + or ErrorCode.ERR_AltInterpolatedVerbatimStringsNotAvailable + or ErrorCode.ERR_IteratorMustBeAsync + or ErrorCode.ERR_NoConvToIAsyncDisp + or ErrorCode.ERR_AwaitForEachMissingMember + or ErrorCode.ERR_BadGetAsyncEnumerator + or ErrorCode.ERR_MultipleIAsyncEnumOfT + or ErrorCode.ERR_ForEachMissingMemberWrongAsync + or ErrorCode.ERR_AwaitForEachMissingMemberWrongAsync + or ErrorCode.ERR_BadDynamicAwaitForEach + or ErrorCode.ERR_NoConvToIAsyncDispWrongAsync + or ErrorCode.ERR_NoConvToIDispWrongAsync + or ErrorCode.ERR_StaticLocalFunctionCannotCaptureVariable + or ErrorCode.ERR_StaticLocalFunctionCannotCaptureThis + or ErrorCode.ERR_AttributeNotOnEventAccessor + or ErrorCode.WRN_UnconsumedEnumeratorCancellationAttributeUsage + or ErrorCode.WRN_UndecoratedCancellationTokenParameter + or ErrorCode.ERR_MultipleEnumeratorCancellationAttributes + or ErrorCode.ERR_VarianceInterfaceNesting + or ErrorCode.ERR_ImplicitIndexIndexerWithName + or ErrorCode.ERR_ImplicitRangeIndexerWithName + or ErrorCode.ERR_WrongNumberOfSubpatterns + or ErrorCode.ERR_PropertyPatternNameMissing + or ErrorCode.ERR_MissingPattern + or ErrorCode.ERR_DefaultPattern + or ErrorCode.ERR_SwitchExpressionNoBestType + or ErrorCode.ERR_VarMayNotBindToType + or ErrorCode.WRN_SwitchExpressionNotExhaustive + or ErrorCode.ERR_SwitchArmSubsumed + or ErrorCode.ERR_ConstantPatternVsOpenType + or ErrorCode.WRN_CaseConstantNamedUnderscore + or ErrorCode.WRN_IsTypeNamedUnderscore + or ErrorCode.ERR_ExpressionTreeContainsSwitchExpression + or ErrorCode.ERR_SwitchGoverningExpressionRequiresParens + or ErrorCode.ERR_TupleElementNameMismatch + or ErrorCode.ERR_DeconstructParameterNameMismatch + or ErrorCode.ERR_IsPatternImpossible + or ErrorCode.WRN_GivenExpressionNeverMatchesPattern + or ErrorCode.WRN_GivenExpressionAlwaysMatchesConstant + or ErrorCode.ERR_PointerTypeInPatternMatching + or ErrorCode.ERR_ArgumentNameInITuplePattern + or ErrorCode.ERR_DiscardPatternInSwitchStatement + or ErrorCode.WRN_SwitchExpressionNotExhaustiveWithUnnamedEnumValue + or ErrorCode.WRN_ThrowPossibleNull + or ErrorCode.ERR_IllegalSuppression + or ErrorCode.WRN_ConvertingNullableToNonNullable + or ErrorCode.WRN_NullReferenceAssignment + or ErrorCode.WRN_NullReferenceReceiver + or ErrorCode.WRN_NullReferenceReturn + or ErrorCode.WRN_NullReferenceArgument + or ErrorCode.WRN_UnboxPossibleNull + or ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment + or ErrorCode.WRN_NullabilityMismatchInTypeOnOverride + or ErrorCode.WRN_NullabilityMismatchInReturnTypeOnOverride + or ErrorCode.WRN_NullabilityMismatchInParameterTypeOnOverride + or ErrorCode.WRN_NullabilityMismatchInParameterTypeOnPartial + or ErrorCode.WRN_NullabilityMismatchInTypeOnImplicitImplementation + or ErrorCode.WRN_NullabilityMismatchInReturnTypeOnImplicitImplementation + or ErrorCode.WRN_NullabilityMismatchInParameterTypeOnImplicitImplementation + or ErrorCode.WRN_NullabilityMismatchInTypeOnExplicitImplementation + or ErrorCode.WRN_NullabilityMismatchInReturnTypeOnExplicitImplementation + or ErrorCode.WRN_NullabilityMismatchInParameterTypeOnExplicitImplementation + or ErrorCode.WRN_UninitializedNonNullableField + or ErrorCode.WRN_NullabilityMismatchInAssignment + or ErrorCode.WRN_NullabilityMismatchInArgument + or ErrorCode.WRN_NullabilityMismatchInReturnTypeOfTargetDelegate + or ErrorCode.WRN_NullabilityMismatchInParameterTypeOfTargetDelegate + or ErrorCode.ERR_ExplicitNullableAttribute + or ErrorCode.WRN_NullabilityMismatchInArgumentForOutput + or ErrorCode.WRN_NullAsNonNullable + or ErrorCode.ERR_NullableUnconstrainedTypeParameter + or ErrorCode.ERR_AnnotationDisallowedInObjectCreation + or ErrorCode.WRN_NullableValueTypeMayBeNull + or ErrorCode.ERR_NullableOptionNotAvailable + or ErrorCode.WRN_NullabilityMismatchInTypeParameterConstraint + or ErrorCode.WRN_MissingNonNullTypesContextForAnnotation + or ErrorCode.WRN_NullabilityMismatchInConstraintsOnImplicitImplementation + or ErrorCode.WRN_NullabilityMismatchInTypeParameterReferenceTypeConstraint + or ErrorCode.ERR_TripleDotNotAllowed + or ErrorCode.ERR_BadNullableContextOption + or ErrorCode.ERR_NullableDirectiveQualifierExpected + or ErrorCode.ERR_BadNullableTypeof + or ErrorCode.ERR_ExpressionTreeCantContainRefStruct + or ErrorCode.ERR_ElseCannotStartStatement + or ErrorCode.ERR_ExpressionTreeCantContainNullCoalescingAssignment + or ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface + or ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase + or ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList + or ErrorCode.ERR_DuplicateExplicitImpl + or ErrorCode.ERR_UsingVarInSwitchCase + or ErrorCode.ERR_GoToForwardJumpOverUsingVar + or ErrorCode.ERR_GoToBackwardJumpOverUsingVar + or ErrorCode.ERR_IsNullableType + or ErrorCode.ERR_AsNullableType + or ErrorCode.ERR_FeatureInPreview + or ErrorCode.WRN_SwitchExpressionNotExhaustiveForNull + or ErrorCode.WRN_ImplicitCopyInReadOnlyMember + or ErrorCode.ERR_StaticMemberCantBeReadOnly + or ErrorCode.ERR_AutoSetterCantBeReadOnly + or ErrorCode.ERR_AutoPropertyWithSetterCantBeReadOnly + or ErrorCode.ERR_InvalidPropertyReadOnlyMods + or ErrorCode.ERR_DuplicatePropertyReadOnlyMods + or ErrorCode.ERR_FieldLikeEventCantBeReadOnly + or ErrorCode.ERR_PartialMethodReadOnlyDifference + or ErrorCode.ERR_ReadOnlyModMissingAccessor + or ErrorCode.ERR_OverrideRefConstraintNotSatisfied + or ErrorCode.ERR_OverrideValConstraintNotSatisfied + or ErrorCode.WRN_NullabilityMismatchInConstraintsOnPartialImplementation + or ErrorCode.ERR_NullableDirectiveTargetExpected + or ErrorCode.WRN_MissingNonNullTypesContextForAnnotationInGeneratedCode + or ErrorCode.WRN_NullReferenceInitializer + or ErrorCode.ERR_MultipleAnalyzerConfigsInSameDir + or ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation + or ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember + or ErrorCode.ERR_InvalidModifierForLanguageVersion + or ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember + or ErrorCode.ERR_MostSpecificImplementationIsNotFound + or ErrorCode.ERR_LanguageVersionDoesNotSupportInterfaceImplementationForMember + or ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember + or ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType + or ErrorCode.ERR_AbstractEventHasAccessors + or ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint + or ErrorCode.ERR_DuplicateNullSuppression + or ErrorCode.ERR_DefaultLiteralNoTargetType + or ErrorCode.ERR_ReAbstractionInNoPIAType + or ErrorCode.ERR_InternalError + or ErrorCode.ERR_ImplicitObjectCreationIllegalTargetType + or ErrorCode.ERR_ImplicitObjectCreationNotValid + or ErrorCode.ERR_ImplicitObjectCreationNoTargetType + or ErrorCode.ERR_BadFuncPointerParamModifier + or ErrorCode.ERR_BadFuncPointerArgCount + or ErrorCode.ERR_MethFuncPtrMismatch + or ErrorCode.ERR_FuncPtrRefMismatch + or ErrorCode.ERR_FuncPtrMethMustBeStatic + or ErrorCode.ERR_ExternEventInitializer + or ErrorCode.ERR_AmbigBinaryOpsOnUnconstrainedDefault + or ErrorCode.WRN_ParameterConditionallyDisallowsNull + or ErrorCode.WRN_ShouldNotReturn + or ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnOverride + or ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnOverride + or ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnImplicitImplementation + or ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnImplicitImplementation + or ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnExplicitImplementation + or ErrorCode.WRN_TopLevelNullabilityMismatchInParameterTypeOnExplicitImplementation + or ErrorCode.WRN_DoesNotReturnMismatch + or ErrorCode.ERR_NoOutputDirectory + or ErrorCode.ERR_StdInOptionProvidedButConsoleInputIsNotRedirected + or ErrorCode.ERR_FeatureNotAvailableInVersion9 + or ErrorCode.WRN_MemberNotNull + or ErrorCode.WRN_MemberNotNullWhen + or ErrorCode.WRN_MemberNotNullBadMember + or ErrorCode.WRN_ParameterDisallowsNull + or ErrorCode.WRN_ConstOutOfRangeChecked + or ErrorCode.ERR_DuplicateInterfaceWithDifferencesInBaseList + or ErrorCode.ERR_DesignatorBeneathPatternCombinator + or ErrorCode.ERR_UnsupportedTypeForRelationalPattern + or ErrorCode.ERR_RelationalPatternWithNaN + or ErrorCode.ERR_ConditionalOnLocalFunction + or ErrorCode.WRN_GeneratorFailedDuringInitialization + or ErrorCode.WRN_GeneratorFailedDuringGeneration + or ErrorCode.ERR_WrongFuncPtrCallingConvention + or ErrorCode.ERR_MissingAddressOf + or ErrorCode.ERR_CannotUseReducedExtensionMethodInAddressOf + or ErrorCode.ERR_CannotUseFunctionPointerAsFixedLocal + or ErrorCode.ERR_ExpressionTreeContainsPatternImplicitIndexer + or ErrorCode.ERR_ExpressionTreeContainsFromEndIndexExpression + or ErrorCode.ERR_ExpressionTreeContainsRangeExpression + or ErrorCode.WRN_GivenExpressionAlwaysMatchesPattern + or ErrorCode.WRN_IsPatternAlways + or ErrorCode.ERR_PartialMethodWithAccessibilityModsMustHaveImplementation + or ErrorCode.ERR_PartialMethodWithNonVoidReturnMustHaveAccessMods + or ErrorCode.ERR_PartialMethodWithOutParamMustHaveAccessMods + or ErrorCode.ERR_PartialMethodWithExtendedModMustHaveAccessMods + or ErrorCode.ERR_PartialMethodAccessibilityDifference + or ErrorCode.ERR_PartialMethodExtendedModDifference + or ErrorCode.ERR_SimpleProgramLocalIsReferencedOutsideOfTopLevelStatement + or ErrorCode.ERR_SimpleProgramMultipleUnitsWithTopLevelStatements + or ErrorCode.ERR_TopLevelStatementAfterNamespaceOrType + or ErrorCode.ERR_SimpleProgramDisallowsMainType + or ErrorCode.ERR_SimpleProgramNotAnExecutable + or ErrorCode.ERR_UnsupportedCallingConvention + or ErrorCode.ERR_InvalidFunctionPointerCallingConvention + or ErrorCode.ERR_InvalidFuncPointerReturnTypeModifier + or ErrorCode.ERR_DupReturnTypeMod + or ErrorCode.ERR_AddressOfMethodGroupInExpressionTree + or ErrorCode.ERR_CannotConvertAddressOfToDelegate + or ErrorCode.ERR_AddressOfToNonFunctionPointer + or ErrorCode.ERR_ModuleInitializerMethodMustBeOrdinary + or ErrorCode.ERR_ModuleInitializerMethodMustBeAccessibleOutsideTopLevelType + or ErrorCode.ERR_ModuleInitializerMethodMustBeStaticParameterlessVoid + or ErrorCode.ERR_ModuleInitializerMethodAndContainingTypesMustNotBeGeneric + or ErrorCode.ERR_PartialMethodReturnTypeDifference + or ErrorCode.ERR_PartialMethodRefReturnDifference + or ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial + or ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureVariable + or ErrorCode.ERR_StaticAnonymousFunctionCannotCaptureThis + or ErrorCode.ERR_OverrideDefaultConstraintNotSatisfied + or ErrorCode.ERR_DefaultConstraintOverrideOnly + or ErrorCode.WRN_ParameterNotNullIfNotNull + or ErrorCode.WRN_ReturnNotNullIfNotNull + or ErrorCode.WRN_PartialMethodTypeDifference + or ErrorCode.ERR_RuntimeDoesNotSupportCovariantReturnsOfClasses + or ErrorCode.ERR_RuntimeDoesNotSupportCovariantPropertiesOfClasses + or ErrorCode.WRN_SwitchExpressionNotExhaustiveWithWhen + or ErrorCode.WRN_SwitchExpressionNotExhaustiveForNullWithWhen + or ErrorCode.WRN_PrecedenceInversion + or ErrorCode.ERR_ExpressionTreeContainsWithExpression + or ErrorCode.WRN_AnalyzerReferencesFramework + or ErrorCode.WRN_RecordEqualsWithoutGetHashCode + or ErrorCode.ERR_AssignmentInitOnly + or ErrorCode.ERR_CantChangeInitOnlyOnOverride + or ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongInitOnly + or ErrorCode.ERR_ExplicitPropertyMismatchInitOnly + or ErrorCode.ERR_BadInitAccessor + or ErrorCode.ERR_InvalidWithReceiverType + or ErrorCode.ERR_CannotClone + or ErrorCode.ERR_CloneDisallowedInRecord + or ErrorCode.WRN_RecordNamedDisallowed + or ErrorCode.ERR_UnexpectedArgumentList + or ErrorCode.ERR_UnexpectedOrMissingConstructorInitializerInRecord + or ErrorCode.ERR_MultipleRecordParameterLists + or ErrorCode.ERR_BadRecordBase + or ErrorCode.ERR_BadInheritanceFromRecord + or ErrorCode.ERR_BadRecordMemberForPositionalParameter + or ErrorCode.ERR_NoCopyConstructorInBaseType + or ErrorCode.ERR_CopyConstructorMustInvokeBaseCopyConstructor + or ErrorCode.ERR_DoesNotOverrideMethodFromObject + or ErrorCode.ERR_SealedAPIInRecord + or ErrorCode.ERR_DoesNotOverrideBaseMethod + or ErrorCode.ERR_NotOverridableAPIInRecord + or ErrorCode.ERR_NonPublicAPIInRecord + or ErrorCode.ERR_SignatureMismatchInRecord + or ErrorCode.ERR_NonProtectedAPIInRecord + or ErrorCode.ERR_DoesNotOverrideBaseEqualityContract + or ErrorCode.ERR_StaticAPIInRecord + or ErrorCode.ERR_CopyConstructorWrongAccessibility + or ErrorCode.ERR_NonPrivateAPIInRecord + or ErrorCode.WRN_UnassignedThisAutoPropertyUnsupportedVersion + or ErrorCode.WRN_UnassignedThisUnsupportedVersion + or ErrorCode.WRN_ParamUnassigned + or ErrorCode.WRN_UseDefViolationProperty + or ErrorCode.WRN_UseDefViolationField + or ErrorCode.WRN_UseDefViolationThisUnsupportedVersion + or ErrorCode.WRN_UseDefViolationOut + or ErrorCode.WRN_UseDefViolation + or ErrorCode.ERR_CannotSpecifyManagedWithUnmanagedSpecifiers + or ErrorCode.ERR_RuntimeDoesNotSupportUnmanagedDefaultCallConv + or ErrorCode.ERR_TypeNotFound + or ErrorCode.ERR_TypeMustBePublic + or ErrorCode.ERR_InvalidUnmanagedCallersOnlyCallConv + or ErrorCode.ERR_CannotUseManagedTypeInUnmanagedCallersOnly + or ErrorCode.ERR_UnmanagedCallersOnlyMethodOrTypeCannotBeGeneric + or ErrorCode.ERR_UnmanagedCallersOnlyRequiresStatic + or ErrorCode.WRN_ParameterIsStaticClass + or ErrorCode.WRN_ReturnTypeIsStaticClass + or ErrorCode.ERR_EntryPointCannotBeUnmanagedCallersOnly + or ErrorCode.ERR_ModuleInitializerCannotBeUnmanagedCallersOnly + or ErrorCode.ERR_UnmanagedCallersOnlyMethodsCannotBeCalledDirectly + or ErrorCode.ERR_UnmanagedCallersOnlyMethodsCannotBeConvertedToDelegate + or ErrorCode.ERR_InitCannotBeReadonly + or ErrorCode.ERR_UnexpectedVarianceStaticMember + or ErrorCode.ERR_FunctionPointersCannotBeCalledWithNamedArguments + or ErrorCode.ERR_EqualityContractRequiresGetter + or ErrorCode.WRN_UnreadRecordParameter + or ErrorCode.ERR_BadFieldTypeInRecord + or ErrorCode.WRN_DoNotCompareFunctionPointers + or ErrorCode.ERR_RecordAmbigCtor + or ErrorCode.ERR_FunctionPointerTypesInAttributeNotSupported + or ErrorCode.ERR_InheritingFromRecordWithSealedToString + or ErrorCode.ERR_HiddenPositionalMember + or ErrorCode.ERR_GlobalUsingInNamespace + or ErrorCode.ERR_GlobalUsingOutOfOrder + or ErrorCode.ERR_AttributesRequireParenthesizedLambdaExpression + or ErrorCode.ERR_CannotInferDelegateType + or ErrorCode.ERR_InvalidNameInSubpattern + or ErrorCode.ERR_RuntimeDoesNotSupportStaticAbstractMembersInInterfaces + or ErrorCode.ERR_GenericConstraintNotSatisfiedInterfaceWithStaticAbstractMembers + or ErrorCode.ERR_BadAbstractUnaryOperatorSignature + or ErrorCode.ERR_BadAbstractIncDecSignature + or ErrorCode.ERR_BadAbstractIncDecRetType + or ErrorCode.ERR_BadAbstractBinaryOperatorSignature + or ErrorCode.ERR_BadAbstractShiftOperatorSignature + or ErrorCode.ERR_BadAbstractStaticMemberAccess + or ErrorCode.ERR_ExpressionTreeContainsAbstractStaticMemberAccess + or ErrorCode.ERR_CloseUnimplementedInterfaceMemberNotStatic + or ErrorCode.ERR_RuntimeDoesNotSupportStaticAbstractMembersInInterfacesForMember + or ErrorCode.ERR_ExplicitImplementationOfOperatorsMustBeStatic + or ErrorCode.ERR_AbstractConversionNotInvolvingContainedType + or ErrorCode.ERR_InterfaceImplementedByUnmanagedCallersOnlyMethod + or ErrorCode.HDN_DuplicateWithGlobalUsing + or ErrorCode.ERR_CantConvAnonMethReturnType + or ErrorCode.ERR_BuilderAttributeDisallowed + or ErrorCode.ERR_FeatureNotAvailableInVersion10 + or ErrorCode.ERR_SimpleProgramIsEmpty + or ErrorCode.ERR_LineSpanDirectiveInvalidValue + or ErrorCode.ERR_LineSpanDirectiveEndLessThanStart + or ErrorCode.ERR_WrongArityAsyncReturn + or ErrorCode.ERR_InterpolatedStringHandlerMethodReturnMalformed + or ErrorCode.ERR_InterpolatedStringHandlerMethodReturnInconsistent + or ErrorCode.ERR_NullInvalidInterpolatedStringHandlerArgumentName + or ErrorCode.ERR_NotInstanceInvalidInterpolatedStringHandlerArgumentName + or ErrorCode.ERR_InvalidInterpolatedStringHandlerArgumentName + or ErrorCode.ERR_TypeIsNotAnInterpolatedStringHandlerType + or ErrorCode.WRN_ParameterOccursAfterInterpolatedStringHandlerParameter + or ErrorCode.ERR_CannotUseSelfAsInterpolatedStringHandlerArgument + or ErrorCode.ERR_InterpolatedStringHandlerArgumentAttributeMalformed + or ErrorCode.ERR_InterpolatedStringHandlerArgumentLocatedAfterInterpolatedString + or ErrorCode.ERR_InterpolatedStringHandlerArgumentOptionalNotSpecified + or ErrorCode.ERR_ExpressionTreeContainsInterpolatedStringHandlerConversion + or ErrorCode.ERR_InterpolatedStringHandlerCreationCannotUseDynamic + or ErrorCode.ERR_MultipleFileScopedNamespace + or ErrorCode.ERR_FileScopedAndNormalNamespace + or ErrorCode.ERR_FileScopedNamespaceNotBeforeAllMembers + or ErrorCode.ERR_NoImplicitConvTargetTypedConditional + or ErrorCode.ERR_NonPublicParameterlessStructConstructor + or ErrorCode.ERR_NoConversionForCallerArgumentExpressionParam + or ErrorCode.WRN_CallerLineNumberPreferredOverCallerArgumentExpression + or ErrorCode.WRN_CallerFilePathPreferredOverCallerArgumentExpression + or ErrorCode.WRN_CallerMemberNamePreferredOverCallerArgumentExpression + or ErrorCode.WRN_CallerArgumentExpressionAttributeHasInvalidParameterName + or ErrorCode.ERR_BadCallerArgumentExpressionParamWithoutDefaultValue + or ErrorCode.WRN_CallerArgumentExpressionAttributeSelfReferential + or ErrorCode.WRN_CallerArgumentExpressionParamForUnconsumedLocation + or ErrorCode.ERR_NewlinesAreNotAllowedInsideANonVerbatimInterpolatedString + or ErrorCode.ERR_AttrTypeArgCannotBeTypeVar + or ErrorCode.ERR_AttrDependentTypeNotAllowed + or ErrorCode.WRN_InterpolatedStringHandlerArgumentAttributeIgnoredOnLambdaParameters + or ErrorCode.ERR_LambdaWithAttributesToExpressionTree + or ErrorCode.WRN_CompileTimeCheckedOverflow + or ErrorCode.WRN_MethGrpToNonDel + or ErrorCode.ERR_LambdaExplicitReturnTypeVar + or ErrorCode.ERR_InterpolatedStringsReferencingInstanceCannotBeInObjectInitializers + or ErrorCode.ERR_CannotUseRefInUnmanagedCallersOnly + or ErrorCode.ERR_CannotBeMadeNullable + or ErrorCode.ERR_UnsupportedTypeForListPattern + or ErrorCode.ERR_MisplacedSlicePattern + or ErrorCode.WRN_LowerCaseTypeName + or ErrorCode.ERR_RecordStructConstructorCallsDefaultConstructor + or ErrorCode.ERR_StructHasInitializersAndNoDeclaredConstructor + or ErrorCode.ERR_ListPatternRequiresLength + or ErrorCode.ERR_ScopedMismatchInParameterOfTarget + or ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation + or ErrorCode.ERR_ScopedMismatchInParameterOfPartial + or ErrorCode.ERR_ParameterNullCheckingNotSupported + or ErrorCode.ERR_RawStringNotInDirectives + or ErrorCode.ERR_UnterminatedRawString + or ErrorCode.ERR_TooManyQuotesForRawString + or ErrorCode.ERR_LineDoesNotStartWithSameWhitespace + or ErrorCode.ERR_RawStringDelimiterOnOwnLine + or ErrorCode.ERR_RawStringInVerbatimInterpolatedStrings + or ErrorCode.ERR_RawStringMustContainContent + or ErrorCode.ERR_LineContainsDifferentWhitespace + or ErrorCode.ERR_NotEnoughQuotesForRawString + or ErrorCode.ERR_NotEnoughCloseBracesForRawString + or ErrorCode.ERR_TooManyOpenBracesForRawString + or ErrorCode.ERR_TooManyCloseBracesForRawString + or ErrorCode.ERR_IllegalAtSequence + or ErrorCode.ERR_StringMustStartWithQuoteCharacter + or ErrorCode.ERR_NoEnumConstraint + or ErrorCode.ERR_NoDelegateConstraint + or ErrorCode.ERR_MisplacedRecord + or ErrorCode.ERR_PatternSpanCharCannotBeStringNull + or ErrorCode.ERR_UseDefViolationPropertyUnsupportedVersion + or ErrorCode.ERR_UseDefViolationFieldUnsupportedVersion + or ErrorCode.WRN_UseDefViolationPropertyUnsupportedVersion + or ErrorCode.WRN_UseDefViolationFieldUnsupportedVersion + or ErrorCode.WRN_UseDefViolationPropertySupportedVersion + or ErrorCode.WRN_UseDefViolationFieldSupportedVersion + or ErrorCode.WRN_UseDefViolationThisSupportedVersion + or ErrorCode.WRN_UnassignedThisAutoPropertySupportedVersion + or ErrorCode.WRN_UnassignedThisSupportedVersion + or ErrorCode.ERR_OperatorCantBeChecked + or ErrorCode.ERR_ImplicitConversionOperatorCantBeChecked + or ErrorCode.ERR_CheckedOperatorNeedsMatch + or ErrorCode.ERR_MisplacedUnchecked + or ErrorCode.ERR_LineSpanDirectiveRequiresSpace + or ErrorCode.ERR_RequiredNameDisallowed + or ErrorCode.ERR_OverrideMustHaveRequired + or ErrorCode.ERR_RequiredMemberCannotBeHidden + or ErrorCode.ERR_RequiredMemberCannotBeLessVisibleThanContainingType + or ErrorCode.ERR_ExplicitRequiredMember + or ErrorCode.ERR_RequiredMemberMustBeSettable + or ErrorCode.ERR_RequiredMemberMustBeSet + or ErrorCode.ERR_RequiredMembersMustBeAssignedValue + or ErrorCode.ERR_RequiredMembersInvalid + or ErrorCode.ERR_RequiredMembersBaseTypeInvalid + or ErrorCode.ERR_ChainingToSetsRequiredMembersRequiresSetsRequiredMembers + or ErrorCode.ERR_NewConstraintCannotHaveRequiredMembers + or ErrorCode.ERR_UnsupportedCompilerFeature + or ErrorCode.WRN_ObsoleteMembersShouldNotBeRequired + or ErrorCode.ERR_RefReturningPropertiesCannotBeRequired + or ErrorCode.ERR_ImplicitImplementationOfInaccessibleInterfaceMember + or ErrorCode.ERR_ScriptsAndSubmissionsCannotHaveRequiredMembers + or ErrorCode.ERR_BadAbstractEqualityOperatorSignature + or ErrorCode.ERR_BadBinaryReadOnlySpanConcatenation + or ErrorCode.ERR_ScopedRefAndRefStructOnly + or ErrorCode.ERR_ScopedDiscard + or ErrorCode.ERR_FixedFieldMustNotBeRef + or ErrorCode.ERR_RefFieldCannotReferToRefStruct + or ErrorCode.ERR_FileTypeDisallowedInSignature + or ErrorCode.ERR_FileTypeNoExplicitAccessibility + or ErrorCode.ERR_FileTypeBase + or ErrorCode.ERR_FileTypeNested + or ErrorCode.ERR_GlobalUsingStaticFileType + or ErrorCode.ERR_FileTypeNameDisallowed + or ErrorCode.ERR_FeatureNotAvailableInVersion11 + or ErrorCode.ERR_RefFieldInNonRefStruct + or ErrorCode.WRN_AnalyzerReferencesNewerCompiler + or ErrorCode.ERR_CannotMatchOnINumberBase + or ErrorCode.ERR_ScopedTypeNameDisallowed + or ErrorCode.ERR_ImplicitlyTypedDefaultParameter + or ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget + or ErrorCode.ERR_RuntimeDoesNotSupportRefFields + or ErrorCode.ERR_ExplicitScopedRef + or ErrorCode.ERR_UnscopedScoped + or ErrorCode.WRN_DuplicateAnalyzerReference + or ErrorCode.ERR_FilePathCannotBeConvertedToUtf8 + or ErrorCode.ERR_FileLocalDuplicateNameInNS + or ErrorCode.WRN_ScopedMismatchInParameterOfTarget + or ErrorCode.WRN_ScopedMismatchInParameterOfOverrideOrImplementation + or ErrorCode.ERR_RefReturnScopedParameter + or ErrorCode.ERR_RefReturnScopedParameter2 + or ErrorCode.ERR_RefReturnOnlyParameter + or ErrorCode.ERR_RefReturnOnlyParameter2 + or ErrorCode.ERR_RefAssignReturnOnly + or ErrorCode.WRN_ManagedAddr + or ErrorCode.WRN_EscapeVariable + or ErrorCode.WRN_EscapeStackAlloc + or ErrorCode.WRN_RefReturnNonreturnableLocal + or ErrorCode.WRN_RefReturnNonreturnableLocal2 + or ErrorCode.WRN_RefReturnStructThis + or ErrorCode.WRN_RefAssignNarrower + or ErrorCode.WRN_MismatchedRefEscapeInTernary + or ErrorCode.WRN_RefReturnParameter + or ErrorCode.WRN_RefReturnScopedParameter + or ErrorCode.WRN_RefReturnParameter2 + or ErrorCode.WRN_RefReturnScopedParameter2 + or ErrorCode.WRN_RefReturnLocal + or ErrorCode.WRN_RefReturnLocal2 + or ErrorCode.WRN_RefAssignReturnOnly + or ErrorCode.WRN_RefReturnOnlyParameter + or ErrorCode.WRN_RefReturnOnlyParameter2 + or ErrorCode.ERR_RefAssignValEscapeWider + or ErrorCode.WRN_RefAssignValEscapeWider + or ErrorCode.WRN_OptionalParamValueMismatch + or ErrorCode.WRN_ParamsArrayInLambdaOnly + or ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget + or ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation + or ErrorCode.ERR_UnrecognizedRefSafetyRulesAttributeVersion + or ErrorCode.ERR_InvalidPrimaryConstructorParameterReference + or ErrorCode.ERR_AmbiguousPrimaryConstructorParameterAsColorColorReceiver + or ErrorCode.WRN_CapturedPrimaryConstructorParameterPassedToBase + or ErrorCode.WRN_UnreadPrimaryConstructorParameter + or ErrorCode.ERR_AssgReadonlyPrimaryConstructorParameter + or ErrorCode.ERR_RefReturnReadonlyPrimaryConstructorParameter + or ErrorCode.ERR_RefReadonlyPrimaryConstructorParameter + or ErrorCode.ERR_AssgReadonlyPrimaryConstructorParameter2 + or ErrorCode.ERR_RefReturnReadonlyPrimaryConstructorParameter2 + or ErrorCode.ERR_RefReadonlyPrimaryConstructorParameter2 + or ErrorCode.ERR_RefReturnPrimaryConstructorParameter + or ErrorCode.ERR_StructLayoutCyclePrimaryConstructorParameter + or ErrorCode.ERR_UnexpectedParameterList + or ErrorCode.WRN_AddressOfInAsync + or ErrorCode.ERR_BadRefInUsingAlias + or ErrorCode.ERR_BadUnsafeInUsingDirective + or ErrorCode.ERR_BadNullableReferenceTypeInUsingAlias + or ErrorCode.ERR_BadStaticAfterUnsafe + or ErrorCode.ERR_BadCaseInSwitchArm + or ErrorCode.ERR_InterceptorsFeatureNotEnabled + or ErrorCode.ERR_InterceptorContainingTypeCannotBeGeneric + or ErrorCode.ERR_InterceptorPathNotInCompilation + or ErrorCode.ERR_InterceptorPathNotInCompilationWithCandidate + or ErrorCode.ERR_InterceptorPositionBadToken + or ErrorCode.ERR_InterceptorLineOutOfRange + or ErrorCode.ERR_InterceptorCharacterOutOfRange + or ErrorCode.ERR_InterceptorMethodMustBeOrdinary + or ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition + or ErrorCode.ERR_InterceptorFilePathCannotBeNull + or ErrorCode.ERR_InterceptorNameNotInvoked + or ErrorCode.ERR_InterceptorNonUniquePath + or ErrorCode.ERR_InterceptorLineCharacterMustBePositive + or ErrorCode.ERR_ConstantValueOfTypeExpected + or ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefAny + or ErrorCode.ERR_InterceptorCannotUseUnmanagedCallersOnly + or ErrorCode.ERR_BadUsingStaticType + or ErrorCode.WRN_CapturedPrimaryConstructorParameterInFieldInitializer + or ErrorCode.ERR_InlineArrayConversionToSpanNotSupported + or ErrorCode.ERR_InlineArrayConversionToReadOnlySpanNotSupported + or ErrorCode.ERR_InlineArrayIndexOutOfRange + or ErrorCode.ERR_InvalidInlineArrayLength + or ErrorCode.ERR_InvalidInlineArrayLayout + or ErrorCode.ERR_InvalidInlineArrayFields + or ErrorCode.ERR_ExpressionTreeContainsInlineArrayOperation + or ErrorCode.ERR_RuntimeDoesNotSupportInlineArrayTypes + or ErrorCode.ERR_InlineArrayBadIndex + or ErrorCode.ERR_NamedArgumentForInlineArray + or ErrorCode.ERR_CollectionExpressionTargetTypeNotConstructible + or ErrorCode.ERR_ExpressionTreeContainsCollectionExpression + or ErrorCode.ERR_CollectionExpressionNoTargetType + or ErrorCode.WRN_PrimaryConstructorParameterIsShadowedAndNotPassedToBase + or ErrorCode.ERR_InlineArrayUnsupportedElementFieldModifier + or ErrorCode.WRN_InlineArrayIndexerNotUsed + or ErrorCode.WRN_InlineArraySliceNotUsed + or ErrorCode.WRN_InlineArrayConversionOperatorNotUsed + or ErrorCode.WRN_InlineArrayNotSupportedByLanguage + or ErrorCode.ERR_CollectionBuilderAttributeMethodNotFound + or ErrorCode.ERR_CollectionBuilderAttributeInvalidType + or ErrorCode.ERR_CollectionBuilderAttributeInvalidMethodName + or ErrorCode.ERR_CollectionBuilderNoElementType + or ErrorCode.ERR_InlineArrayForEachNotSupported + or ErrorCode.ERR_RefReadOnlyWrongOrdering + or ErrorCode.WRN_BadArgRef + or ErrorCode.WRN_ArgExpectedRefOrIn + or ErrorCode.WRN_RefReadonlyNotVariable + or ErrorCode.ERR_BadArgExtraRefLangVersion + or ErrorCode.WRN_ArgExpectedIn + or ErrorCode.WRN_OverridingDifferentRefness + or ErrorCode.WRN_HidingDifferentRefness + or ErrorCode.WRN_TargetDifferentRefness + or ErrorCode.ERR_OutAttrOnRefReadonlyParam + or ErrorCode.WRN_RefReadonlyParameterDefaultValue + or ErrorCode.WRN_ByValArraySizeConstRequired + or ErrorCode.WRN_UseDefViolationRefField + or ErrorCode.ERR_FeatureNotAvailableInVersion12 + or ErrorCode.ERR_CollectionExpressionEscape + or ErrorCode.WRN_Experimental + or ErrorCode.ERR_ExpectedInterpolatedString + or ErrorCode.ERR_InterceptorGlobalNamespace + or ErrorCode.WRN_CollectionExpressionRefStructMayAllocate + or ErrorCode.WRN_CollectionExpressionRefStructSpreadMayAllocate + or ErrorCode.ERR_CollectionExpressionImmutableArray + or ErrorCode.ERR_InvalidExperimentalDiagID + or ErrorCode.ERR_SpreadMissingMember + or ErrorCode.ERR_CollectionExpressionTargetNoElementType + or ErrorCode.ERR_CollectionExpressionMissingConstructor + or ErrorCode.ERR_CollectionExpressionMissingAdd + or ErrorCode.WRN_ConvertingLock + or ErrorCode.ERR_DynamicDispatchToParamsCollection + or ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument + or ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod + or ErrorCode.WRN_DynamicDispatchToParamsCollectionIndexer + or ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor + or ErrorCode.ERR_ParamsCollectionInfiniteChainOfConstructorCalls + or ErrorCode.ERR_ParamsMemberCannotBeLessVisibleThanDeclaringMember + or ErrorCode.ERR_ParamsCollectionConstructorDoesntInitializeRequiredMember + or ErrorCode.ERR_ParamsCollectionExpressionTree + or ErrorCode.ERR_ParamsCollectionExtensionAddMethod + or ErrorCode.ERR_ParamsCollectionMissingConstructor + or ErrorCode.ERR_NoModifiersOnUsing + or ErrorCode.ERR_CannotDynamicInvokeOnExpression + or ErrorCode.ERR_InterceptsLocationDataInvalidFormat + or ErrorCode.ERR_InterceptsLocationUnsupportedVersion + or ErrorCode.ERR_InterceptsLocationDuplicateFile + or ErrorCode.ERR_InterceptsLocationFileNotFound + or ErrorCode.ERR_InterceptsLocationDataInvalidPosition + or ErrorCode.INF_TooManyBoundLambdas + or ErrorCode.WRN_BadYieldInLock + or ErrorCode.ERR_BadYieldInUnsafe + or ErrorCode.ERR_AddressOfInIterator + or ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics + or ErrorCode.ERR_RefStructConstraintAlreadySpecified + or ErrorCode.ERR_AllowsClauseMustBeLast + or ErrorCode.ERR_ClassIsCombinedWithRefStruct + or ErrorCode.ERR_NotRefStructConstraintNotSatisfied + or ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember + or ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike + or ErrorCode.ERR_BadAllowByRefLikeEnumerator + => false, + }; +#pragma warning restore CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. } /// diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index 72f876baaa909..18fa9dbb51d6e 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -282,6 +282,10 @@ internal enum MessageID IDS_FeatureLockObject = MessageBase + 12841, IDS_FeatureParamsCollections = MessageBase + 12842, + + IDS_FeatureRefUnsafeInIteratorAsync = MessageBase + 12843, + + IDS_FeatureRefStructInterfaces = MessageBase + 12844, } // Message IDs may refer to strings that need to be localized. @@ -466,6 +470,8 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) case MessageID.IDS_FeatureImplicitIndexerInitializer: case MessageID.IDS_FeatureLockObject: case MessageID.IDS_FeatureParamsCollections: + case MessageID.IDS_FeatureRefUnsafeInIteratorAsync: + case MessageID.IDS_FeatureRefStructInterfaces: return LanguageVersion.Preview; // C# 12.0 features. diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/ControlFlowPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/ControlFlowPass.cs index f658b027842cb..c490fe273e06b 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/ControlFlowPass.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/ControlFlowPass.cs @@ -353,13 +353,12 @@ public override BoundNode VisitGotoStatement(BoundGotoStatement node) } else if (sourceStart > usingStart && targetStart < usingStart) { - // Backwards jump, so we must have already seen the label, or it must be a switch case label. If it is a switch case label, we know + // Backwards jump, so we must have already seen the label, or it must be a switch case label, or it might be in outer scope. If it is a switch case label, we know // that either the user received an error for having a using declaration at the top level in a switch statement, or the label is a valid // target to branch to. - Debug.Assert(_labelsDefined.ContainsKey(node.Label)); // Error if label and using are part of the same block - if (_labelsDefined[node.Label] == usingDecl.block) + if (_labelsDefined.TryGetValue(node.Label, out BoundNode target) && target == usingDecl.block) { Diagnostics.Add(ErrorCode.ERR_GoToBackwardJumpOverUsingVar, sourceLocation); break; diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index 91dc066983043..81109ab290733 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -4081,8 +4081,7 @@ void setAnalyzedNullabilityAsContinuation( if (symbol != null) { - Debug.Assert(TypeSymbol.Equals(objectInitializer.Type, symbol.GetTypeOrReturnType().Type, TypeCompareKind.IgnoreNullableModifiersForReferenceTypes) || - (symbol is PropertySymbol { IsIndexer: true } && objectInitializer.Type.IsDynamic())); + Debug.Assert(TypeSymbol.Equals(objectInitializer.Type, symbol.GetTypeOrReturnType().Type, TypeCompareKind.IgnoreNullableModifiersForReferenceTypes)); symbol = AsMemberOfType(containingType, symbol); } @@ -5441,35 +5440,20 @@ private static BoundExpression SkipReferenceConversions(BoundExpression possibly LearnFromNonNullTest(leftOperand, ref leftState); LearnFromNullTest(leftOperand, ref this.State); - var adjustedNodeType = node.Type; - if (LocalRewriter.ShouldConvertResultOfAssignmentToDynamic(node, leftOperand)) - { - Debug.Assert(leftOperand.Type is not null); - - if (node.IsNullableValueTypeAssignment) - { - adjustedNodeType = leftOperand.Type.GetNullableUnderlyingType(); - } - else - { - adjustedNodeType = leftOperand.Type; - } - } - // If we are assigning to a nullable value type variable, set the top-level state of // the LHS first, then change the slot to the Value property of the LHS to simulate // assignment of the RHS and update the nullable state of the underlying value type. if (node.IsNullableValueTypeAssignment) { Debug.Assert(targetType.Type.ContainsErrorType() || - adjustedNodeType?.ContainsErrorType() == true || - TypeSymbol.Equals(targetType.Type.GetNullableUnderlyingType(), adjustedNodeType, TypeCompareKind.AllIgnoreOptions)); + node.Type?.ContainsErrorType() == true || + TypeSymbol.Equals(targetType.Type.GetNullableUnderlyingType(), node.Type, TypeCompareKind.AllIgnoreOptions)); if (leftSlot > 0) { SetState(ref this.State, leftSlot, NullableFlowState.NotNull); leftSlot = GetNullableOfTValueSlot(targetType.Type, leftSlot, out _); } - targetType = TypeWithAnnotations.Create(adjustedNodeType, NullableAnnotation.NotAnnotated); + targetType = TypeWithAnnotations.Create(node.Type, NullableAnnotation.NotAnnotated); } TypeWithState rightResult = VisitOptionalImplicitConversion(rightOperand, targetType, useLegacyWarnings: UseLegacyWarnings(leftOperand), trackMembers: false, AssignmentKind.Assignment); @@ -5478,49 +5462,10 @@ private static BoundExpression SkipReferenceConversions(BoundExpression possibly Join(ref this.State, ref leftState); TypeWithState resultType = TypeWithState.Create(targetType.Type, rightResult.State); - - if (adjustedNodeType != (object?)node.Type) - { - Debug.Assert(adjustedNodeType is not null); - SetDynamicResult(node, resultType); - } - else - { - SetResultType(node, resultType); - } - + SetResultType(node, resultType); return null; } - /// - /// When an operation on an indexer with dynamic argument is resolved statically, - /// in some scenarios result type of the operation is set to 'dynamic' type. - /// - /// This helper takes care of the setting result type to 'dynamic' type. - /// - private void SetDynamicResult(BoundExpression node, TypeWithState sourceType) - { - Debug.Assert(node.Type is not null); - Debug.Assert(node.Type.IsDynamic()); - Debug.Assert(sourceType.Type is not null); - Debug.Assert(!sourceType.Type.IsDynamic()); - Debug.Assert(!sourceType.Type.IsVoidType()); - - var discardedUseSiteInfo = CompoundUseSiteInfo.Discarded; - - SetResultType(node, - VisitConversion( - conversionOpt: null, - conversionOperand: node, - _conversions.ClassifyConversionFromExpressionType(sourceType.Type, node.Type, isChecked: false, ref discardedUseSiteInfo), - targetTypeWithNullability: TypeWithAnnotations.Create(node.Type, NullableAnnotation.Annotated), - operandType: sourceType, - checkConversion: false, - fromExplicitCast: false, - useLegacyWarnings: false, - AssignmentKind.Assignment)); - } - public override BoundNode? VisitNullCoalescingOperator(BoundNullCoalescingOperator node) { Debug.Assert(!IsConditionalState); @@ -6211,16 +6156,7 @@ void reinferMethodAndVisitArguments(BoundCall node, TypeWithState receiverType, returnState = returnState.WithNotNullState(); } - if (node.Type.IsDynamic() && !node.Method.ReturnType.IsDynamic()) - { - Debug.Assert(!node.Method.ReturnsByRef); - SetDynamicResult(node, returnState); - } - else - { - SetResult(node, returnState, method.ReturnTypeWithAnnotations); - } - + SetResult(node, returnState, method.ReturnTypeWithAnnotations); SetUpdatedSymbol(node, node.Method, method); } } @@ -6783,27 +6719,26 @@ private ImmutableArray VisitArguments( (ParameterSymbol? parameter, TypeWithAnnotations parameterType, FlowAnalysisAnnotations parameterAnnotations, bool isExpandedParamsArgument) = GetCorrespondingParameter(i, parametersOpt, argsToParamsOpt, expanded, ref paramsIterationType); - if (// This is known to happen for certain error scenarios, because - // the parameter matching logic above is not as flexible as the one we use in `Binder.BuildArgumentsForErrorRecovery` - // so we may end up with a pending conversion completion for an argument apparently without a corresponding parameter. - parameter is null || - // In error recovery with named arguments, target-typing cannot work as we can get a different parameter type - // from our GetCorrespondingParameter logic than Binder.BuildArgumentsForErrorRecovery does. - node is BoundCall { HasErrors: true, ArgumentNamesOpt.IsDefaultOrEmpty: false, ArgsToParamsOpt.IsDefault: true }) + // This is known to happen for certain error scenarios, because + // the parameter matching logic above is not as flexible as the one we use in `Binder.BuildArgumentsForErrorRecovery` + // so we may end up with a pending conversion completion for an argument apparently without a corresponding parameter. + if (parameter is null) { - if (IsTargetTypedExpression(argumentNoConversion) && _targetTypedAnalysisCompletionOpt?.TryGetValue(argumentNoConversion, out var completion) is true) + if (tryShortCircuitTargetTypedExpression(argument, argumentNoConversion)) { - // We've done something wrong if we have a target-typed expression and registered an analysis continuation for it - // (we won't be able to complete that continuation) - // We flush the completion with a plausible/dummy type and remove it. - completion(TypeWithAnnotations.Create(argument.Type)); - TargetTypedAnalysisCompletion.Remove(argumentNoConversion); - - Debug.Assert(parameter is not null || method is ErrorMethodSymbol); + Debug.Assert(method is ErrorMethodSymbol); } continue; } + // In error recovery with named arguments, target-typing cannot work as we can get a different parameter type + // from our GetCorrespondingParameter logic than Binder.BuildArgumentsForErrorRecovery does. + if (node is BoundCall { HasErrors: true, ArgumentNamesOpt.IsDefaultOrEmpty: false, ArgsToParamsOpt.IsDefault: true } && + tryShortCircuitTargetTypedExpression(argument, argumentNoConversion)) + { + continue; + } + // We disable diagnostics when: // 1. the containing call has errors (to reduce cascading diagnostics) // 2. on implicit default arguments (since that's really only an issue with the declaration) @@ -6990,6 +6925,21 @@ static void expandParamsCollection(ref ImmutableArray arguments } } } + + bool tryShortCircuitTargetTypedExpression(BoundExpression argument, BoundExpression argumentNoConversion) + { + if (IsTargetTypedExpression(argumentNoConversion) && _targetTypedAnalysisCompletionOpt?.TryGetValue(argumentNoConversion, out var completion) is true) + { + // We've done something wrong if we have a target-typed expression and registered an analysis continuation for it + // (we won't be able to complete that continuation) + // We flush the completion with a plausible/dummy type and remove it. + completion(TypeWithAnnotations.Create(argument.Type)); + TargetTypedAnalysisCompletion.Remove(argumentNoConversion); + return true; + } + + return false; + } } private void ApplyMemberPostConditions(BoundExpression? receiverOpt, MethodSymbol? method) @@ -9843,7 +9793,7 @@ private void VisitThisOrBaseReference(BoundExpression node) } else { - SetResultConveringToDynamicIfNecessary(node, left, TypeWithState.Create(leftLValueType.Type, rightState.State), leftLValueType); + SetResult(node, TypeWithState.Create(leftLValueType.Type, rightState.State), leftLValueType); } AdjustSetValue(left, ref rightState); @@ -9853,21 +9803,6 @@ private void VisitThisOrBaseReference(BoundExpression node) return null; } - private void SetResultConveringToDynamicIfNecessary(BoundExpression originalAssignment, BoundExpression assignmentTarget, TypeWithState resultType, TypeWithAnnotations lvalueType) - { - Debug.Assert(originalAssignment.Type is not null); - Debug.Assert(assignmentTarget.Type is not null); - - if (LocalRewriter.ShouldConvertResultOfAssignmentToDynamic(originalAssignment, assignmentTarget)) - { - SetDynamicResult(originalAssignment, resultType); - } - else - { - SetResult(originalAssignment, resultType, lvalueType); - } - } - private bool IsPropertyOutputMoreStrictThanInput(PropertySymbol property) { var type = property.TypeWithAnnotations; @@ -10377,7 +10312,7 @@ private ImmutableArray GetDeconstructionRightParts(BoundExpress { var op = node.OperatorKind.Operator(); TypeWithState resultType = (op == UnaryOperatorKind.PrefixIncrement || op == UnaryOperatorKind.PrefixDecrement) ? resultOfIncrementType : operandType; - SetResultConveringToDynamicIfNecessary(node, node.Operand, resultType, resultType.ToTypeWithAnnotations(compilation)); + SetResultType(node, resultType); setResult = true; TrackNullableStateForAssignment(node, targetType: operandLvalue, targetSlot: MakeSlot(node.Operand), valueType: resultOfIncrementType); @@ -10445,7 +10380,7 @@ private ImmutableArray GetDeconstructionRightParts(BoundExpress // Handle `[DisallowNull]` on LHS operand (final assignment target). CheckDisallowedNullAssignment(resultTypeWithState, leftArgumentAnnotations, node.Syntax); - SetResultConveringToDynamicIfNecessary(node, node.Left, resultTypeWithState, resultTypeWithState.ToTypeWithAnnotations(compilation)); + SetResultType(node, resultTypeWithState); AdjustSetValue(node.Left, ref resultTypeWithState); Debug.Assert(MakeSlot(node) == -1); @@ -10583,17 +10518,7 @@ private TypeWithAnnotations GetDeclaredParameterResult(ParameterSymbol parameter VisitArguments(node, node.Arguments, node.ArgumentRefKindsOpt, indexer, node.ArgsToParamsOpt, node.DefaultArguments, node.Expanded); var resultType = ApplyUnconditionalAnnotations(indexer.TypeWithAnnotations.ToTypeWithState(), GetRValueAnnotations(indexer)); - - if (node.Type.IsDynamic() && !node.Indexer.Type.IsDynamic()) - { - Debug.Assert(!node.Indexer.ReturnsByRef); - SetDynamicResult(node, resultType); - } - else - { - SetResult(node, resultType, indexer.TypeWithAnnotations); - } - + SetResult(node, resultType, indexer.TypeWithAnnotations); SetUpdatedSymbol(node, node.Indexer, indexer); return null; } @@ -10797,7 +10722,7 @@ protected override void VisitForEachExpression(BoundForEachStatement node) // This is case 4. We need to look for the IEnumerable that this reinferred expression implements, // so that we pick up any nested type substitutions that could have occurred. var discardedUseSiteInfo = CompoundUseSiteInfo.Discarded; - targetTypeWithAnnotations = TypeWithAnnotations.Create(ForEachLoopBinder.GetIEnumerableOfT(resultType, isAsync, compilation, ref discardedUseSiteInfo, out bool foundMultiple)); + targetTypeWithAnnotations = TypeWithAnnotations.Create(ForEachLoopBinder.GetIEnumerableOfT(resultType, isAsync, compilation, ref discardedUseSiteInfo, out bool foundMultiple, needSupportForRefStructInterfaces: out _)); Debug.Assert(!foundMultiple); Debug.Assert(targetTypeWithAnnotations.HasType); } diff --git a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 index a5ce638524661..602ad728c80df 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 +++ b/src/Compilers/CSharp/Portable/Generated/CSharp.Generated.g4 @@ -208,12 +208,25 @@ type_parameter_constraint_clause ; type_parameter_constraint - : class_or_struct_constraint + : allows_constraint_clause + | class_or_struct_constraint | constructor_constraint | default_constraint | type_constraint ; +allows_constraint_clause + : 'allows' allows_constraint (',' allows_constraint)* + ; + +allows_constraint + : ref_struct_constraint + ; + +ref_struct_constraint + : 'ref' 'struct' + ; + class_or_struct_constraint : 'class' '?'? | 'struct' '?'? @@ -931,6 +944,18 @@ interpolation_format_clause : ':' interpolated_string_text_token ; +interpolated_multi_line_raw_string_start_token + : '$'+ '"""' '"'* + ; + +interpolated_raw_string_end_token + : '"""' '"'* /* must match number of quotes in raw_string_start_token */ + ; + +interpolated_single_line_raw_string_start_token + : '$'+ '"""' '"'* + ; + invocation_expression : expression argument_list ; @@ -940,19 +965,31 @@ is_pattern_expression ; literal_expression - : '__arglist' - | 'default' + : 'default' | 'false' | 'null' | 'true' + | '__arglist' | character_literal_token | multi_line_raw_string_literal_token | numeric_literal_token | single_line_raw_string_literal_token | string_literal_token - | utf_8_multi_line_raw_string_literal_token - | utf_8_single_line_raw_string_literal_token - | utf_8_string_literal_token + | utf8_multi_line_raw_string_literal_token + | utf8_single_line_raw_string_literal_token + | utf8_string_literal_token + ; + +utf8_multi_line_raw_string_literal_token + : multi_line_raw_string_literal_token ('U8' | 'u8') + ; + +utf8_single_line_raw_string_literal_token + : single_line_raw_string_literal_token ('U8' | 'u8') + ; + +utf8_string_literal_token + : string_literal_token ('U8' | 'u8') ; make_ref_expression @@ -1101,22 +1138,22 @@ with_expression ; xml_node - : xml_c_data_section - | xml_comment + : xml_comment + | xml_c_data_section | xml_element | xml_empty_element | xml_processing_instruction | xml_text ; -xml_c_data_section - : '' - ; - xml_comment : '' ; +xml_c_data_section + : '' + ; + xml_element : xml_element_start_tag xml_node* xml_element_end_tag ; @@ -1347,84 +1384,388 @@ skipped_tokens_trivia : syntax_token* ; -base_argument_list - : argument_list - | bracketed_argument_list +syntax_token + : character_literal_token + | identifier_token + | keyword + | numeric_literal_token + | operator_token + | punctuation_token + | string_literal_token ; -base_cref_parameter_list - : cref_bracketed_parameter_list - | cref_parameter_list +identifier_token + : '@'? identifier_start_character identifier_part_character ; -base_parameter_list - : bracketed_parameter_list - | parameter_list +identifier_start_character + : letter_character + | underscore_character ; -base_parameter - : function_pointer_parameter - | parameter +letter_character + : /* [\p{L}\p{Nl}] category letter, all subcategories; category number, subcategory letter */ + | unicode_escape_sequence /* only escapes for categories L & Nl allowed */ ; -character_literal_token - : /* see lexical specification */ +underscore_character + : '\\u005' /* unicode_escape_sequence for underscore */ + | '_' ; -expression_or_pattern - : expression - | pattern +identifier_part_character + : combining_character + | connecting_character + | decimal_digit_character + | formatting_character + | letter_character ; -identifier_token - : /* see lexical specification */ +combining_character + : /* [\p{Mn}\p{Mc}] category Mark, subcategories non-spacing and spacing combining */ + | unicode_escape_sequence /* only escapes for categories Mn & Mc allowed */ ; -interpolated_multi_line_raw_string_start_token - : /* see lexical specification */ +connecting_character + : /* [\p{Pc}] category Punctuation, subcategory connector */ + | unicode_escape_sequence /* only escapes for category Pc allowed */ ; -interpolated_raw_string_end_token - : /* see lexical specification */ +decimal_digit_character + : /* [\p{Nd}] category number, subcategory decimal digit */ + | unicode_escape_sequence /* only escapes for category Nd allowed */ ; -interpolated_single_line_raw_string_start_token - : /* see lexical specification */ +formatting_character + : /* [\p{Cf}] category Other, subcategory format. */ + | unicode_escape_sequence /* only escapes for category Cf allowed */ ; -interpolated_string_text_token - : /* see lexical specification */ +keyword + : 'as' + | 'base' + | 'bool' + | 'break' + | 'byte' + | 'case' + | 'catch' + | 'char' + | 'checked' + | 'class' + | 'continue' + | 'decimal' + | 'default' + | 'delegate' + | 'do' + | 'double' + | 'else' + | 'enum' + | 'event' + | 'explicit' + | 'false' + | 'finally' + | 'float' + | 'for' + | 'foreach' + | 'goto' + | 'if' + | 'implicit' + | 'in' + | 'int' + | 'interface' + | 'is' + | 'lock' + | 'long' + | 'namespace' + | 'null' + | 'object' + | 'operator' + | 'out' + | 'params' + | 'return' + | 'sbyte' + | 'short' + | 'sizeof' + | 'stackalloc' + | 'string' + | 'struct' + | 'switch' + | 'this' + | 'throw' + | 'true' + | 'try' + | 'typeof' + | 'uint' + | 'ulong' + | 'unchecked' + | 'ushort' + | 'using' + | 'void' + | 'while' + | '__arglist' + | '__makeref' + | '__reftype' + | '__refvalue' + | modifier ; -multi_line_raw_string_literal_token - : /* see lexical specification */ +numeric_literal_token + : integer_literal_token + | real_literal_token ; -numeric_literal_token - : /* see lexical specification */ +integer_literal_token + : decimal_integer_literal_token + | hexadecimal_integer_literal_token ; -single_line_raw_string_literal_token - : /* see lexical specification */ +decimal_integer_literal_token + : decimal_digit+ integer_type_suffix? + ; + +decimal_digit + : '0' + | '1' + | '2' + | '3' + | '4' + | '5' + | '6' + | '7' + | '8' + | '9' + ; + +integer_type_suffix + : 'L' + | 'l' + | 'LU' + | 'lU' + | 'Lu' + | 'lu' + | 'U' + | 'u' + | 'UL' + | 'uL' + | 'Ul' + | 'ul' + ; + +hexadecimal_integer_literal_token + : ('0x' | '0X') hexadecimal_digit+ integer_type_suffix? + ; + +hexadecimal_digit + : 'A' + | 'a' + | 'B' + | 'b' + | 'C' + | 'c' + | 'D' + | 'd' + | 'E' + | 'e' + | 'F' + | 'f' + | decimal_digit + ; + +real_literal_token + : '.' decimal_digit+ exponent_part? real_type_suffix? + | decimal_digit+ '.' decimal_digit+ exponent_part? real_type_suffix? + | decimal_digit+ exponent_part real_type_suffix? + | decimal_digit+ real_type_suffix + ; + +exponent_part + : ('E' | 'e') ('+' | '-')? decimal_digit+ + ; + +real_type_suffix + : 'D' + | 'd' + | 'F' + | 'f' + | 'M' + | 'm' + ; + +character_literal_token + : '\'' character '\'' + ; + +character + : hexadecimal_escape_sequence + | simple_escape_sequence + | single_character + | unicode_escape_sequence + ; + +hexadecimal_escape_sequence + : '\\x' hexadecimal_digit hexadecimal_digit? hexadecimal_digit? hexadecimal_digit? + ; + +simple_escape_sequence + : '\\"' + | '\\0' + | '\\a' + | '\\b' + | '\\f' + | '\\n' + | '\\r' + | '\\t' + | '\\v' + | '\\\'' + | '\\\\' + ; + +single_character + : /* ~['\\\u000D\u000A\u0085\u2028\u2029] anything but ', \\, and new_line_character */ + ; + +unicode_escape_sequence + : '\\u' hexadecimal_digit hexadecimal_digit hexadecimal_digit hexadecimal_digit + | '\\U' hexadecimal_digit hexadecimal_digit hexadecimal_digit hexadecimal_digit hexadecimal_digit hexadecimal_digit hexadecimal_digit hexadecimal_digit ; string_literal_token - : /* see lexical specification */ + : regular_string_literal_token + | verbatim_string_literal_token + ; + +regular_string_literal_token + : '"' regular_string_literal_character* '"' + ; + +regular_string_literal_character + : hexadecimal_escape_sequence + | simple_escape_sequence + | single_regular_string_literal_character + | unicode_escape_sequence + ; + +single_regular_string_literal_character + : /* ~["\\\u000D\u000A\u0085\u2028\u2029] anything but ", \, and new_line_character */ + ; + +verbatim_string_literal_token + : '@"' verbatim_string_literal_character* '"' + ; + +verbatim_string_literal_character + : quote_escape_sequence + | single_verbatim_string_literal_character + ; + +quote_escape_sequence + : '""' + ; + +single_verbatim_string_literal_character + : /* anything but quotation mark (U+0022) */ + ; + +operator_token + : '!' + | '!=' + | '%' + | '%=' + | '&&' + | '&' + | '&=' + | '*' + | '*=' + | '+' + | '++' + | '+=' + | '-' + | '--' + | '-=' + | '/' + | '/=' + | '<' + | '<<' + | '<<=' + | '<=' + | '=' + | '==' + | '>' + | '>=' + | '>>' + | '>>=' + | '>>>' + | '>>>=' + | '??' + | '??=' + | 'as' + | 'is' + | '^' + | '^=' + | '|' + | '|=' + | '||' + | '~' + ; + +punctuation_token + : '"' + | '#' + | '(' + | ')' + | ',' + | '->' + | '.' + | '..' + | '/>' + | ':' + | '::' + | ';' + | '' + | '?' + | '[' + | '\'' + | '\\' + | ']' + | '{' + | '}' ; -syntax_token - : /* see lexical specification */ +base_argument_list + : argument_list + | bracketed_argument_list + ; + +base_cref_parameter_list + : cref_bracketed_parameter_list + | cref_parameter_list ; -utf_8_multi_line_raw_string_literal_token +base_parameter_list + : bracketed_parameter_list + | parameter_list + ; + +base_parameter + : function_pointer_parameter + | parameter + ; + +expression_or_pattern + : expression + | pattern + ; + +interpolated_string_text_token : /* see lexical specification */ ; -utf_8_single_line_raw_string_literal_token +multi_line_raw_string_literal_token : /* see lexical specification */ ; -utf_8_string_literal_token +single_line_raw_string_literal_token : /* see lexical specification */ ; diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs index 9038906d3253c..ed09f4ccd3931 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Internal.Generated.cs @@ -18715,6 +18715,186 @@ internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) => new DefaultConstraintSyntax(this.Kind, this.defaultKeyword, GetDiagnostics(), annotations); } +/// The allows type parameter constraint clause. +internal sealed partial class AllowsConstraintClauseSyntax : TypeParameterConstraintSyntax +{ + internal readonly SyntaxToken allowsKeyword; + internal readonly GreenNode? constraints; + + internal AllowsConstraintClauseSyntax(SyntaxKind kind, SyntaxToken allowsKeyword, GreenNode? constraints, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + : base(kind, diagnostics, annotations) + { + this.SlotCount = 2; + this.AdjustFlagsAndWidth(allowsKeyword); + this.allowsKeyword = allowsKeyword; + if (constraints != null) + { + this.AdjustFlagsAndWidth(constraints); + this.constraints = constraints; + } + } + + internal AllowsConstraintClauseSyntax(SyntaxKind kind, SyntaxToken allowsKeyword, GreenNode? constraints, SyntaxFactoryContext context) + : base(kind) + { + this.SetFactoryContext(context); + this.SlotCount = 2; + this.AdjustFlagsAndWidth(allowsKeyword); + this.allowsKeyword = allowsKeyword; + if (constraints != null) + { + this.AdjustFlagsAndWidth(constraints); + this.constraints = constraints; + } + } + + internal AllowsConstraintClauseSyntax(SyntaxKind kind, SyntaxToken allowsKeyword, GreenNode? constraints) + : base(kind) + { + this.SlotCount = 2; + this.AdjustFlagsAndWidth(allowsKeyword); + this.allowsKeyword = allowsKeyword; + if (constraints != null) + { + this.AdjustFlagsAndWidth(constraints); + this.constraints = constraints; + } + } + + public SyntaxToken AllowsKeyword => this.allowsKeyword; + /// Gets the constraints list. + public CoreSyntax.SeparatedSyntaxList Constraints => new CoreSyntax.SeparatedSyntaxList(new CoreSyntax.SyntaxList(this.constraints)); + + internal override GreenNode? GetSlot(int index) + => index switch + { + 0 => this.allowsKeyword, + 1 => this.constraints, + _ => null, + }; + + internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.AllowsConstraintClauseSyntax(this, parent, position); + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitAllowsConstraintClause(this); + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitAllowsConstraintClause(this); + + public AllowsConstraintClauseSyntax Update(SyntaxToken allowsKeyword, CoreSyntax.SeparatedSyntaxList constraints) + { + if (allowsKeyword != this.AllowsKeyword || constraints != this.Constraints) + { + var newNode = SyntaxFactory.AllowsConstraintClause(allowsKeyword, constraints); + var diags = GetDiagnostics(); + if (diags?.Length > 0) + newNode = newNode.WithDiagnosticsGreen(diags); + var annotations = GetAnnotations(); + if (annotations?.Length > 0) + newNode = newNode.WithAnnotationsGreen(annotations); + return newNode; + } + + return this; + } + + internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics) + => new AllowsConstraintClauseSyntax(this.Kind, this.allowsKeyword, this.constraints, diagnostics, GetAnnotations()); + + internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) + => new AllowsConstraintClauseSyntax(this.Kind, this.allowsKeyword, this.constraints, GetDiagnostics(), annotations); +} + +/// Base type for allow constraint syntax. +internal abstract partial class AllowsConstraintSyntax : CSharpSyntaxNode +{ + internal AllowsConstraintSyntax(SyntaxKind kind, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + : base(kind, diagnostics, annotations) + { + } + + internal AllowsConstraintSyntax(SyntaxKind kind) + : base(kind) + { + } +} + +/// Ref struct constraint syntax. +internal sealed partial class RefStructConstraintSyntax : AllowsConstraintSyntax +{ + internal readonly SyntaxToken refKeyword; + internal readonly SyntaxToken structKeyword; + + internal RefStructConstraintSyntax(SyntaxKind kind, SyntaxToken refKeyword, SyntaxToken structKeyword, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) + : base(kind, diagnostics, annotations) + { + this.SlotCount = 2; + this.AdjustFlagsAndWidth(refKeyword); + this.refKeyword = refKeyword; + this.AdjustFlagsAndWidth(structKeyword); + this.structKeyword = structKeyword; + } + + internal RefStructConstraintSyntax(SyntaxKind kind, SyntaxToken refKeyword, SyntaxToken structKeyword, SyntaxFactoryContext context) + : base(kind) + { + this.SetFactoryContext(context); + this.SlotCount = 2; + this.AdjustFlagsAndWidth(refKeyword); + this.refKeyword = refKeyword; + this.AdjustFlagsAndWidth(structKeyword); + this.structKeyword = structKeyword; + } + + internal RefStructConstraintSyntax(SyntaxKind kind, SyntaxToken refKeyword, SyntaxToken structKeyword) + : base(kind) + { + this.SlotCount = 2; + this.AdjustFlagsAndWidth(refKeyword); + this.refKeyword = refKeyword; + this.AdjustFlagsAndWidth(structKeyword); + this.structKeyword = structKeyword; + } + + /// Gets the "ref" keyword. + public SyntaxToken RefKeyword => this.refKeyword; + /// Gets the "struct" keyword. + public SyntaxToken StructKeyword => this.structKeyword; + + internal override GreenNode? GetSlot(int index) + => index switch + { + 0 => this.refKeyword, + 1 => this.structKeyword, + _ => null, + }; + + internal override SyntaxNode CreateRed(SyntaxNode? parent, int position) => new CSharp.Syntax.RefStructConstraintSyntax(this, parent, position); + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitRefStructConstraint(this); + public override TResult Accept(CSharpSyntaxVisitor visitor) => visitor.VisitRefStructConstraint(this); + + public RefStructConstraintSyntax Update(SyntaxToken refKeyword, SyntaxToken structKeyword) + { + if (refKeyword != this.RefKeyword || structKeyword != this.StructKeyword) + { + var newNode = SyntaxFactory.RefStructConstraint(refKeyword, structKeyword); + var diags = GetDiagnostics(); + if (diags?.Length > 0) + newNode = newNode.WithDiagnosticsGreen(diags); + var annotations = GetAnnotations(); + if (annotations?.Length > 0) + newNode = newNode.WithAnnotationsGreen(annotations); + return newNode; + } + + return this; + } + + internal override GreenNode SetDiagnostics(DiagnosticInfo[]? diagnostics) + => new RefStructConstraintSyntax(this.Kind, this.refKeyword, this.structKeyword, diagnostics, GetAnnotations()); + + internal override GreenNode SetAnnotations(SyntaxAnnotation[]? annotations) + => new RefStructConstraintSyntax(this.Kind, this.refKeyword, this.structKeyword, GetDiagnostics(), annotations); +} + internal abstract partial class BaseFieldDeclarationSyntax : MemberDeclarationSyntax { internal BaseFieldDeclarationSyntax(SyntaxKind kind, DiagnosticInfo[]? diagnostics, SyntaxAnnotation[]? annotations) @@ -26416,6 +26596,8 @@ internal partial class CSharpSyntaxVisitor public virtual TResult VisitClassOrStructConstraint(ClassOrStructConstraintSyntax node) => this.DefaultVisit(node); public virtual TResult VisitTypeConstraint(TypeConstraintSyntax node) => this.DefaultVisit(node); public virtual TResult VisitDefaultConstraint(DefaultConstraintSyntax node) => this.DefaultVisit(node); + public virtual TResult VisitAllowsConstraintClause(AllowsConstraintClauseSyntax node) => this.DefaultVisit(node); + public virtual TResult VisitRefStructConstraint(RefStructConstraintSyntax node) => this.DefaultVisit(node); public virtual TResult VisitFieldDeclaration(FieldDeclarationSyntax node) => this.DefaultVisit(node); public virtual TResult VisitEventFieldDeclaration(EventFieldDeclarationSyntax node) => this.DefaultVisit(node); public virtual TResult VisitExplicitInterfaceSpecifier(ExplicitInterfaceSpecifierSyntax node) => this.DefaultVisit(node); @@ -26661,6 +26843,8 @@ internal partial class CSharpSyntaxVisitor public virtual void VisitClassOrStructConstraint(ClassOrStructConstraintSyntax node) => this.DefaultVisit(node); public virtual void VisitTypeConstraint(TypeConstraintSyntax node) => this.DefaultVisit(node); public virtual void VisitDefaultConstraint(DefaultConstraintSyntax node) => this.DefaultVisit(node); + public virtual void VisitAllowsConstraintClause(AllowsConstraintClauseSyntax node) => this.DefaultVisit(node); + public virtual void VisitRefStructConstraint(RefStructConstraintSyntax node) => this.DefaultVisit(node); public virtual void VisitFieldDeclaration(FieldDeclarationSyntax node) => this.DefaultVisit(node); public virtual void VisitEventFieldDeclaration(EventFieldDeclarationSyntax node) => this.DefaultVisit(node); public virtual void VisitExplicitInterfaceSpecifier(ExplicitInterfaceSpecifierSyntax node) => this.DefaultVisit(node); @@ -27260,6 +27444,12 @@ public override CSharpSyntaxNode VisitTypeConstraint(TypeConstraintSyntax node) public override CSharpSyntaxNode VisitDefaultConstraint(DefaultConstraintSyntax node) => node.Update((SyntaxToken)Visit(node.DefaultKeyword)); + public override CSharpSyntaxNode VisitAllowsConstraintClause(AllowsConstraintClauseSyntax node) + => node.Update((SyntaxToken)Visit(node.AllowsKeyword), VisitList(node.Constraints)); + + public override CSharpSyntaxNode VisitRefStructConstraint(RefStructConstraintSyntax node) + => node.Update((SyntaxToken)Visit(node.RefKeyword), (SyntaxToken)Visit(node.StructKeyword)); + public override CSharpSyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node) => node.Update(VisitList(node.AttributeLists), VisitList(node.Modifiers), (VariableDeclarationSyntax)Visit(node.Declaration), (SyntaxToken)Visit(node.SemicolonToken)); @@ -31311,6 +31501,48 @@ public DefaultConstraintSyntax DefaultConstraint(SyntaxToken defaultKeyword) return result; } + public AllowsConstraintClauseSyntax AllowsConstraintClause(SyntaxToken allowsKeyword, CoreSyntax.SeparatedSyntaxList constraints) + { +#if DEBUG + if (allowsKeyword == null) throw new ArgumentNullException(nameof(allowsKeyword)); + if (allowsKeyword.Kind != SyntaxKind.AllowsKeyword) throw new ArgumentException(nameof(allowsKeyword)); +#endif + + int hash; + var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.AllowsConstraintClause, allowsKeyword, constraints.Node, this.context, out hash); + if (cached != null) return (AllowsConstraintClauseSyntax)cached; + + var result = new AllowsConstraintClauseSyntax(SyntaxKind.AllowsConstraintClause, allowsKeyword, constraints.Node, this.context); + if (hash >= 0) + { + SyntaxNodeCache.AddNode(result, hash); + } + + return result; + } + + public RefStructConstraintSyntax RefStructConstraint(SyntaxToken refKeyword, SyntaxToken structKeyword) + { +#if DEBUG + if (refKeyword == null) throw new ArgumentNullException(nameof(refKeyword)); + if (refKeyword.Kind != SyntaxKind.RefKeyword) throw new ArgumentException(nameof(refKeyword)); + if (structKeyword == null) throw new ArgumentNullException(nameof(structKeyword)); + if (structKeyword.Kind != SyntaxKind.StructKeyword) throw new ArgumentException(nameof(structKeyword)); +#endif + + int hash; + var cached = CSharpSyntaxNodeCache.TryGetNode((int)SyntaxKind.RefStructConstraint, refKeyword, structKeyword, this.context, out hash); + if (cached != null) return (RefStructConstraintSyntax)cached; + + var result = new RefStructConstraintSyntax(SyntaxKind.RefStructConstraint, refKeyword, structKeyword, this.context); + if (hash >= 0) + { + SyntaxNodeCache.AddNode(result, hash); + } + + return result; + } + public FieldDeclarationSyntax FieldDeclaration(CoreSyntax.SyntaxList attributeLists, CoreSyntax.SyntaxList modifiers, VariableDeclarationSyntax declaration, SyntaxToken semicolonToken) { #if DEBUG @@ -36517,6 +36749,48 @@ public static DefaultConstraintSyntax DefaultConstraint(SyntaxToken defaultKeywo return result; } + public static AllowsConstraintClauseSyntax AllowsConstraintClause(SyntaxToken allowsKeyword, CoreSyntax.SeparatedSyntaxList constraints) + { +#if DEBUG + if (allowsKeyword == null) throw new ArgumentNullException(nameof(allowsKeyword)); + if (allowsKeyword.Kind != SyntaxKind.AllowsKeyword) throw new ArgumentException(nameof(allowsKeyword)); +#endif + + int hash; + var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.AllowsConstraintClause, allowsKeyword, constraints.Node, out hash); + if (cached != null) return (AllowsConstraintClauseSyntax)cached; + + var result = new AllowsConstraintClauseSyntax(SyntaxKind.AllowsConstraintClause, allowsKeyword, constraints.Node); + if (hash >= 0) + { + SyntaxNodeCache.AddNode(result, hash); + } + + return result; + } + + public static RefStructConstraintSyntax RefStructConstraint(SyntaxToken refKeyword, SyntaxToken structKeyword) + { +#if DEBUG + if (refKeyword == null) throw new ArgumentNullException(nameof(refKeyword)); + if (refKeyword.Kind != SyntaxKind.RefKeyword) throw new ArgumentException(nameof(refKeyword)); + if (structKeyword == null) throw new ArgumentNullException(nameof(structKeyword)); + if (structKeyword.Kind != SyntaxKind.StructKeyword) throw new ArgumentException(nameof(structKeyword)); +#endif + + int hash; + var cached = SyntaxNodeCache.TryGetNode((int)SyntaxKind.RefStructConstraint, refKeyword, structKeyword, out hash); + if (cached != null) return (RefStructConstraintSyntax)cached; + + var result = new RefStructConstraintSyntax(SyntaxKind.RefStructConstraint, refKeyword, structKeyword); + if (hash >= 0) + { + SyntaxNodeCache.AddNode(result, hash); + } + + return result; + } + public static FieldDeclarationSyntax FieldDeclaration(CoreSyntax.SyntaxList attributeLists, CoreSyntax.SyntaxList modifiers, VariableDeclarationSyntax declaration, SyntaxToken semicolonToken) { #if DEBUG diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs index 69db879f93ae3..fff130e4907ad 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Main.Generated.cs @@ -546,6 +546,12 @@ public partial class CSharpSyntaxVisitor /// Called when the visitor visits a DefaultConstraintSyntax node. public virtual TResult? VisitDefaultConstraint(DefaultConstraintSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a AllowsConstraintClauseSyntax node. + public virtual TResult? VisitAllowsConstraintClause(AllowsConstraintClauseSyntax node) => this.DefaultVisit(node); + + /// Called when the visitor visits a RefStructConstraintSyntax node. + public virtual TResult? VisitRefStructConstraint(RefStructConstraintSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a FieldDeclarationSyntax node. public virtual TResult? VisitFieldDeclaration(FieldDeclarationSyntax node) => this.DefaultVisit(node); @@ -1272,6 +1278,12 @@ public partial class CSharpSyntaxVisitor /// Called when the visitor visits a DefaultConstraintSyntax node. public virtual void VisitDefaultConstraint(DefaultConstraintSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a AllowsConstraintClauseSyntax node. + public virtual void VisitAllowsConstraintClause(AllowsConstraintClauseSyntax node) => this.DefaultVisit(node); + + /// Called when the visitor visits a RefStructConstraintSyntax node. + public virtual void VisitRefStructConstraint(RefStructConstraintSyntax node) => this.DefaultVisit(node); + /// Called when the visitor visits a FieldDeclarationSyntax node. public virtual void VisitFieldDeclaration(FieldDeclarationSyntax node) => this.DefaultVisit(node); @@ -1998,6 +2010,12 @@ public partial class CSharpSyntaxRewriter : CSharpSyntaxVisitor public override SyntaxNode? VisitDefaultConstraint(DefaultConstraintSyntax node) => node.Update(VisitToken(node.DefaultKeyword)); + public override SyntaxNode? VisitAllowsConstraintClause(AllowsConstraintClauseSyntax node) + => node.Update(VisitToken(node.AllowsKeyword), VisitList(node.Constraints)); + + public override SyntaxNode? VisitRefStructConstraint(RefStructConstraintSyntax node) + => node.Update(VisitToken(node.RefKeyword), VisitToken(node.StructKeyword)); + public override SyntaxNode? VisitFieldDeclaration(FieldDeclarationSyntax node) => node.Update(VisitList(node.AttributeLists), VisitList(node.Modifiers), (VariableDeclarationSyntax?)Visit(node.Declaration) ?? throw new ArgumentNullException("declaration"), VisitToken(node.SemicolonToken)); @@ -5226,6 +5244,29 @@ public static DefaultConstraintSyntax DefaultConstraint(SyntaxToken defaultKeywo public static DefaultConstraintSyntax DefaultConstraint() => SyntaxFactory.DefaultConstraint(SyntaxFactory.Token(SyntaxKind.DefaultKeyword)); + /// Creates a new AllowsConstraintClauseSyntax instance. + public static AllowsConstraintClauseSyntax AllowsConstraintClause(SyntaxToken allowsKeyword, SeparatedSyntaxList constraints) + { + if (allowsKeyword.Kind() != SyntaxKind.AllowsKeyword) throw new ArgumentException(nameof(allowsKeyword)); + return (AllowsConstraintClauseSyntax)Syntax.InternalSyntax.SyntaxFactory.AllowsConstraintClause((Syntax.InternalSyntax.SyntaxToken)allowsKeyword.Node!, constraints.Node.ToGreenSeparatedList()).CreateRed(); + } + + /// Creates a new AllowsConstraintClauseSyntax instance. + public static AllowsConstraintClauseSyntax AllowsConstraintClause(SeparatedSyntaxList constraints = default) + => SyntaxFactory.AllowsConstraintClause(SyntaxFactory.Token(SyntaxKind.AllowsKeyword), constraints); + + /// Creates a new RefStructConstraintSyntax instance. + public static RefStructConstraintSyntax RefStructConstraint(SyntaxToken refKeyword, SyntaxToken structKeyword) + { + if (refKeyword.Kind() != SyntaxKind.RefKeyword) throw new ArgumentException(nameof(refKeyword)); + if (structKeyword.Kind() != SyntaxKind.StructKeyword) throw new ArgumentException(nameof(structKeyword)); + return (RefStructConstraintSyntax)Syntax.InternalSyntax.SyntaxFactory.RefStructConstraint((Syntax.InternalSyntax.SyntaxToken)refKeyword.Node!, (Syntax.InternalSyntax.SyntaxToken)structKeyword.Node!).CreateRed(); + } + + /// Creates a new RefStructConstraintSyntax instance. + public static RefStructConstraintSyntax RefStructConstraint() + => SyntaxFactory.RefStructConstraint(SyntaxFactory.Token(SyntaxKind.RefKeyword), SyntaxFactory.Token(SyntaxKind.StructKeyword)); + /// Creates a new FieldDeclarationSyntax instance. public static FieldDeclarationSyntax FieldDeclaration(SyntaxList attributeLists, SyntaxTokenList modifiers, VariableDeclarationSyntax declaration, SyntaxToken semicolonToken) { diff --git a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs index ff8f7b840cb63..dadef45b3bf3d 100644 --- a/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/CSharpSyntaxGenerator/CSharpSyntaxGenerator.SourceGenerator/Syntax.xml.Syntax.Generated.cs @@ -11701,6 +11701,112 @@ public DefaultConstraintSyntax Update(SyntaxToken defaultKeyword) public DefaultConstraintSyntax WithDefaultKeyword(SyntaxToken defaultKeyword) => Update(defaultKeyword); } +/// The allows type parameter constraint clause. +/// +/// This node is associated with the following syntax kinds: +/// +/// +/// +/// +public sealed partial class AllowsConstraintClauseSyntax : TypeParameterConstraintSyntax +{ + private SyntaxNode? constraints; + + internal AllowsConstraintClauseSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) + : base(green, parent, position) + { + } + + public SyntaxToken AllowsKeyword => new SyntaxToken(this, ((InternalSyntax.AllowsConstraintClauseSyntax)this.Green).allowsKeyword, Position, 0); + + /// Gets the constraints list. + public SeparatedSyntaxList Constraints + { + get + { + var red = GetRed(ref this.constraints, 1); + return red != null ? new SeparatedSyntaxList(red, GetChildIndex(1)) : default; + } + } + + internal override SyntaxNode? GetNodeSlot(int index) => index == 1 ? GetRed(ref this.constraints, 1)! : null; + + internal override SyntaxNode? GetCachedSlot(int index) => index == 1 ? this.constraints : null; + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitAllowsConstraintClause(this); + public override TResult? Accept(CSharpSyntaxVisitor visitor) where TResult : default => visitor.VisitAllowsConstraintClause(this); + + public AllowsConstraintClauseSyntax Update(SyntaxToken allowsKeyword, SeparatedSyntaxList constraints) + { + if (allowsKeyword != this.AllowsKeyword || constraints != this.Constraints) + { + var newNode = SyntaxFactory.AllowsConstraintClause(allowsKeyword, constraints); + var annotations = GetAnnotations(); + return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode; + } + + return this; + } + + public AllowsConstraintClauseSyntax WithAllowsKeyword(SyntaxToken allowsKeyword) => Update(allowsKeyword, this.Constraints); + public AllowsConstraintClauseSyntax WithConstraints(SeparatedSyntaxList constraints) => Update(this.AllowsKeyword, constraints); + + public AllowsConstraintClauseSyntax AddConstraints(params AllowsConstraintSyntax[] items) => WithConstraints(this.Constraints.AddRange(items)); +} + +/// Base type for allow constraint syntax. +public abstract partial class AllowsConstraintSyntax : CSharpSyntaxNode +{ + internal AllowsConstraintSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) + : base(green, parent, position) + { + } +} + +/// Ref struct constraint syntax. +/// +/// This node is associated with the following syntax kinds: +/// +/// +/// +/// +public sealed partial class RefStructConstraintSyntax : AllowsConstraintSyntax +{ + + internal RefStructConstraintSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) + : base(green, parent, position) + { + } + + /// Gets the "ref" keyword. + public SyntaxToken RefKeyword => new SyntaxToken(this, ((InternalSyntax.RefStructConstraintSyntax)this.Green).refKeyword, Position, 0); + + /// Gets the "struct" keyword. + public SyntaxToken StructKeyword => new SyntaxToken(this, ((InternalSyntax.RefStructConstraintSyntax)this.Green).structKeyword, GetChildPosition(1), GetChildIndex(1)); + + internal override SyntaxNode? GetNodeSlot(int index) => null; + + internal override SyntaxNode? GetCachedSlot(int index) => null; + + public override void Accept(CSharpSyntaxVisitor visitor) => visitor.VisitRefStructConstraint(this); + public override TResult? Accept(CSharpSyntaxVisitor visitor) where TResult : default => visitor.VisitRefStructConstraint(this); + + public RefStructConstraintSyntax Update(SyntaxToken refKeyword, SyntaxToken structKeyword) + { + if (refKeyword != this.RefKeyword || structKeyword != this.StructKeyword) + { + var newNode = SyntaxFactory.RefStructConstraint(refKeyword, structKeyword); + var annotations = GetAnnotations(); + return annotations?.Length > 0 ? newNode.WithAnnotations(annotations) : newNode; + } + + return this; + } + + public RefStructConstraintSyntax WithRefKeyword(SyntaxToken refKeyword) => Update(refKeyword, this.StructKeyword); + public RefStructConstraintSyntax WithStructKeyword(SyntaxToken structKeyword) => Update(this.RefKeyword, structKeyword); +} + public abstract partial class BaseFieldDeclarationSyntax : MemberDeclarationSyntax { internal BaseFieldDeclarationSyntax(InternalSyntax.CSharpSyntaxNode green, SyntaxNode? parent, int position) diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs index 62d7b4c68bec6..ac6ebf95db21f 100644 --- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs @@ -341,6 +341,7 @@ public static bool IsWarning(ErrorCode code) case ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod: case ErrorCode.WRN_DynamicDispatchToParamsCollectionIndexer: case ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor: + case ErrorCode.WRN_BadYieldInLock: return true; default: return false; diff --git a/src/Compilers/CSharp/Portable/GlobalSuppressions.cs b/src/Compilers/CSharp/Portable/GlobalSuppressions.cs index cfeb8ccd4a8cc..3b2657e6fa0c9 100644 --- a/src/Compilers/CSharp/Portable/GlobalSuppressions.cs +++ b/src/Compilers/CSharp/Portable/GlobalSuppressions.cs @@ -44,3 +44,4 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.FunctionPointerUnmanagedCallingConventionList(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerUnmanagedCallingConventionSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerUnmanagedCallingConventionListSyntax")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.FunctionPointerParameterList(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerParameterSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.FunctionPointerParameterListSyntax")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:Public API with optional parameter(s) should have the most parameters amongst its public overloads.", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CollectionExpression(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.CollectionElementSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.CollectionExpressionSyntax")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("ApiDesign", "RS0027:API with optional parameter(s) should have the most parameters amongst its public overloads", Justification = "", Scope = "member", Target = "~M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.AllowsConstraintClause(Microsoft.CodeAnalysis.SeparatedSyntaxList{Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintSyntax})~Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax")] diff --git a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.Tree.cs b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.Tree.cs index 861a69e682754..f4413a571f973 100644 --- a/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.Tree.cs +++ b/src/Compilers/CSharp/Portable/Lowering/ClosureConversion/ClosureConversion.Analysis.Tree.cs @@ -697,6 +697,7 @@ private void AddDiagnosticIfRestrictedType(Symbol capturedVariable, SyntaxNode s if (type.IsRestrictedType() == true) { + Debug.Assert(false); // Add test(s) for scenarios that hit this code path _diagnostics.Add(ErrorCode.ERR_SpecialByRefInLambda, syntax.Location, type); } } diff --git a/src/Compilers/CSharp/Portable/Lowering/Instrumentation/LocalStateTracingInstrumenter.cs b/src/Compilers/CSharp/Portable/Lowering/Instrumentation/LocalStateTracingInstrumenter.cs index 352fb6eab69f3..021bccf5534bb 100644 --- a/src/Compilers/CSharp/Portable/Lowering/Instrumentation/LocalStateTracingInstrumenter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/Instrumentation/LocalStateTracingInstrumenter.cs @@ -111,7 +111,7 @@ public void Close(bool isMethodBody) if (isMethodBody) { - Debug.Assert(_lazyPreviousContextVariables?.IsEmpty() != false); + Debug.Assert(_lazyPreviousContextVariables?.IsEmpty != false); _lazyPreviousContextVariables?.Free(); _lazyPreviousContextVariables = null; } @@ -236,6 +236,8 @@ _ when !variableType.IsManagedTypeNoUseSiteDiagnostics => WellKnownMember.Microsoft_CodeAnalysis_Runtime_LocalStoreTracker__LogLocalStoreUnmanaged, _ when variableType.IsRefLikeType && !hasOverriddenToString(variableType) => null, // not possible to invoke ToString on ref struct that doesn't override it + _ when variableType is TypeParameterSymbol { AllowsRefLikeType: true } + => null, // not possible to invoke ToString on ref struct type parameter _ when variableType.TypeKind is TypeKind.Struct // we'll emit ToString constrained virtcall to avoid boxing the struct => WellKnownMember.Microsoft_CodeAnalysis_Runtime_LocalStoreTracker__LogLocalStoreString, diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_AssignmentOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_AssignmentOperator.cs index 9fcab11c2c2f6..75c23b3592248 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_AssignmentOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_AssignmentOperator.cs @@ -81,49 +81,7 @@ private BoundExpression VisitAssignmentOperator(BoundAssignmentOperator node, bo break; } - var result = MakeStaticAssignmentOperator(node.Syntax, loweredLeft, loweredRight, node.IsRef, used); - - result = ConvertResultOfAssignmentToDynamicIfNecessary(node, left, result, used); - - Debug.Assert(used || result.Type?.IsVoidType() == true || - (left switch { BoundIndexerAccess indexer => indexer.Indexer, BoundPropertyAccess property => property.PropertySymbol, _ => null }) is not PropertySymbol prop || - prop.GetOwnOrInheritedSetMethod() is null); - - Debug.Assert(result.Type?.IsVoidType() == true || TypeSymbol.Equals(result.Type, node.Type, TypeCompareKind.AllIgnoreOptions)); - - return result; - } - - private static bool ShouldConvertResultOfAssignmentToDynamic(TypeSymbol? assignmentResultType, BoundExpression target) - { - if (assignmentResultType?.IsDynamic() == true && target is BoundIndexerAccess { Type.TypeKind: not TypeKind.Dynamic } indexerAccess) - { - Debug.Assert(!indexerAccess.Indexer.Type.IsDynamic()); - Debug.Assert(!indexerAccess.Indexer.ReturnsByRef); - - return true; - } - - return false; - } - - internal static bool ShouldConvertResultOfAssignmentToDynamic(BoundExpression assignment, BoundExpression target) - { - Debug.Assert(assignment is BoundAssignmentOperator or BoundIncrementOperator or BoundCompoundAssignmentOperator or BoundNullCoalescingAssignmentOperator); - return ShouldConvertResultOfAssignmentToDynamic(assignment.Type, target); - } - - private BoundExpression ConvertResultOfAssignmentToDynamicIfNecessary(BoundExpression originalAssignment, BoundExpression originalTarget, BoundExpression result, bool used) - { - Debug.Assert(originalAssignment.Type is not null); - if (used && ShouldConvertResultOfAssignmentToDynamic(originalAssignment, originalTarget)) - { - Debug.Assert(result.Type is not null); - Debug.Assert(!result.Type.IsDynamic()); - result = _factory.Convert(originalAssignment.Type, result); - } - - return result; + return MakeStaticAssignmentOperator(node.Syntax, loweredLeft, loweredRight, node.IsRef, used); } /// diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs index 8a57e0daae122..46d37fdd2d589 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_BinaryOperator.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; @@ -998,7 +999,7 @@ private BoundExpression LowerLiftedBuiltInComparisonOperator( // Optimization: If one side is non-default constant, checking HasValue is not needed. if (kind.Operator() is BinaryOperatorKind.Equal or BinaryOperatorKind.NotEqual) { - if (xNonNull?.ConstantValueOpt is { IsDefaultValue: false }) + if (canNotBeEqualToDefaultValue(xNonNull?.ConstantValueOpt)) { Debug.Assert(yNonNull is null, "Handled by trivial optimization above; otherwise we should use yNonNull here."); return MakeBinaryOperator( @@ -1011,7 +1012,7 @@ private BoundExpression LowerLiftedBuiltInComparisonOperator( constrainedToTypeOpt: null); } - if (yNonNull?.ConstantValueOpt is { IsDefaultValue: false }) + if (canNotBeEqualToDefaultValue(yNonNull?.ConstantValueOpt)) { Debug.Assert(xNonNull is null, "Handled by trivial optimization above; otherwise we should use xNonNull here."); return MakeBinaryOperator( @@ -1098,6 +1099,27 @@ private BoundExpression LowerLiftedBuiltInComparisonOperator( sideEffects: ImmutableArray.Create(tempAssignmentX, tempAssignmentY), value: binaryExpression, type: boolType); + + static bool canNotBeEqualToDefaultValue( + [NotNullWhen(returnValue: true)] ConstantValue? constantValue) + { + // This is an explicit list so new constant values are not accidentally supported without consideration. + // Decimal is not in the list because it is possible to have a non-default decimal constant + // which is equal to the default decimal (0.0m == default(decimal)). + return constantValue is + { + IsDefaultValue: false, + Discriminator: ConstantValueTypeDiscriminator.Boolean + or ConstantValueTypeDiscriminator.Double + or ConstantValueTypeDiscriminator.Int32 + or ConstantValueTypeDiscriminator.Int64 + or ConstantValueTypeDiscriminator.NInt + or ConstantValueTypeDiscriminator.NUInt + or ConstantValueTypeDiscriminator.Single + or ConstantValueTypeDiscriminator.UInt32 + or ConstantValueTypeDiscriminator.UInt64 + }; + } } private BoundExpression LowerLiftedUserDefinedComparisonOperator( diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs index a63910f4e0572..bdddfdbab14ef 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Call.cs @@ -415,16 +415,6 @@ BoundExpression visitArgumentsAndFinishRewrite(BoundCall node, BoundExpression? rewrittenCall = Instrumenter.InstrumentCall(node, rewrittenCall); } - if (node.Type.IsDynamic() && !method.ReturnType.IsDynamic()) - { - Debug.Assert(node.Type.IsDynamic()); - Debug.Assert(!method.ReturnsByRef); - Debug.Assert(rewrittenCall.Type is not null); - Debug.Assert(!rewrittenCall.Type.IsDynamic()); - Debug.Assert(!rewrittenCall.Type.IsVoidType()); - rewrittenCall = _factory.Convert(node.Type, rewrittenCall); - } - return rewrittenCall; } } diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs index ef6e145345c23..6cbecefe3f188 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_CollectionExpression.cs @@ -195,8 +195,7 @@ private BoundExpression VisitArrayOrSpanCollectionExpression(BoundCollectionExpr syntax, elementType, elements, - asReadOnlySpan: collectionTypeKind == CollectionExpressionTypeKind.ReadOnlySpan, - _additionalLocals); + asReadOnlySpan: collectionTypeKind == CollectionExpressionTypeKind.ReadOnlySpan); } Debug.Assert(IsAllocatingRefStructCollectionExpression(node, collectionTypeKind, elementType.Type, _compilation)); @@ -243,7 +242,7 @@ private BoundExpression VisitCollectionInitializerCollectionExpression(BoundColl // Create a temp for the collection. BoundAssignmentOperator assignmentToTemp; - BoundLocal temp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true); + BoundLocal temp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp); var sideEffects = ArrayBuilder.GetInstance(elements.Length + 1); sideEffects.Add(assignmentToTemp); @@ -429,16 +428,33 @@ private BoundExpression CreateAndPopulateSpanFromInlineArray( SyntaxNode syntax, TypeWithAnnotations elementType, ImmutableArray elements, - bool asReadOnlySpan, - ArrayBuilder locals) + bool asReadOnlySpan) { Debug.Assert(elements.Length > 0); Debug.Assert(elements.All(e => e is BoundExpression)); Debug.Assert(_factory.ModuleBuilderOpt is { }); Debug.Assert(_diagnostics.DiagnosticBag is { }); Debug.Assert(_compilation.Assembly.RuntimeSupportsInlineArrayTypes); + Debug.Assert(_additionalLocals is { }); int arrayLength = elements.Length; + if (arrayLength == 1 + && _factory.WellKnownMember(asReadOnlySpan + ? WellKnownMember.System_ReadOnlySpan_T__ctor_ref_readonly_T + : WellKnownMember.System_Span_T__ctor_ref_T, isOptional: true) is MethodSymbol spanRefConstructor) + { + // Special case: no need to create an InlineArray1 type. Just use a temp of the element type. + var spanType = _factory + .WellKnownType(asReadOnlySpan ? WellKnownType.System_ReadOnlySpan_T : WellKnownType.System_Span_T) + .Construct([elementType]); + var constructor = spanRefConstructor.AsMember(spanType); + var element = VisitExpression((BoundExpression)elements[0]); + var temp = _factory.StoreToTemp(element, out var assignment); + _additionalLocals.Add(temp.LocalSymbol); + var call = _factory.New(constructor, arguments: [temp], argumentRefKinds: [asReadOnlySpan ? RefKindExtensions.StrictIn : RefKind.Ref]); + return _factory.Sequence([assignment], call); + } + var inlineArrayType = _factory.ModuleBuilderOpt.EnsureInlineArrayTypeExists(syntax, _factory, arrayLength, _diagnostics.DiagnosticBag).Construct(ImmutableArray.Create(elementType)); Debug.Assert(inlineArrayType.HasInlineArrayAttribute(out int inlineArrayLength) && inlineArrayLength == arrayLength); @@ -449,10 +465,10 @@ private BoundExpression CreateAndPopulateSpanFromInlineArray( // Create an inline array and assign to a local. // var tmp = new <>y__InlineArrayN(); BoundAssignmentOperator assignmentToTemp; - BoundLocal inlineArrayLocal = _factory.StoreToTemp(new BoundDefaultExpression(syntax, inlineArrayType), out assignmentToTemp, isKnownToReferToTempIfReferenceType: true); + BoundLocal inlineArrayLocal = _factory.StoreToTemp(new BoundDefaultExpression(syntax, inlineArrayType), out assignmentToTemp); var sideEffects = ArrayBuilder.GetInstance(); sideEffects.Add(assignmentToTemp); - locals.Add(inlineArrayLocal.LocalSymbol); + _additionalLocals.Add(inlineArrayLocal.LocalSymbol); // Populate the inline array. // InlineArrayElementRef<<>y__InlineArrayN, ElementType>(ref tmp, 0) = element0; @@ -604,8 +620,7 @@ bool tryGetToArrayMethod(TypeSymbol spreadTypeOriginalDefinition, WellKnownType // int index = 0; BoundLocal indexTemp = _factory.StoreToTemp( _factory.Literal(0), - out assignmentToTemp, - isKnownToReferToTempIfReferenceType: true); + out assignmentToTemp); localsBuilder.Add(indexTemp); sideEffects.Add(assignmentToTemp); @@ -615,8 +630,7 @@ bool tryGetToArrayMethod(TypeSymbol spreadTypeOriginalDefinition, WellKnownType ImmutableArray.Create(GetKnownLengthExpression(elements, numberIncludingLastSpread, localsBuilder)), initializerOpt: null, arrayType), - out assignmentToTemp, - isKnownToReferToTempIfReferenceType: true); + out assignmentToTemp); localsBuilder.Add(arrayTemp); sideEffects.Add(assignmentToTemp); @@ -903,7 +917,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty // If we use optimizations, we know the length of the resulting list, and we store it in a temp so we can pass it to List.ctor(int32) and to CollectionsMarshal.SetCount // int knownLengthTemp = N + s1.Length + ...; - knownLengthTemp = _factory.StoreToTemp(knownLengthExpression, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true); + knownLengthTemp = _factory.StoreToTemp(knownLengthExpression, out assignmentToTemp); localsBuilder.Add(knownLengthTemp); sideEffects.Add(assignmentToTemp); @@ -924,7 +938,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty } // Create a temp for the list. - BoundLocal listTemp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp, isKnownToReferToTempIfReferenceType: true); + BoundLocal listTemp = _factory.StoreToTemp(rewrittenReceiver, out assignmentToTemp); localsBuilder.Add(listTemp); sideEffects.Add(assignmentToTemp); @@ -940,7 +954,7 @@ private BoundExpression CreateAndPopulateList(BoundCollectionExpression node, Ty sideEffects.Add(_factory.Call(receiver: null, setCount, listTemp, knownLengthTemp)); // var span = CollectionsMarshal.AsSpan @@ -34,12 +34,13 @@ internal sealed partial class LocalRewriter /// - the conversion phase /// - the assignment phase /// - private BoundExpression? RewriteDeconstruction(BoundTupleExpression left, Conversion conversion, BoundExpression right, bool isUsed, NamedTypeSymbol assignmentResultTupleType) + private BoundExpression? RewriteDeconstruction(BoundTupleExpression left, Conversion conversion, BoundExpression right, bool isUsed) { var lhsTemps = ArrayBuilder.GetInstance(); var lhsEffects = ArrayBuilder.GetInstance(); ArrayBuilder lhsTargets = GetAssignmentTargetsAndSideEffects(left, lhsTemps, lhsEffects); - BoundExpression? result = RewriteDeconstruction(lhsTargets, conversion, right, assignmentResultTupleType, isUsed); + Debug.Assert(left.Type is { }); + BoundExpression? result = RewriteDeconstruction(lhsTargets, conversion, left.Type, right, isUsed); Binder.DeconstructionVariable.FreeDeconstructionVariables(lhsTargets); if (result is null) { @@ -54,8 +55,8 @@ internal sealed partial class LocalRewriter private BoundExpression? RewriteDeconstruction( ArrayBuilder lhsTargets, Conversion conversion, + TypeSymbol leftType, BoundExpression right, - NamedTypeSymbol assignmentResultTupleType, bool isUsed) { if (right.Kind == BoundKind.ConditionalOperator) @@ -65,17 +66,17 @@ internal sealed partial class LocalRewriter return conditional.Update( conditional.IsRef, VisitExpression(conditional.Condition), - RewriteDeconstruction(lhsTargets, conversion, conditional.Consequence, assignmentResultTupleType, isUsed: true)!, - RewriteDeconstruction(lhsTargets, conversion, conditional.Alternative, assignmentResultTupleType, isUsed: true)!, + RewriteDeconstruction(lhsTargets, conversion, leftType, conditional.Consequence, isUsed: true)!, + RewriteDeconstruction(lhsTargets, conversion, leftType, conditional.Alternative, isUsed: true)!, conditional.ConstantValueOpt, - assignmentResultTupleType, + leftType, wasTargetTyped: true, - assignmentResultTupleType); + leftType); } var temps = ArrayBuilder.GetInstance(); var effects = DeconstructionSideEffects.GetInstance(); - BoundExpression? returnValue = ApplyDeconstructionConversion(lhsTargets, right, conversion, temps, effects, assignmentResultTupleType, isUsed, inInit: true); + BoundExpression? returnValue = ApplyDeconstructionConversion(lhsTargets, right, conversion, temps, effects, isUsed, inInit: true); reverseAssignmentsToTargetsIfApplicable(); effects.Consolidate(); @@ -212,7 +213,6 @@ static bool canReorderTargetAssignments(ArrayBuilder temps, DeconstructionSideEffects effects, - NamedTypeSymbol assignmentResultTupleType, bool isUsed, bool inInit) { @@ -227,19 +227,14 @@ static bool canReorderTargetAssignments(ArrayBuilder useSiteInfo = GetNewCompoundUseSiteInfo(); - isImplicit = conversions.ClassifyImplicitConversionFromType(enumeratorType, idisposableTypeSymbol, ref useSiteInfo).IsImplicit; + implementsInterface = conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(enumeratorType, idisposableTypeSymbol, ref useSiteInfo, out _); _diagnostics.Add(forEachSyntax, useSiteInfo); } @@ -348,7 +348,7 @@ private bool TryGetDisposeMethod(SyntaxNode forEachSyntax, ForEachEnumeratorInfo containingType: _factory.CurrentType, location: enumeratorInfo.Location); - if (isImplicit || !(enumeratorInfo.PatternDisposeInfo is null)) + if (implementsInterface || !(enumeratorInfo.PatternDisposeInfo is null)) { Conversion receiverConversion = enumeratorType.IsStructType() ? Conversion.Boxing : @@ -402,7 +402,7 @@ private bool TryGetDisposeMethod(SyntaxNode forEachSyntax, ForEachEnumeratorInfo var objectType = _factory.SpecialType(SpecialType.System_Object); alwaysOrMaybeDisposeStmt = RewriteIfStatement( syntax: forEachSyntax, - rewrittenCondition: _factory.ObjectNotEqual(_factory.Convert(objectType, boundEnumeratorVar), _factory.Null(objectType)), + rewrittenCondition: _factory.IsNotNullReference(boundEnumeratorVar), rewrittenConsequence: disposeCallStatement, rewrittenAlternativeOpt: null, hasErrors: false); diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IndexerAccess.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IndexerAccess.cs index d69554e9b960d..202ce78595e4c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IndexerAccess.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IndexerAccess.cs @@ -105,22 +105,19 @@ private BoundExpression MakeIndexerAccess( bool expanded, ImmutableArray argsToParamsOpt, BitVector defaultArguments, - BoundExpression originalIndexerAccessOrObjectInitializerMember, + BoundIndexerAccess? oldNodeOpt, bool isLeftOfAssignment) { - Debug.Assert(originalIndexerAccessOrObjectInitializerMember is BoundIndexerAccess or BoundObjectInitializerMember); - Debug.Assert(originalIndexerAccessOrObjectInitializerMember.Type is not null); - if (isLeftOfAssignment && indexer.RefKind == RefKind.None) { TypeSymbol type = indexer.Type; - Debug.Assert(originalIndexerAccessOrObjectInitializerMember.Type.Equals(type, TypeCompareKind.ConsiderEverything)); + Debug.Assert(oldNodeOpt?.Type.Equals(type, TypeCompareKind.ConsiderEverything) != false); // This is an indexer set access. We return a BoundIndexerAccess node here. // This node will be rewritten with MakePropertyAssignment when rewriting the enclosing BoundAssignmentOperator. - return originalIndexerAccessOrObjectInitializerMember is BoundIndexerAccess indexerAccess ? - indexerAccess.Update(rewrittenReceiver, initialBindingReceiverIsSubjectToCloning: ThreeState.Unknown, indexer, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, defaultArguments, type) : + return oldNodeOpt != null ? + oldNodeOpt.Update(rewrittenReceiver, initialBindingReceiverIsSubjectToCloning: ThreeState.Unknown, indexer, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, defaultArguments, type) : new BoundIndexerAccess(syntax, rewrittenReceiver, initialBindingReceiverIsSubjectToCloning: ThreeState.Unknown, indexer, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, defaultArguments, type); } else @@ -149,14 +146,6 @@ private BoundExpression MakeIndexerAccess( BoundExpression call = MakePropertyGetAccess(syntax, rewrittenReceiver, indexer, rewrittenArguments, argumentRefKindsOpt, getMethod); - if (originalIndexerAccessOrObjectInitializerMember.Type.IsDynamic() == true && !indexer.Type.IsDynamic()) - { - Debug.Assert(call.Type is not null); - Debug.Assert(!call.Type.IsDynamic()); - Debug.Assert(!getMethod.ReturnsByRef); - call = _factory.Convert(originalIndexerAccessOrObjectInitializerMember.Type, call); - } - Debug.Assert(call.Type is not null); if (temps.Count == 0) diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_NullCoalescingAssignmentOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_NullCoalescingAssignmentOperator.cs index 6b3b62aa0bc01..5fa4abcac8f85 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_NullCoalescingAssignmentOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_NullCoalescingAssignmentOperator.cs @@ -25,12 +25,10 @@ public override BoundNode VisitNullCoalescingAssignmentOperator(BoundNullCoalesc var lhsRead = MakeRValue(transformedLHS); BoundExpression loweredRight = VisitExpression(node.RightOperand); - var result = node.IsNullableValueTypeAssignment ? + return node.IsNullableValueTypeAssignment ? rewriteNullCoalescingAssignmentForValueType() : rewriteNullCoalscingAssignmentStandard(); - return ConvertResultOfAssignmentToDynamicIfNecessary(node, node.LeftOperand, result, used: true); - BoundExpression rewriteNullCoalscingAssignmentStandard() { // Now that LHS is transformed with temporaries, we rewrite this node into a coalesce expression: diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreationExpression.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreationExpression.cs index dd6498eef7b0d..aff831efb5f7f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreationExpression.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreationExpression.cs @@ -340,6 +340,8 @@ private BoundExpression MakeNewT(SyntaxNode syntax, TypeParameterSymbol typePara Debug.Assert((object)method != null); method = method.Construct(ImmutableArray.Create(typeParameter)); + method.CheckConstraints(new ConstraintsHelper.CheckConstraintsArgs(_compilation, _compilation.Conversions, syntax.GetLocation(), _diagnostics)); + var createInstanceCall = new BoundCall( syntax, receiverOpt: null, diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs index 8583c6cf6329a..fca9eecc90167 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectOrCollectionInitializerExpression.cs @@ -663,7 +663,8 @@ private BoundExpression MakeObjectInitializerMemberAccess( #if DEBUG var discardedUseSiteInfo = CompoundUseSiteInfo.Discarded; - Debug.Assert(_compilation.Conversions.ClassifyConversionFromType(rewrittenReceiver.Type, memberSymbol.ContainingType, isChecked: false, ref discardedUseSiteInfo).IsImplicit); + Debug.Assert(_compilation.Conversions.ClassifyConversionFromType(rewrittenReceiver.Type, memberSymbol.ContainingType, isChecked: false, ref discardedUseSiteInfo).IsImplicit || + _compilation.Conversions.HasImplicitConversionToOrImplementsVarianceCompatibleInterface(rewrittenReceiver.Type, memberSymbol.ContainingType, ref discardedUseSiteInfo, out _)); // It is possible there are use site diagnostics from the above, but none that we need report as we aren't generating code for the conversion #endif @@ -688,7 +689,7 @@ private BoundExpression MakeObjectInitializerMemberAccess( rewrittenLeft.Expanded, rewrittenLeft.ArgsToParamsOpt, rewrittenLeft.DefaultArguments, - originalIndexerAccessOrObjectInitializerMember: rewrittenLeft, + oldNodeOpt: null, isLeftOfAssignment: !isRhsNestedInitializer); } else diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UnaryOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UnaryOperator.cs index 00d6f2d7854b0..5ebaf25a2cc57 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UnaryOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UnaryOperator.cs @@ -438,8 +438,7 @@ public override BoundNode VisitIncrementOperator(BoundIncrementOperator node) BoundExpression transformedLHS = TransformCompoundAssignmentLHS(node.Operand, isRegularCompoundAssignment: true, tempInitializers, tempSymbols, isDynamic); TypeSymbol? operandType = transformedLHS.Type; //type of the variable being incremented Debug.Assert(operandType is { }); - Debug.Assert(TypeSymbol.Equals(operandType, node.Type, TypeCompareKind.ConsiderEverything2) || - ShouldConvertResultOfAssignmentToDynamic(node, node.Operand)); + Debug.Assert(TypeSymbol.Equals(operandType, node.Type, TypeCompareKind.ConsiderEverything2)); LocalSymbol tempSymbol = _factory.SynthesizedLocal(operandType); tempSymbols.Add(tempSymbol); @@ -473,22 +472,15 @@ public override BoundNode VisitIncrementOperator(BoundIncrementOperator node) // In a case of the non-byref operand we use a single-sequence strategy as it results in shorter // overall life time of temps and as such more appropriate. (problem of crossed reads does not affect that case) // - BoundExpression result; - if (isIndirectOrInstanceField(transformedLHS)) { - result = rewriteWithRefOperand(isPrefix, isChecked, tempSymbols, tempInitializers, syntax, transformedLHS, boundTemp, newValue); + return rewriteWithRefOperand(isPrefix, isChecked, tempSymbols, tempInitializers, syntax, transformedLHS, boundTemp, newValue); } else { - result = rewriteWithNotRefOperand(isPrefix, isChecked, tempSymbols, tempInitializers, syntax, transformedLHS, boundTemp, newValue); + return rewriteWithNotRefOperand(isPrefix, isChecked, tempSymbols, tempInitializers, syntax, transformedLHS, boundTemp, newValue); } - result = ConvertResultOfAssignmentToDynamicIfNecessary(node, node.Operand, result, used: true); - Debug.Assert(TypeSymbol.Equals(result.Type, node.Type, TypeCompareKind.AllIgnoreOptions)); - - return result; - static bool isIndirectOrInstanceField(BoundExpression expression) { switch (expression.Kind) diff --git a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs index 5f5eae68a4cf5..84cfae1c3b2c0 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs @@ -334,7 +334,7 @@ private BoundExpression Spill( continue; case BoundKind.Sequence: - if (refKind != RefKind.None || expression.Type?.IsRefLikeType == true) + if (refKind != RefKind.None || expression.Type?.IsRefLikeOrAllowsRefLikeType() == true) { var sequence = (BoundSequence)expression; @@ -1264,9 +1264,7 @@ public override BoundNode VisitLoweredConditionalAccess(BoundLoweredConditionalA if (hasValueOpt == null) { - condition = _F.ObjectNotEqual( - _F.Convert(_F.SpecialType(SpecialType.System_Object), receiver), - _F.Null(_F.SpecialType(SpecialType.System_Object))); + condition = _F.IsNotNullReference(receiver); } else { @@ -1282,18 +1280,14 @@ public override BoundNode VisitLoweredConditionalAccess(BoundLoweredConditionalA receiverBuilder.AddLocal(clone); // (object)default(T) != null - var isNotClass = _F.ObjectNotEqual( - _F.Convert(_F.SpecialType(SpecialType.System_Object), _F.Default(receiver.Type)), - _F.Null(_F.SpecialType(SpecialType.System_Object))); + var isNotClass = _F.IsNotNullReference(_F.Default(receiver.Type)); // isNotCalss || {clone = receiver; (object)clone != null} condition = _F.LogicalOr( isNotClass, _F.MakeSequence( _F.AssignmentExpression(_F.Local(clone), receiver), - _F.ObjectNotEqual( - _F.Convert(_F.SpecialType(SpecialType.System_Object), _F.Local(clone)), - _F.Null(_F.SpecialType(SpecialType.System_Object)))) + _F.IsNotNullReference(_F.Local(clone))) ); receiver = _F.ComplexConditionalReceiver(receiver, _F.Local(clone)); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs index 91d75e4f81586..d8ce97fa4088f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/IteratorAndAsyncCaptureWalker.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp /// /// /// Data flow analysis is used to calculate the locals. At yield/await we mark all variables as "unassigned". - /// When a read from an unassigned variables is reported we add the variable to the captured set. + /// When a read from an unassigned variable is reported we add the variable to the captured set. /// "this" parameter is captured if a reference to "this", "base" or an instance field is encountered. /// Variables used in finally also need to be captured if there is a yield in the corresponding try block. /// @@ -76,19 +76,33 @@ public static OrderedSet Analyze(CSharpCompilation compilation, MethodSy foreach (var kvp in lazyDisallowedCaptures) { var variable = kvp.Key; - var type = (variable.Kind == SymbolKind.Local) ? ((LocalSymbol)variable).Type : ((ParameterSymbol)variable).Type; - if (variable is SynthesizedLocal local && local.SynthesizedKind == SynthesizedLocalKind.Spill) + if (variable is LocalSymbol local) { - Debug.Assert(local.TypeWithAnnotations.IsRestrictedType()); - diagnostics.Add(ErrorCode.ERR_ByRefTypeAndAwait, local.GetFirstLocation(), local.TypeWithAnnotations); + foreach (var syntax in kvp.Value) + { + if (local.TypeWithAnnotations.IsRestrictedType()) + { + // CS4007: Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + diagnostics.Add(ErrorCode.ERR_ByRefTypeAndAwait, syntax.Location, local.TypeWithAnnotations); + } + else + { + Debug.Assert(local.RefKind != RefKind.None); + // CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + diagnostics.Add(ErrorCode.ERR_RefLocalAcrossAwait, syntax.Location); + } + } } else { - foreach (CSharpSyntaxNode syntax in kvp.Value) + var parameter = (ParameterSymbol)variable; + Debug.Assert(parameter.TypeWithAnnotations.IsRestrictedType()); + + foreach (var syntax in kvp.Value) { - // CS4013: Instance of type '{0}' cannot be used inside an anonymous function, query expression, iterator block or async method - diagnostics.Add(ErrorCode.ERR_SpecialByRefInLambda, syntax.Location, type); + // CS4007: Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + diagnostics.Add(ErrorCode.ERR_ByRefTypeAndAwait, syntax.Location, parameter.TypeWithAnnotations); } } } @@ -195,14 +209,23 @@ protected override ImmutableArray Scan(ref bool badRegion) private void CaptureVariable(Symbol variable, SyntaxNode syntax) { var type = (variable.Kind == SymbolKind.Local) ? ((LocalSymbol)variable).Type : ((ParameterSymbol)variable).Type; - if (type.IsRestrictedType()) + if (type.IsRestrictedType() || + (variable is LocalSymbol { RefKind: not RefKind.None } refLocal && !canRefLocalBeHoisted(refLocal))) { (_lazyDisallowedCaptures ??= new MultiDictionary()).Add(variable, syntax); } else { if (_variablesToHoist.Add(variable) && variable is LocalSymbol local && _boundRefLocalInitializers.TryGetValue(local, out var variableInitializer)) - CaptureRefInitializer(variableInitializer, syntax); + CaptureRefInitializer(variableInitializer, local.SynthesizedKind != SynthesizedLocalKind.UserDefined ? variableInitializer.Syntax : syntax); + } + + static bool canRefLocalBeHoisted(LocalSymbol refLocal) + { + return refLocal.SynthesizedKind == SynthesizedLocalKind.Spill || + (refLocal.SynthesizedKind == SynthesizedLocalKind.ForEachArray && + refLocal.Type.HasInlineArrayAttribute(out _) && + refLocal.Type.TryGetInlineArrayElementField() is not null); } } diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs index 76dc796ee859b..ef2ad4236dbb8 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs @@ -49,7 +49,7 @@ protected StateMachineRewriter( Debug.Assert(compilationState != null); Debug.Assert(diagnostics != null); Debug.Assert(diagnostics.DiagnosticBag != null); - Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty()); + Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty); this.body = body; this.method = method; diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs index ec3d3a6db7114..cb28b923999b7 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs @@ -718,6 +718,12 @@ public BoundBinaryOperator ObjectEqual(BoundExpression left, BoundExpression rig return Binary(BinaryOperatorKind.ObjectEqual, SpecialType(Microsoft.CodeAnalysis.SpecialType.System_Boolean), left, right); } + public BoundExpression IsNotNullReference(BoundExpression value) + { + var objectType = SpecialType(Microsoft.CodeAnalysis.SpecialType.System_Object); + return ObjectNotEqual(Convert(objectType, value, allowBoxingByRefLikeTypeParametersToObject: true), Null(objectType)); + } + public BoundBinaryOperator ObjectNotEqual(BoundExpression left, BoundExpression right) { return Binary(BinaryOperatorKind.ObjectNotEqual, SpecialType(Microsoft.CodeAnalysis.SpecialType.System_Boolean), left, right); @@ -789,6 +795,21 @@ public BoundObjectCreationExpression New(NamedTypeSymbol type, ImmutableArray args) => new BoundObjectCreationExpression(Syntax, ctor, args) { WasCompilerGenerated = true }; + public BoundObjectCreationExpression New(MethodSymbol constructor, ImmutableArray arguments, ImmutableArray argumentRefKinds) + => new BoundObjectCreationExpression( + Syntax, + constructor, + arguments, + argumentNamesOpt: default, + argumentRefKinds, + expanded: false, + argsToParamsOpt: default, + defaultArguments: default, + constantValueOpt: null, + initializerExpressionOpt: null, + constructor.ContainingType) + { WasCompilerGenerated = true }; + public BoundObjectCreationExpression New(WellKnownMember wm, ImmutableArray args) { var ctor = WellKnownMethod(wm); @@ -1501,8 +1522,10 @@ private MethodSymbol GetFieldFromHandleMethod(NamedTypeSymbol fieldContainer) CodeAnalysis.WellKnownMember.System_Reflection_FieldInfo__GetFieldFromHandle2); } - public BoundExpression Convert(TypeSymbol type, BoundExpression arg) + public BoundExpression Convert(TypeSymbol type, BoundExpression arg, bool allowBoxingByRefLikeTypeParametersToObject = false) { + Debug.Assert(!allowBoxingByRefLikeTypeParametersToObject || type.IsObjectType()); + if (TypeSymbol.Equals(type, arg.Type, TypeCompareKind.ConsiderEverything2)) { return arg; @@ -1515,6 +1538,13 @@ public BoundExpression Convert(TypeSymbol type, BoundExpression arg) CompoundUseSiteInfo.Discarded; #endif Conversion c = Compilation.Conversions.ClassifyConversionFromExpression(arg, type, isChecked: false, ref useSiteInfo); + + if (allowBoxingByRefLikeTypeParametersToObject && !c.Exists && + arg.Type is TypeParameterSymbol { AllowsRefLikeType: true } && type.IsObjectType()) + { + c = Conversion.Boxing; + } + Debug.Assert(c.Exists); // The use-site diagnostics should be reported earlier, and we shouldn't get to lowering if they're errors. Debug.Assert(!useSiteInfo.HasErrors); diff --git a/src/Compilers/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.csproj b/src/Compilers/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.csproj index fc2bc788af954..b1a1a6daab2a3 100644 --- a/src/Compilers/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.csproj +++ b/src/Compilers/CSharp/Portable/Microsoft.CodeAnalysis.CSharp.csproj @@ -76,6 +76,7 @@ + diff --git a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs index acf8246550b90..2b7e62c5393bc 100644 --- a/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs +++ b/src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs @@ -881,7 +881,9 @@ private IOperation CreateBoundObjectInitializerMemberOperation(BoundObjectInitia { // In nested member initializers, the property is not actually set. Instead, it is retrieved for a series of Add method calls or nested property setter calls, // so we need to use the getter for this property - MethodSymbol? accessor = isObjectOrCollectionInitializer ? property.GetOwnOrInheritedGetMethod() : property.GetOwnOrInheritedSetMethod(); + MethodSymbol? accessor = isObjectOrCollectionInitializer || property.RefKind != RefKind.None + ? property.GetOwnOrInheritedGetMethod() + : property.GetOwnOrInheritedSetMethod(); if (accessor == null || boundObjectInitializerMember.ResultKind == LookupResultKind.OverloadResolutionFailure || accessor.OriginalDefinition is ErrorMethodSymbol) { var children = CreateFromArray(((IBoundInvalidNode)boundObjectInitializerMember).InvalidNodeChildren); @@ -1877,9 +1879,10 @@ private IForLoopOperation CreateBoundForStatementOperation(BoundForStatement bou needsDispose: enumeratorInfoOpt.NeedsDisposal, knownToImplementIDisposable: enumeratorInfoOpt.NeedsDisposal ? compilation.Conversions. - ClassifyImplicitConversionFromType(enumeratorInfoOpt.GetEnumeratorInfo.Method.ReturnType, + HasImplicitConversionToOrImplementsVarianceCompatibleInterface(enumeratorInfoOpt.GetEnumeratorInfo.Method.ReturnType, iDisposable, - ref discardedUseSiteInfo).IsImplicit : + ref discardedUseSiteInfo, + needSupportForRefStructInterfaces: out _) : false, enumeratorInfoOpt.PatternDisposeInfo?.Method.GetPublicSymbol(), BoundNode.GetConversion(enumeratorInfoOpt.CurrentConversion, enumeratorInfoOpt.CurrentPlaceholder), diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 6ee66aec39cd7..b78ac9891e10b 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -1962,11 +1962,14 @@ private TypeParameterConstraintClauseSyntax ParseTypeParameterConstraintClause() } else { - bounds.Add(this.ParseTypeParameterConstraint()); + TypeParameterConstraintSyntax constraint = this.ParseTypeParameterConstraint(); + bounds.Add(constraint); // remaining bounds while (true) { + bool haveComma; + if (this.CurrentToken.Kind == SyntaxKind.OpenBraceToken || ((_termState & TerminatorState.IsEndOfRecordOrClassOrStructOrInterfaceSignature) != 0 && this.CurrentToken.Kind == SyntaxKind.SemicolonToken) || this.CurrentToken.Kind == SyntaxKind.EqualsGreaterThanToken @@ -1974,9 +1977,17 @@ private TypeParameterConstraintClauseSyntax ParseTypeParameterConstraintClause() { break; } - else if (this.CurrentToken.Kind == SyntaxKind.CommaToken || this.IsPossibleTypeParameterConstraint()) + else if (haveComma = (this.CurrentToken.Kind == SyntaxKind.CommaToken) || this.IsPossibleTypeParameterConstraint()) { - bounds.AddSeparator(this.EatToken(SyntaxKind.CommaToken)); + SyntaxToken separatorToken = this.EatToken(SyntaxKind.CommaToken); + + if (constraint.Kind == SyntaxKind.AllowsConstraintClause && haveComma && !this.IsPossibleTypeParameterConstraint()) + { + AddTrailingSkippedSyntax(bounds, this.AddError(separatorToken, ErrorCode.ERR_UnexpectedToken, SyntaxFacts.GetText(SyntaxKind.CommaToken))); + break; + } + + bounds.AddSeparator(separatorToken); if (this.IsCurrentTokenWhereOfConstraintClause()) { bounds.Add(_syntaxFactory.TypeConstraint(this.AddError(this.CreateMissingIdentifierName(), ErrorCode.ERR_TypeExpected))); @@ -1984,7 +1995,8 @@ private TypeParameterConstraintClauseSyntax ParseTypeParameterConstraintClause() } else { - bounds.Add(this.ParseTypeParameterConstraint()); + constraint = this.ParseTypeParameterConstraint(); + bounds.Add(constraint); } } else if (skipBadTypeParameterConstraintTokens(bounds, SyntaxKind.CommaToken) == PostSkipAction.Abort) @@ -2021,7 +2033,8 @@ private bool IsPossibleTypeParameterConstraint() case SyntaxKind.DefaultKeyword: return true; case SyntaxKind.IdentifierToken: - return this.IsTrueIdentifier(); + + return (this.CurrentToken.ContextualKind == SyntaxKind.AllowsKeyword && PeekToken(1).Kind == SyntaxKind.RefKeyword) || this.IsTrueIdentifier(); default: return IsPredefinedType(this.CurrentToken.Kind); } @@ -2068,8 +2081,39 @@ private TypeParameterConstraintSyntax ParseTypeParameterConstraint() this.AddError(this.CreateMissingIdentifierName(), ErrorCode.ERR_NoDelegateConstraint), this.EatToken())), - _ => _syntaxFactory.TypeConstraint(this.ParseType()), + _ => parseTypeOrAllowsConstraint(), }; + + TypeParameterConstraintSyntax parseTypeOrAllowsConstraint() + { + if (this.CurrentToken.ContextualKind == SyntaxKind.AllowsKeyword && + PeekToken(1).Kind == SyntaxKind.RefKeyword) + { + var allows = this.EatContextualToken(SyntaxKind.AllowsKeyword); + + var bounds = _pool.AllocateSeparated(); + + while (true) + { + bounds.Add( + _syntaxFactory.RefStructConstraint( + this.EatToken(SyntaxKind.RefKeyword), + this.EatToken(SyntaxKind.StructKeyword))); + + if (this.CurrentToken.Kind == SyntaxKind.CommaToken && PeekToken(1).Kind == SyntaxKind.RefKeyword) + { + bounds.AddSeparator(this.EatToken(SyntaxKind.CommaToken)); + continue; + } + + break; + } + + return _syntaxFactory.AllowsConstraintClause(allows, _pool.ToListAndFree(bounds)); + } + + return _syntaxFactory.TypeConstraint(this.ParseType()); + } } private bool IsPossibleMemberStart() diff --git a/src/Compilers/CSharp/Portable/Parser/Lexer.cs b/src/Compilers/CSharp/Portable/Parser/Lexer.cs index b409d5a3abab0..bcb3d9296d2ad 100644 --- a/src/Compilers/CSharp/Portable/Parser/Lexer.cs +++ b/src/Compilers/CSharp/Portable/Parser/Lexer.cs @@ -411,6 +411,9 @@ private SyntaxToken Create(in TokenInfo info, SyntaxListBuilder? leading, Syntax case SyntaxKind.EndOfFileToken: token = SyntaxFactory.Token(leadingNode, info.Kind, trailingNode); break; + case SyntaxKind.RazorContentToken: + token = SyntaxFactory.Token(leadingNode, info.Kind, info.Text, trailingNode); + break; case SyntaxKind.None: token = SyntaxFactory.BadToken(leadingNode, info.Text, trailingNode); break; @@ -610,6 +613,19 @@ private void ScanSyntaxToken(ref TokenInfo info) !this.ScanIdentifierOrKeyword(ref info)) { Debug.Assert(TextWindow.PeekChar() == '@'); + + if (TextWindow.PeekChar(1) == ':') + { + // Razor HTML transition. For best consumption by razor, we want to simply pretend it's a token and + // consume all the way to the end of the line. + info.Kind = SyntaxKind.RazorContentToken; + this.AddError(TextWindow.Position + 1, width: 1, ErrorCode.ERR_ExpectedVerbatimLiteral); + + this.ScanToEndOfLine(); + info.Text = TextWindow.GetText(false); + break; + } + this.ConsumeAtSignSequence(); info.Text = TextWindow.GetText(intern: true); this.AddError(ErrorCode.ERR_ExpectedVerbatimLiteral); @@ -1945,14 +1961,6 @@ private void LexSyntaxTrivia(bool afterFirstToken, bool isTrailing, ref SyntaxLi onlyWhitespaceOnLine = false; break; } - else if (ch == ':') - { - // Razor HTML transition. We pretend it's a single-line comment for error recovery. - this.AddError(TextWindow.Position, width: 1, ErrorCode.ERR_UnexpectedCharacter, '@'); - lexSingleLineComment(ref triviaList); - onlyWhitespaceOnLine = false; - break; - } else { return; diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index e2eac632d971c..6f01326afcc99 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -7,18 +7,9 @@ Microsoft.CodeAnalysis.CSharp.Conversion.IsCollectionExpression.get -> bool Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax.ReadOnlyKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken refKindKeyword, Microsoft.CodeAnalysis.SyntaxToken readOnlyKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax! type) -> Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax! Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax.WithReadOnlyKeyword(Microsoft.CodeAnalysis.SyntaxToken readOnlyKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax! -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Dispose() -> void -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.ParseNextToken() -> Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.ResetTo(Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result result) -> void -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result.ContextualKind.get -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result.Result() -> void -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result.Token.get -> Microsoft.CodeAnalysis.SyntaxToken -Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.SkipForwardTo(int position) -> void +Microsoft.CodeAnalysis.CSharp.SyntaxKind.RazorContentToken = 8523 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetDeclaredSymbol(this Microsoft.CodeAnalysis.SemanticModel? semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax! node, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.IMethodSymbol? static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetElementConversion(this Microsoft.CodeAnalysis.Operations.ISpreadOperation! spread) -> Microsoft.CodeAnalysis.CSharp.Conversion -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CreateTokenParser(Microsoft.CodeAnalysis.Text.SourceText! sourceText, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions? options = null) -> Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser! static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CrefParameter(Microsoft.CodeAnalysis.SyntaxToken refKindKeyword, Microsoft.CodeAnalysis.SyntaxToken readOnlyKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax! type) -> Microsoft.CodeAnalysis.CSharp.Syntax.CrefParameterSyntax! [RSEXPERIMENTAL001]Microsoft.CodeAnalysis.CSharp.CSharpCompilation.GetSemanticModel(Microsoft.CodeAnalysis.SyntaxTree! syntaxTree, Microsoft.CodeAnalysis.SemanticModelOptions options) -> Microsoft.CodeAnalysis.SemanticModel! [RSEXPERIMENTAL002]override abstract Microsoft.CodeAnalysis.CSharp.InterceptableLocation.Equals(object? obj) -> bool @@ -26,3 +17,46 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CrefParameter(Microsoft.CodeA [RSEXPERIMENTAL002]static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetInterceptorMethod(this Microsoft.CodeAnalysis.SemanticModel? semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax! node, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.IMethodSymbol? [RSEXPERIMENTAL002]static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetInterceptableLocation(this Microsoft.CodeAnalysis.SemanticModel? semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax! node, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.CSharp.InterceptableLocation? [RSEXPERIMENTAL002]static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetInterceptsLocationAttributeSyntax(this Microsoft.CodeAnalysis.CSharp.InterceptableLocation! location) -> string! +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Dispose() -> void +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.ParseLeadingTrivia() -> Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.ParseNextToken() -> Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.ParseTrailingTrivia() -> Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.ResetTo(Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result result) -> void +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result.ContextualKind.get -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result.Result() -> void +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.Result.Token.get -> Microsoft.CodeAnalysis.SyntaxToken +[RSEXPERIMENTAL003]Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser.SkipForwardTo(int position) -> void +[RSEXPERIMENTAL003]static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.CreateTokenParser(Microsoft.CodeAnalysis.Text.SourceText! sourceText, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions? options = null) -> Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser! +Microsoft.CodeAnalysis.CSharp.SyntaxKind.AllowsConstraintClause = 8879 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.AllowsKeyword = 8450 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.RefStructConstraint = 8880 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitAllowsConstraintClause(Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! node) -> Microsoft.CodeAnalysis.SyntaxNode? +override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitRefStructConstraint(Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! node) -> Microsoft.CodeAnalysis.SyntaxNode? +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.AddConstraints(params Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintSyntax![]! items) -> Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.AllowsKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.Constraints.get -> Microsoft.CodeAnalysis.SeparatedSyntaxList +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken allowsKeyword, Microsoft.CodeAnalysis.SeparatedSyntaxList constraints) -> Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.WithAllowsKeyword(Microsoft.CodeAnalysis.SyntaxToken allowsKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.WithConstraints(Microsoft.CodeAnalysis.SeparatedSyntaxList constraints) -> Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! +override Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor! visitor) -> void +override Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor! visitor) -> TResult? +Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.RefKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.StructKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken refKeyword, Microsoft.CodeAnalysis.SyntaxToken structKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! +Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.WithRefKeyword(Microsoft.CodeAnalysis.SyntaxToken refKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! +Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.WithStructKeyword(Microsoft.CodeAnalysis.SyntaxToken structKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! +override Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor! visitor) -> void +override Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor! visitor) -> TResult? +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.AllowsConstraintClause(Microsoft.CodeAnalysis.SeparatedSyntaxList constraints = default(Microsoft.CodeAnalysis.SeparatedSyntaxList)) -> Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.AllowsConstraintClause(Microsoft.CodeAnalysis.SyntaxToken allowsKeyword, Microsoft.CodeAnalysis.SeparatedSyntaxList constraints) -> Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RefStructConstraint() -> Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RefStructConstraint(Microsoft.CodeAnalysis.SyntaxToken refKeyword, Microsoft.CodeAnalysis.SyntaxToken structKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitAllowsConstraintClause(Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! node) -> void +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRefStructConstraint(Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! node) -> void +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitAllowsConstraintClause(Microsoft.CodeAnalysis.CSharp.Syntax.AllowsConstraintClauseSyntax! node) -> TResult? +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRefStructConstraint(Microsoft.CodeAnalysis.CSharp.Syntax.RefStructConstraintSyntax! node) -> TResult? \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs index a6aa4f0cb8909..0825bdf3f429f 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Members.cs @@ -829,7 +829,7 @@ public override void VisitParameter(IParameterSymbol symbol) if (symbol.ScopedKind == ScopedKind.ScopedValue && symbol.RefKind == RefKind.None && - !(symbol.IsParams && symbol.Type.IsRefLikeType)) + !(symbol.IsParams && symbol.Type is { IsRefLikeType: true } or ITypeParameterSymbol { AllowsRefLikeType: true })) { AddKeyword(SyntaxKind.ScopedKeyword); AddSpace(); diff --git a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs index 396fcdd7f80b4..71fac01c8ba6c 100644 --- a/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs +++ b/src/Compilers/CSharp/Portable/SymbolDisplay/SymbolDisplayVisitor.Types.cs @@ -837,7 +837,7 @@ private static bool TypeParameterHasConstraints(ITypeParameterSymbol typeParam) { return !typeParam.ConstraintTypes.IsEmpty || typeParam.HasConstructorConstraint || typeParam.HasReferenceTypeConstraint || typeParam.HasValueTypeConstraint || - typeParam.HasNotNullConstraint; + typeParam.HasNotNullConstraint || typeParam.AllowsRefLikeType; } private void AddTypeParameterConstraints(ImmutableArray typeArguments) @@ -917,7 +917,7 @@ private void AddTypeParameterConstraints(ImmutableArray typeArgumen needComma = true; } - //ctor constraint must be last + //ctor constraint must be last before 'allows ref struct' if (typeParam.HasConstructorConstraint) { if (needComma) @@ -929,6 +929,22 @@ private void AddTypeParameterConstraints(ImmutableArray typeArgumen AddKeyword(SyntaxKind.NewKeyword); AddPunctuation(SyntaxKind.OpenParenToken); AddPunctuation(SyntaxKind.CloseParenToken); + needComma = true; + } + + if (typeParam.AllowsRefLikeType) + { + if (needComma) + { + AddPunctuation(SyntaxKind.CommaToken); + AddSpace(); + } + + AddKeyword(SyntaxKind.AllowsKeyword); + AddSpace(); + AddKeyword(SyntaxKind.RefKeyword); + AddSpace(); + AddKeyword(SyntaxKind.StructKeyword); } } } diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeField.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeField.cs index 5cbe3c388479c..06d8968093dcb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeField.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeField.cs @@ -43,7 +43,6 @@ public AnonymousTypeField( bool isParams = false, bool hasUnscopedRefAttribute = false) { - Debug.Assert(!isParams || !typeWithAnnotations.Type.IsTypeParameter()); this.Name = name; this.Location = location; this.TypeWithAnnotations = typeWithAnnotations; diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeManager.Templates.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeManager.Templates.cs index 6bfbd8e32d86d..157718ec50f0e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeManager.Templates.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/AnonymousTypeManager.Templates.cs @@ -190,7 +190,9 @@ private NamedTypeSymbol ConstructAnonymousDelegateImplementationSymbol(Anonymous // If all parameter types and return type are valid type arguments, construct // the delegate type from a generic template. Otherwise, use a non-generic template. bool useUpdatedEscapeRules = Compilation.SourceModule.UseUpdatedEscapeRules; - if (allValidTypeArguments(useUpdatedEscapeRules, typeDescr, out var needsIndexedName)) + bool runtimeSupportsByRefLikeGenerics = Compilation.SourceAssembly.RuntimeSupportsByRefLikeGenerics; + + if (allValidTypeArguments(useUpdatedEscapeRules, runtimeSupportsByRefLikeGenerics, typeDescr, out var needsIndexedName)) { var fields = typeDescr.Fields; Debug.Assert(fields.All(f => hasDefaultScope(useUpdatedEscapeRules, f))); @@ -294,20 +296,20 @@ private NamedTypeSymbol ConstructAnonymousDelegateImplementationSymbol(Anonymous template.Construct(typeParameters); } - static bool allValidTypeArguments(bool useUpdatedEscapeRules, AnonymousTypeDescriptor typeDescr, out bool needsIndexedName) + static bool allValidTypeArguments(bool useUpdatedEscapeRules, bool runtimeSupportsByRefLikeGenerics, AnonymousTypeDescriptor typeDescr, out bool needsIndexedName) { needsIndexedName = false; var fields = typeDescr.Fields; int n = fields.Length; for (int i = 0; i < n - 1; i++) { - if (!isValidTypeArgument(useUpdatedEscapeRules, fields[i], ref needsIndexedName)) + if (!isValidTypeArgument(useUpdatedEscapeRules, runtimeSupportsByRefLikeGenerics, fields[i], ref needsIndexedName)) { return false; } } var returnParameter = fields[n - 1]; - return returnParameter.Type.IsVoidType() || isValidTypeArgument(useUpdatedEscapeRules, returnParameter, ref needsIndexedName); + return returnParameter.Type.IsVoidType() || isValidTypeArgument(useUpdatedEscapeRules, runtimeSupportsByRefLikeGenerics, returnParameter, ref needsIndexedName); } static bool hasDefaultScope(bool useUpdatedEscapeRules, AnonymousTypeField field) @@ -324,13 +326,13 @@ static bool hasDefaultScope(bool useUpdatedEscapeRules, AnonymousTypeField field }; } - static bool isValidTypeArgument(bool useUpdatedEscapeRules, AnonymousTypeField field, ref bool needsIndexedName) + static bool isValidTypeArgument(bool useUpdatedEscapeRules, bool runtimeSupportsByRefLikeGenerics, AnonymousTypeField field, ref bool needsIndexedName) { needsIndexedName = needsIndexedName || field.IsParams || field.DefaultValue is not null; return hasDefaultScope(useUpdatedEscapeRules, field) && field.Type is { } type && !type.IsPointerOrFunctionPointer() && - !type.IsRestrictedType() && + (type.IsTypeParameter() || !type.IsRestrictedType(ignoreSpanLikeTypes: runtimeSupportsByRefLikeGenerics)) && (!field.IsParams || field.Type.IsSZArray()); // [params T collection] is not recognized as a valid params parameter definition } diff --git a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeParameterSymbol.cs index 252080f9666c0..b7a14cc207bbf 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousType.TypeParameterSymbol.cs @@ -17,11 +17,11 @@ internal sealed partial class AnonymousTypeManager /// internal sealed class AnonymousTypeParameterSymbol : TypeParameterSymbol { - private readonly Symbol _container; + private readonly AnonymousTypeOrDelegateTemplateSymbol _container; private readonly int _ordinal; private readonly string _name; - public AnonymousTypeParameterSymbol(Symbol container, int ordinal, string name) + public AnonymousTypeParameterSymbol(AnonymousTypeOrDelegateTemplateSymbol container, int ordinal, string name) { Debug.Assert((object)container != null); Debug.Assert(!string.IsNullOrEmpty(name)); @@ -91,6 +91,14 @@ public override bool HasValueTypeConstraint get { return false; } } + public override bool AllowsRefLikeType + { + get + { + return _container.IsDelegateType() && ContainingAssembly.RuntimeSupportsByRefLikeGenerics; + } + } + public override bool IsValueTypeFromConstraintTypes { get { return false; } diff --git a/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs index f9d5d858f07da..b9b6dc93256bc 100644 --- a/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/AssemblySymbol.cs @@ -427,6 +427,8 @@ public bool SupportsRuntimeCapability(RuntimeCapability capability) return this.RuntimeSupportsStaticAbstractMembersInInterfaces; case RuntimeCapability.InlineArrayTypes: return this.RuntimeSupportsInlineArrayTypes; + case RuntimeCapability.ByRefLikeGenerics: + return this.RuntimeSupportsByRefLikeGenerics; } return false; @@ -477,6 +479,21 @@ internal bool RuntimeSupportsInlineArrayTypes } } + /// + /// Figure out if the target runtime supports inline array types. + /// + internal bool RuntimeSupportsByRefLikeGenerics + { + // Keep in sync with VB's AssemblySymbol.RuntimeSupportsByRefLikeGenerics + get + { + // CorLibrary should never be null, but that invariant is broken in some cases for MissingAssemblySymbol. + // Tracked by https://github.com/dotnet/roslyn/issues/61262 + return CorLibrary is not null && + RuntimeSupportsFeature(SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics); + } + } + protected bool RuntimeSupportsFeature(SpecialMember feature) { // Keep in sync with VB's AssemblySymbol.RuntimeSupportsFeature diff --git a/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs b/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs index da3009c5a969c..2fd329ace506a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs +++ b/src/Compilers/CSharp/Portable/Symbols/CompletionPart.cs @@ -85,9 +85,9 @@ internal enum CompletionPart StartDefaultSyntaxValue = 1 << 11, EndDefaultSyntaxValue = 1 << 12, EndDefaultSyntaxValueDiagnostics = 1 << 13, - StartParamsValidation = 1 << 14, - EndParamsValidation = 1 << 15, - ComplexParameterSymbolAll = Attributes | StartDefaultSyntaxValue | EndDefaultSyntaxValue | EndDefaultSyntaxValueDiagnostics | StartParamsValidation | EndParamsValidation, + StartMiscValidation = 1 << 14, + EndMiscValidation = 1 << 15, + ComplexParameterSymbolAll = Attributes | StartDefaultSyntaxValue | EndDefaultSyntaxValue | EndDefaultSyntaxValueDiagnostics | StartMiscValidation | EndMiscValidation, // For type parameter symbols TypeParameterConstraints = 1 << 11, diff --git a/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs b/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs index 247025c28b16e..adda0ec4d4d9e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ConstraintsHelper.cs @@ -69,7 +69,7 @@ internal static class ConstraintsHelper /// generic method. In those cases, additional constraint checks are applied. /// public static TypeParameterBounds ResolveBounds( - this TypeParameterSymbol typeParameter, + this SourceTypeParameterSymbolBase typeParameter, AssemblySymbol corLibrary, ConsList inProgress, ImmutableArray constraintTypes, @@ -93,6 +93,34 @@ public static TypeParameterBounds ResolveBounds( } diagnosticsBuilder.Free(); + + if (typeParameter.AllowsRefLikeType) + { + if (inherited) + { + Location location = typeParameter.GetFirstLocation(); + Binder.CheckFeatureAvailability(location.SourceTree, MessageID.IDS_FeatureRefStructInterfaces, diagnostics, location); + + if (!typeParameter.DeclaringCompilation.Assembly.RuntimeSupportsByRefLikeGenerics) + { + diagnostics.Add(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, location); + } + } + else + { + switch (typeParameter.HasReferenceTypeConstraint ? SpecialType.None : (bounds?.EffectiveBaseClass.SpecialType ?? SpecialType.System_Object)) + { + case SpecialType.System_Object: + case SpecialType.System_ValueType: + case SpecialType.System_Enum: + break; + default: + diagnostics.Add(ErrorCode.ERR_ClassIsCombinedWithRefStruct, typeParameter.GetFirstLocation()); + break; + } + } + } + return bounds; } @@ -899,13 +927,37 @@ private static bool CheckBasicConstraints( ArrayBuilder nullabilityDiagnosticsBuilderOpt, ref ArrayBuilder useSiteDiagnosticsBuilder) { - if (typeArgument.Type.IsPointerOrFunctionPointer() || typeArgument.IsRestrictedType() || typeArgument.IsVoidType()) + if (typeArgument.Type.IsPointerOrFunctionPointer() || typeArgument.IsRestrictedType(ignoreSpanLikeTypes: true) || typeArgument.IsVoidType()) { // "The type '{0}' may not be used as a type argument" diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo(new CSDiagnosticInfo(ErrorCode.ERR_BadTypeArgument, typeArgument.Type)))); return false; } + if (typeArgument.Type.IsRefLikeOrAllowsRefLikeType()) + { + if (typeParameter.AllowsRefLikeType) + { + if (args.CurrentCompilation.SourceModule != typeParameter.ContainingModule) + { + if (MessageID.IDS_FeatureRefStructInterfaces.GetFeatureAvailabilityDiagnosticInfo(args.CurrentCompilation) is { } diagnosticInfo) + { + diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo(diagnosticInfo))); + } + + if (!args.CurrentCompilation.Assembly.RuntimeSupportsByRefLikeGenerics) + { + diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo(new CSDiagnosticInfo(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics)))); + } + } + } + else + { + diagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, new UseSiteInfo(new CSDiagnosticInfo(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, containingSymbol.ConstructedFrom(), typeParameter, typeArgument.Type)))); + return false; + } + } + if (typeArgument.IsStatic) { // "'{0}': static types cannot be used as type arguments" @@ -1279,13 +1331,21 @@ private static bool SatisfiesConstraintType( return true; } - // "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..." - // NOTE: we extend this to allow, for example, a conversion from Nullable to object. - if (typeArgument.Type.IsValueType && - conversions.HasBoxingConversion(typeArgument.Type.IsNullableType() ? ((NamedTypeSymbol)typeArgument.Type).ConstructedFrom : typeArgument.Type, - constraintType.Type, ref useSiteInfo)) + if (typeArgument.Type.IsValueType) { - return true; + // "... A boxing conversion (6.1.7), provided that type A is a non-nullable value type. ..." + // NOTE: we extend this to allow, for example, a conversion from Nullable to object. + if (conversions.HasBoxingConversion(typeArgument.Type.IsNullableType() ? ((NamedTypeSymbol)typeArgument.Type).ConstructedFrom : typeArgument.Type, + constraintType.Type, ref useSiteInfo)) + { + return true; + } + + if (typeArgument.Type is NamedTypeSymbol { IsRefLikeType: true } refLike && + conversions.ImplementsVarianceCompatibleInterface(refLike, constraintType.Type, ref useSiteInfo)) + { + return true; + } } if (typeArgument.TypeKind == TypeKind.TypeParameter) diff --git a/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.ErrorTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.ErrorTypeParameterSymbol.cs index efe4c2211d380..8a63c9a6e1ce5 100644 --- a/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.ErrorTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/ErrorTypeSymbol.ErrorTypeParameterSymbol.cs @@ -91,6 +91,14 @@ public override bool HasValueTypeConstraint } } + public override bool AllowsRefLikeType + { + get + { + return false; + } + } + public override bool IsValueTypeFromConstraintTypes { get diff --git a/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs b/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs index e0e96d43a6888..49e600be59c0e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MemberSignatureComparer.cs @@ -654,6 +654,7 @@ public static bool HaveSameConstraints(TypeParameterSymbol typeParameter1, TypeM if ((typeParameter1.HasConstructorConstraint != typeParameter2.HasConstructorConstraint) || (typeParameter1.HasReferenceTypeConstraint != typeParameter2.HasReferenceTypeConstraint) || (typeParameter1.HasValueTypeConstraint != typeParameter2.HasValueTypeConstraint) || + (typeParameter1.AllowsRefLikeType != typeParameter2.AllowsRefLikeType) || (typeParameter1.HasUnmanagedTypeConstraint != typeParameter2.HasUnmanagedTypeConstraint) || (typeParameter1.Variance != typeParameter2.Variance)) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs index ca5bc67794aa9..4018b84c18f48 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEFieldSymbol.cs @@ -634,7 +634,7 @@ internal override UseSiteInfo GetUseSiteInfo() UseSiteInfo result = new UseSiteInfo(primaryDependency); CalculateUseSiteDiagnostic(ref result); if (RefKind != RefKind.None && - (IsFixedSizeBuffer || Type.IsRefLikeType == true)) + (IsFixedSizeBuffer || Type.IsRefLikeOrAllowsRefLikeType())) { MergeUseSiteInfo(ref result, new UseSiteInfo(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this))); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs index 02540a7efea77..8f09cb23e255c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PEParameterSymbol.cs @@ -333,7 +333,7 @@ private PEParameterSymbol( Debug.Assert(refKind != RefKind.None); scope = ScopedKind.ScopedRef; } - else if (typeWithAnnotations.Type.IsRefLikeType) + else if (typeWithAnnotations.Type.IsRefLikeOrAllowsRefLikeType()) { scope = ScopedKind.ScopedValue; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs index 147b7b07f8bc1..0a0d718a4a27e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.cs @@ -567,6 +567,14 @@ public override bool HasValueTypeConstraint } } + public override bool AllowsRefLikeType + { + get + { + return (_flags & MetadataHelpers.GenericParameterAttributesAllowByRefLike) != 0; + } + } + public override bool IsValueTypeFromConstraintTypes { get diff --git a/src/Compilers/CSharp/Portable/Symbols/MethodSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/MethodSymbolExtensions.cs index 5f85462fcdeb1..b1fee8aae96ac 100644 --- a/src/Compilers/CSharp/Portable/Symbols/MethodSymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/MethodSymbolExtensions.cs @@ -216,7 +216,8 @@ internal static CSharpSyntaxNode ExtractReturnTypeSyntax(this MethodSymbol metho internal static bool IsValidUnscopedRefAttributeTarget(this MethodSymbol method) { return !method.IsStatic && - method.ContainingType?.IsStructType() == true && + method.ContainingType is NamedTypeSymbol containingType && + (containingType.IsStructType() == true || (containingType.IsInterface && method.IsImplementable())) && method.MethodKind is (MethodKind.Ordinary or MethodKind.ExplicitInterfaceImplementation or MethodKind.PropertyGet or MethodKind.PropertySet) && !method.IsInitOnly; } diff --git a/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeParameterSymbol.cs index a12d1cd45e2a1..30c6a668122c2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/PublicModel/TypeParameterSymbol.cs @@ -88,6 +88,8 @@ ITypeParameterSymbol ITypeParameterSymbol.ReducedFrom bool ITypeParameterSymbol.HasValueTypeConstraint => _underlying.HasValueTypeConstraint; + bool ITypeParameterSymbol.AllowsRefLikeType => _underlying.AllowsRefLikeType; + bool ITypeParameterSymbol.HasUnmanagedTypeConstraint => _underlying.HasUnmanagedTypeConstraint; bool ITypeParameterSymbol.HasNotNullConstraint => _underlying.HasNotNullConstraint; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/CrefTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/CrefTypeParameterSymbol.cs index e3ee9a0c24d67..a18134e5d95fe 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/CrefTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/CrefTypeParameterSymbol.cs @@ -127,6 +127,11 @@ public override bool HasValueTypeConstraint get { return false; } } + public override bool AllowsRefLikeType + { + get { return false; } + } + public override bool IsValueTypeFromConstraintTypes { get { return false; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/IndexedTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/IndexedTypeParameterSymbol.cs index c3990987bfd60..f53239ea8f4ec 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/IndexedTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/IndexedTypeParameterSymbol.cs @@ -142,6 +142,11 @@ public override bool HasValueTypeConstraint get { return false; } } + public override bool AllowsRefLikeType + { + get { return false; } + } + public override bool IsValueTypeFromConstraintTypes { get { return false; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index cd3aec6946c79..d502a7080b83c 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -58,7 +58,7 @@ public LocalFunctionSymbol( ScopeBinder = binder; - binder = binder.WithUnsafeRegionIfNecessary(syntax.Modifiers); + binder = binder.SetOrClearUnsafeRegionIfNecessary(syntax.Modifiers); if (syntax.TypeParameterList != null) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs index f5e9116f1248d..f09261eaf06ab 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs @@ -190,11 +190,10 @@ private static ImmutableArray MakeParameters (p.RefKind is RefKind.Ref or RefKind.Out) && p.Type.IsRefLikeType)) + else if (parameters.Any(p => (p.RefKind is RefKind.Ref or RefKind.Out) && p.Type.IsRefLikeOrAllowsRefLikeType())) { nRefParametersRequired = 2; // including the parameter found above } @@ -1423,7 +1423,7 @@ internal static bool RequiresValidScopedOverrideForRefSafety(MethodSymbol? metho { return true; } - else if (parameters.Any(p => p.RefKind == RefKind.None && p.Type.IsRefLikeType)) + else if (parameters.Any(p => p.RefKind == RefKind.None && p.Type.IsRefLikeOrAllowsRefLikeType())) { return true; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs index 804ac34303400..8f635798af17d 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberFieldSymbol.cs @@ -63,7 +63,7 @@ protected void TypeChecks(TypeSymbol type, BindingDiagnosticBag diagnostics) { diagnostics.Add(ErrorCode.ERR_FieldCantBeRefAny, TypeSyntax?.Location ?? this.GetFirstLocation(), type); } - else if (type.IsRefLikeType && (this.IsStatic || !containingType.IsRefLikeType)) + else if (type.IsRefLikeOrAllowsRefLikeType() && (this.IsStatic || !containingType.IsRefLikeType)) { diagnostics.Add(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, TypeSyntax?.Location ?? this.GetFirstLocation(), type); } @@ -500,7 +500,7 @@ private TypeAndRefKind GetTypeAndRefKind(ConsList fieldsBeingBound) if (!containingType.IsRefLikeType) diagnostics.Add(ErrorCode.ERR_RefFieldInNonRefStruct, ErrorLocation); - if (type.Type?.IsRefLikeType == true) + if (type.Type.IsRefLikeOrAllowsRefLikeType()) diagnostics.Add(ErrorCode.ERR_RefFieldCannotReferToRefStruct, typeSyntax.SkipScoped(out _).Location); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs index a1771beb99a70..8cce2057e5200 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbol.cs @@ -72,7 +72,7 @@ internal void ReportAsyncParameterErrors(BindingDiagnosticBag diagnostics, Locat } else if (parameter.Type.IsRestrictedType()) { - diagnostics.Add(ErrorCode.ERR_BadSpecialByRefLocal, getLocation(parameter, location), parameter.Type); + diagnostics.Add(ErrorCode.ERR_BadSpecialByRefParameter, getLocation(parameter, location), parameter.Type); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 70bbd0a42458f..e5765d5060ace 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -82,7 +82,7 @@ internal SyntaxReference SyntaxRef } } - internal virtual CSharpSyntaxNode SyntaxNode + internal CSharpSyntaxNode SyntaxNode { get { @@ -595,6 +595,11 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut if (this.IsValidUnscopedRefAttributeTarget()) { arguments.GetOrCreateData().HasUnscopedRefAttribute = true; + + if (ContainingType.IsInterface || IsExplicitInterfaceImplementation) + { + MessageID.IDS_FeatureRefStructInterfaces.CheckFeatureAvailability(diagnostics, arguments.AttributeSyntaxOpt); + } } else { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol_Bases.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol_Bases.cs index 1bd1e0998a13f..c6aef2c70456b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol_Bases.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol_Bases.cs @@ -569,8 +569,7 @@ private Tuple> MakeOneDeclaredB if (this.IsRefLikeType) { - // '{0}': ref structs cannot implement interfaces - diagnostics.Add(ErrorCode.ERR_RefStructInterfaceImpl, location, this); + Binder.CheckFeatureAvailability(typeSyntax, MessageID.IDS_FeatureRefStructInterfaces, diagnostics); } if (baseType.ContainsDynamic()) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs index c1c22b25029cd..cfab273ec53e3 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodOrUserDefinedOperatorSymbol.cs @@ -69,12 +69,6 @@ public sealed override bool ReturnsVoid } } - if (!IsPartial) - { - LazyAsyncMethodChecks(CancellationToken.None); - Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks)); - } - // The runtime will not treat this method as an override or implementation of another // method unless both the signatures and the custom modifiers match. Hence, in the // case of overrides and *explicit* implementations, we need to copy the custom modifiers diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs index f1ade69b03ff6..158419141cdeb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceOrdinaryMethodSymbolBase.cs @@ -43,10 +43,6 @@ protected SourceOrdinaryMethodSymbolBase( protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellationToken) { - Debug.Assert(this.IsPartial == state.HasComplete(CompletionPart.FinishMethodChecks), - "Partial methods complete method checks during construction. " + - "Other methods can't complete method checks before executing this method."); - if (!this.IsAsync) { CompleteAsyncMethodChecks(diagnosticsOpt: null, cancellationToken: cancellationToken); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs index d7afda5c988fb..15f02aa85bb9e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceParameterSymbol.cs @@ -79,9 +79,10 @@ public static SourceParameterSymbol Create( !isExtensionMethodThis && (syntax.Default == null) && (syntax.AttributeLists.Count == 0) && - !owner.IsPartialMethod()) + !owner.IsPartialMethod() && + scope == ScopedKind.None) { - return new SourceSimpleParameterSymbol(owner, parameterType, ordinal, refKind, scope, name, location); + return new SourceSimpleParameterSymbol(owner, parameterType, ordinal, refKind, name, location); } return new SourceComplexParameterSymbol( @@ -241,7 +242,7 @@ protected ScopedKind CalculateEffectiveScopeIgnoringAttributes() { return ScopedKind.ScopedRef; } - else if (HasParamsModifier && Type.IsRefLikeType) + else if (HasParamsModifier && Type.IsRefLikeOrAllowsRefLikeType()) { return ScopedKind.ScopedValue; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs index af93d12c934ff..eb6c3ff553bfa 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbol.cs @@ -59,7 +59,7 @@ private static SourcePropertySymbol Create( bool isExpressionBodied = !hasAccessorList && GetArrowExpression(syntax) != null; - binder = binder.WithUnsafeRegionIfNecessary(modifiersTokenList); + binder = binder.SetOrClearUnsafeRegionIfNecessary(modifiersTokenList); TypeSymbol? explicitInterfaceType; string? aliasQualifierOpt; string memberName = ExplicitInterfaceHelpers.GetMemberNameAndInterfaceSymbol(binder, explicitInterfaceSpecifier, name, diagnostics, out explicitInterfaceType, out aliasQualifierOpt); @@ -431,7 +431,7 @@ private Binder CreateBinderForTypeAndParameters() var binderFactory = compilation.GetBinderFactory(syntaxTree); var binder = binderFactory.GetBinder(syntax, syntax, this); SyntaxTokenList modifiers = GetModifierTokensSyntax(syntax); - binder = binder.WithUnsafeRegionIfNecessary(modifiers); + binder = binder.SetOrClearUnsafeRegionIfNecessary(modifiers); return binder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs index 326d8414791f1..78c9c04f76aae 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs @@ -1312,6 +1312,11 @@ protected override void DecodeWellKnownAttributeImpl(ref DecodeWellKnownAttribut if (this.IsValidUnscopedRefAttributeTarget()) { arguments.GetOrCreateData().HasUnscopedRefAttribute = true; + + if (ContainingType.IsInterface || IsExplicitInterfaceImplementation) + { + MessageID.IDS_FeatureRefStructInterfaces.CheckFeatureAvailability(diagnostics, arguments.AttributeSyntaxOpt); + } } else { @@ -1539,7 +1544,7 @@ protected virtual void ValidatePropertyType(BindingDiagnosticBag diagnostics) { diagnostics.Add(ErrorCode.ERR_FieldCantBeRefAny, TypeLocation, type); } - else if (this.IsAutoPropertyWithGetAccessor && type.IsRefLikeType && (this.IsStatic || !this.ContainingType.IsRefLikeType)) + else if (this.IsAutoPropertyWithGetAccessor && type.IsRefLikeOrAllowsRefLikeType() && (this.IsStatic || !this.ContainingType.IsRefLikeType)) { diagnostics.Add(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, TypeLocation, type); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceSimpleParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceSimpleParameterSymbol.cs index 99070f56e32b8..5d5a66667a155 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceSimpleParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceSimpleParameterSymbol.cs @@ -22,10 +22,9 @@ public SourceSimpleParameterSymbol( TypeWithAnnotations parameterType, int ordinal, RefKind refKind, - ScopedKind scope, string name, ImmutableArray locations) - : this(owner, parameterType, ordinal, refKind, scope, name, locations.FirstOrDefault()) + : this(owner, parameterType, ordinal, refKind, name, locations.FirstOrDefault()) { Debug.Assert(locations.Length <= 1); } @@ -35,10 +34,9 @@ public SourceSimpleParameterSymbol( TypeWithAnnotations parameterType, int ordinal, RefKind refKind, - ScopedKind scope, string name, Location? location) - : base(owner, ordinal, refKind, scope, name, location) + : base(owner, ordinal, refKind, ScopedKind.None, name, location) { _parameterType = parameterType; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs index d00d69180e628..b4f70d7b9dc34 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceTypeParameterSymbol.cs @@ -504,6 +504,15 @@ public override bool HasValueTypeConstraint } } + public override bool AllowsRefLikeType + { + get + { + var constraints = this.GetConstraintKinds(); + return (constraints & TypeParameterConstraintKind.AllowByRefLike) != 0; + } + } + public override bool IsValueTypeFromConstraintTypes { get @@ -637,6 +646,15 @@ public override bool HasValueTypeConstraint } } + public override bool AllowsRefLikeType + { + get + { + var constraints = this.GetConstraintKinds(); + return (constraints & TypeParameterConstraintKind.AllowByRefLike) != 0; + } + } + public override bool IsValueTypeFromConstraintTypes { get @@ -891,6 +909,15 @@ public override bool HasValueTypeConstraint } } + public override bool AllowsRefLikeType + { + get + { + var typeParameter = this.OverriddenTypeParameter; + return ((object)typeParameter != null) && typeParameter.AllowsRefLikeType; + } + } + public override bool IsValueTypeFromConstraintTypes { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ThisParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ThisParameterSymbol.cs index 373f6bcaf5436..beba4aa633cfb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/ThisParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/ThisParameterSymbol.cs @@ -7,169 +7,171 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols { - internal sealed class ThisParameterSymbol : ParameterSymbol + internal abstract class ThisParameterSymbolBase : ParameterSymbol { internal const string SymbolName = "this"; - private readonly MethodSymbol? _containingMethod; - private readonly TypeSymbol _containingType; - - internal ThisParameterSymbol(MethodSymbol forMethod) : this(forMethod, forMethod.ContainingType) - { - } - - internal ThisParameterSymbol(MethodSymbol? forMethod, TypeSymbol containingType) - { - Debug.Assert(containingType is not null); - _containingMethod = forMethod; - _containingType = containingType; - } + public sealed override string Name => SymbolName; - public override string Name => SymbolName; + public sealed override bool IsDiscard => false; - public override bool IsDiscard => false; - - public override TypeWithAnnotations TypeWithAnnotations - => TypeWithAnnotations.Create(_containingType, NullableAnnotation.NotAnnotated); - - public override RefKind RefKind - { - get - { - if (ContainingType?.TypeKind != TypeKind.Struct) - { - return RefKind.None; - } - - if (_containingMethod?.MethodKind == MethodKind.Constructor) - { - return RefKind.Out; - } - - if (_containingMethod?.IsEffectivelyReadOnly == true) - { - return RefKind.In; - } - - return RefKind.Ref; - } - } - - public override ImmutableArray Locations - { - get { return _containingMethod is not null ? _containingMethod.Locations : ImmutableArray.Empty; } - } - - public override ImmutableArray DeclaringSyntaxReferences + public sealed override ImmutableArray DeclaringSyntaxReferences { get { return ImmutableArray.Empty; } } - public override Symbol ContainingSymbol - { - get { return (Symbol?)_containingMethod ?? _containingType; } - } - - internal override ConstantValue? ExplicitDefaultConstantValue + internal sealed override ConstantValue? ExplicitDefaultConstantValue { get { return null; } } - internal override bool IsMetadataOptional + internal sealed override bool IsMetadataOptional { get { return false; } } - public override bool IsParamsArray + public sealed override bool IsParamsArray { get { return false; } } - public override bool IsParamsCollection + public sealed override bool IsParamsCollection { get { return false; } } - internal override bool IsIDispatchConstant + internal sealed override bool IsIDispatchConstant { get { return false; } } - internal override bool IsIUnknownConstant + internal sealed override bool IsIUnknownConstant { get { return false; } } - internal override bool IsCallerFilePath + internal sealed override bool IsCallerFilePath { get { return false; } } - internal override bool IsCallerLineNumber + internal sealed override bool IsCallerLineNumber { get { return false; } } - internal override bool IsCallerMemberName + internal sealed override bool IsCallerMemberName { get { return false; } } - internal override int CallerArgumentExpressionParameterIndex + internal sealed override int CallerArgumentExpressionParameterIndex { get { return -1; } } - internal override FlowAnalysisAnnotations FlowAnalysisAnnotations + internal sealed override FlowAnalysisAnnotations FlowAnalysisAnnotations { get { return FlowAnalysisAnnotations.None; } } - internal override ImmutableHashSet NotNullIfParameterNotNull + internal sealed override ImmutableHashSet NotNullIfParameterNotNull { get { return ImmutableHashSet.Empty; } } - public override int Ordinal + public sealed override int Ordinal { get { return -1; } } - public override ImmutableArray RefCustomModifiers + public sealed override ImmutableArray RefCustomModifiers { get { return ImmutableArray.Empty; } } - // TODO: structs - public override bool IsThis + public sealed override bool IsThis { get { return true; } } // "this" is never explicitly declared. - public override bool IsImplicitlyDeclared + public sealed override bool IsImplicitlyDeclared { get { return true; } } - internal override bool IsMetadataIn + internal sealed override bool IsMetadataIn { get { return false; } } - internal override bool IsMetadataOut + internal sealed override bool IsMetadataOut { get { return false; } } - internal override MarshalPseudoCustomAttributeData? MarshallingInformation + internal sealed override MarshalPseudoCustomAttributeData? MarshallingInformation { get { return null; } } - internal override ImmutableArray InterpolatedStringHandlerArgumentIndexes => ImmutableArray.Empty; + internal sealed override ImmutableArray InterpolatedStringHandlerArgumentIndexes => ImmutableArray.Empty; + + internal sealed override bool HasInterpolatedStringHandlerArgumentError => false; + } + + internal sealed class ThisParameterSymbol : ThisParameterSymbolBase + { + private readonly MethodSymbol? _containingMethod; + private readonly TypeSymbol _containingType; + + internal ThisParameterSymbol(MethodSymbol forMethod) : this(forMethod, forMethod.ContainingType) + { + } + + internal ThisParameterSymbol(MethodSymbol? forMethod, TypeSymbol containingType) + { + Debug.Assert(containingType is not null); + _containingMethod = forMethod; + _containingType = containingType; + } + + public override TypeWithAnnotations TypeWithAnnotations + => TypeWithAnnotations.Create(_containingType, NullableAnnotation.NotAnnotated); - internal override bool HasInterpolatedStringHandlerArgumentError => false; + public override RefKind RefKind + { + get + { + if (ContainingType?.TypeKind != TypeKind.Struct) + { + return RefKind.None; + } + + if (_containingMethod?.MethodKind == MethodKind.Constructor) + { + return RefKind.Out; + } + + if (_containingMethod?.IsEffectivelyReadOnly == true) + { + return RefKind.In; + } + + return RefKind.Ref; + } + } + + public override ImmutableArray Locations + { + get { return _containingMethod is not null ? _containingMethod.Locations : ImmutableArray.Empty; } + } + + public override Symbol ContainingSymbol + { + get { return (Symbol?)_containingMethod ?? _containingType; } + } internal override ScopedKind EffectiveScope { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs b/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs index 7bbb48ec3c906..986c50a904636 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/TypeParameterConstraintClause.cs @@ -47,6 +47,8 @@ internal enum TypeParameterConstraintKind ValueTypeFromConstraintTypes = 0x400, // Not set if any flag from AllValueTypeKinds is set ReferenceTypeFromConstraintTypes = 0x800, + AllowByRefLike = 0x1000, + /// /// All bits involved into describing various aspects of 'class' constraint. /// @@ -60,7 +62,7 @@ internal enum TypeParameterConstraintKind /// /// All bits except those that are involved into describing various nullability aspects. /// - AllNonNullableKinds = ReferenceType | ValueType | Constructor | Unmanaged, + AllNonNullableKinds = ReferenceType | ValueType | Constructor | Unmanaged | AllowByRefLike, } /// @@ -115,8 +117,10 @@ private TypeParameterConstraintClause( } Debug.Assert((constraints & TypeParameterConstraintKind.ObliviousNullabilityIfReferenceType) == 0 || - (constraints & ~(TypeParameterConstraintKind.ObliviousNullabilityIfReferenceType | TypeParameterConstraintKind.Constructor | TypeParameterConstraintKind.Default | - TypeParameterConstraintKind.PartialMismatch | TypeParameterConstraintKind.ValueTypeFromConstraintTypes | TypeParameterConstraintKind.ReferenceTypeFromConstraintTypes)) == 0); + (constraints & ~(TypeParameterConstraintKind.ObliviousNullabilityIfReferenceType | TypeParameterConstraintKind.Constructor | + TypeParameterConstraintKind.Default | TypeParameterConstraintKind.PartialMismatch | + TypeParameterConstraintKind.ValueTypeFromConstraintTypes | TypeParameterConstraintKind.ReferenceTypeFromConstraintTypes | + TypeParameterConstraintKind.AllowByRefLike)) == 0); #endif this.Constraints = constraints; this.ConstraintTypes = constraintTypes; diff --git a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs index 2aa0d93d48f98..7c30811f783b1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs @@ -201,6 +201,7 @@ public static Symbol ConstructedFrom(this Symbol symbol) switch (symbol.Kind) { case SymbolKind.NamedType: + case SymbolKind.ErrorType: return ((NamedTypeSymbol)symbol).ConstructedFrom; case SymbolKind.Method: diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeParameterSymbol.cs index 0b35e07201ccf..0bd394ee8a6cb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/ReadOnlyListType/SynthesizedReadOnlyListTypeParameterSymbol.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; +using System.Diagnostics; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols @@ -13,6 +14,7 @@ internal sealed class SynthesizedReadOnlyListTypeParameterSymbol : TypeParameter internal SynthesizedReadOnlyListTypeParameterSymbol(SynthesizedReadOnlyListTypeSymbol containingType) { + Debug.Assert(containingType.IsClassType()); _containingType = containingType; } @@ -32,6 +34,8 @@ internal SynthesizedReadOnlyListTypeParameterSymbol(SynthesizedReadOnlyListTypeS public override bool HasValueTypeConstraint => false; + public override bool AllowsRefLikeType => false; // The list is a class type and cannot store ref structs as elements. + public override bool IsValueTypeFromConstraintTypes => false; public override bool HasUnmanagedTypeConstraint => false; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs index fb23a1599653f..12928b4b558f6 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordBaseEquals.cs @@ -30,7 +30,7 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray( new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(ContainingType.BaseTypeNoUseSiteDiagnostics, NullableAnnotation.Annotated), - ordinal: 0, RefKind.None, ScopedKind.None, "other", Locations))); + ordinal: 0, RefKind.None, "other", Locations))); } protected override int GetParameterCountFromSyntax() => 1; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs index 8df91cb09a940..e941cd6288516 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordDeconstruct.cs @@ -39,7 +39,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray( new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(ContainingType, annotation), - ordinal: 0, RefKind.None, ScopedKind.None, "left", Locations), + ordinal: 0, RefKind.None, "left", Locations), new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(ContainingType, annotation), - ordinal: 1, RefKind.None, ScopedKind.None, "right", Locations))); + ordinal: 1, RefKind.None, "right", Locations))); } protected override int GetParameterCountFromSyntax() => 2; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs index 59b03317a8b9d..8301c43f491ec 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordEquals.cs @@ -38,7 +38,7 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray( new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(ContainingType, annotation), - ordinal: 0, RefKind.None, ScopedKind.None, "other", Locations))); + ordinal: 0, RefKind.None, "other", Locations))); } protected override int GetParameterCountFromSyntax() => 1; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs index da1c56468ea0b..d19e4a53ca829 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordObjEquals.cs @@ -33,7 +33,7 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray( new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_Object, location, diagnostics), annotation), - ordinal: 0, RefKind.None, ScopedKind.None, "obj", Locations))); + ordinal: 0, RefKind.None, "obj", Locations))); } protected override int GetParameterCountFromSyntax() => 1; diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs index 4f463b0b29831..50e424981207b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/Records/SynthesizedRecordPrintMembers.cs @@ -95,7 +95,7 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray( new SourceSimpleParameterSymbol(owner: this, TypeWithAnnotations.Create(Binder.GetWellKnownType(compilation, WellKnownType.System_Text_StringBuilder, diagnostics, location), annotation), - ordinal: 0, RefKind.None, ScopedKind.None, "builder", Locations))); + ordinal: 0, RefKind.None, "builder", Locations))); } protected override int GetParameterCountFromSyntax() => 1; @@ -213,8 +213,9 @@ internal override void GenerateMethodBody(TypeCompilationState compilationState, F.WellKnownMethod(WellKnownMember.System_Text_StringBuilder__AppendString), F.Call(value, F.SpecialMethod(SpecialMember.System_Object__ToString))))); } - else + else if (!value.Type.IsRestrictedType()) { + // Otherwise, an error has been reported elsewhere (SourceMemberFieldSymbol.TypeChecks) block.Add(F.ExpressionStatement( F.Call(receiver: builder, F.WellKnownMethod(WellKnownMember.System_Text_StringBuilder__AppendObject), diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs index 9342a59c8f4b1..05dca7980687e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInlineArrayTypeSymbol.cs @@ -226,6 +226,8 @@ internal InlineArrayTypeParameterSymbol(SynthesizedInlineArrayTypeSymbol contain public override bool HasValueTypeConstraint => false; + public override bool AllowsRefLikeType => false; // Span types do not support ref like type parameters for now + public override bool IsValueTypeFromConstraintTypes => false; public override bool HasUnmanagedTypeConstraint => false; diff --git a/src/Compilers/CSharp/Portable/Symbols/SynthesizedSimpleMethodTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/SynthesizedSimpleMethodTypeParameterSymbol.cs index f466741206cd9..3b712530adae8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/SynthesizedSimpleMethodTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/SynthesizedSimpleMethodTypeParameterSymbol.cs @@ -68,6 +68,11 @@ public override bool HasValueTypeConstraint get { return false; } } + public override bool AllowsRefLikeType + { + get { return false; } + } + public override bool IsValueTypeFromConstraintTypes { get { return false; } diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs index 03558a19ff419..ccab2679def85 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeParameterSymbol.cs @@ -634,6 +634,8 @@ internal sealed override ObsoleteAttributeData ObsoleteAttributeData public abstract bool HasValueTypeConstraint { get; } + public abstract bool AllowsRefLikeType { get; } + public abstract bool IsValueTypeFromConstraintTypes { get; } public abstract bool HasUnmanagedTypeConstraint { get; } diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs index 4b875082e4b5f..5fe68d3f83887 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbol.cs @@ -1620,34 +1620,44 @@ private static void CheckForImplementationOfCorrespondingPropertyOrEvent(MethodS private static void ReportDefaultInterfaceImplementationMatchDiagnostics(Symbol interfaceMember, TypeSymbol implementingType, Symbol implicitImpl, BindingDiagnosticBag diagnostics) { - if (interfaceMember.Kind == SymbolKind.Method && implementingType.ContainingModule != implicitImpl.ContainingModule) + if (interfaceMember.Kind == SymbolKind.Method) { - // The default implementation is coming from a different module, which means that we probably didn't check - // for the required runtime capability or language version bool isStatic = implicitImpl.IsStatic; - var feature = isStatic ? MessageID.IDS_FeatureStaticAbstractMembersInInterfaces : MessageID.IDS_DefaultInterfaceImplementation; - LanguageVersion requiredVersion = feature.RequiredVersion(); - LanguageVersion? availableVersion = implementingType.DeclaringCompilation?.LanguageVersion; - if (requiredVersion > availableVersion) + if (!isStatic && implementingType.IsRefLikeType) { - diagnostics.Add(ErrorCode.ERR_LanguageVersionDoesNotSupportInterfaceImplementationForMember, + diagnostics.Add(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, GetInterfaceLocation(interfaceMember, implementingType), - implicitImpl, interfaceMember, implementingType, - feature.Localize(), - availableVersion.GetValueOrDefault().ToDisplayString(), - new CSharpRequiredLanguageVersion(requiredVersion)); + implicitImpl, interfaceMember, implementingType); } - - if (!(isStatic ? - implementingType.ContainingAssembly.RuntimeSupportsStaticAbstractMembersInInterfaces : - implementingType.ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)) + else if (implementingType.ContainingModule != implicitImpl.ContainingModule) { - diagnostics.Add(isStatic ? - ErrorCode.ERR_RuntimeDoesNotSupportStaticAbstractMembersInInterfacesForMember : - ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, - GetInterfaceLocation(interfaceMember, implementingType), - implicitImpl, interfaceMember, implementingType); + // The default implementation is coming from a different module, which means that we probably didn't check + // for the required runtime capability or language version + var feature = isStatic ? MessageID.IDS_FeatureStaticAbstractMembersInInterfaces : MessageID.IDS_DefaultInterfaceImplementation; + + LanguageVersion requiredVersion = feature.RequiredVersion(); + LanguageVersion? availableVersion = implementingType.DeclaringCompilation?.LanguageVersion; + if (requiredVersion > availableVersion) + { + diagnostics.Add(ErrorCode.ERR_LanguageVersionDoesNotSupportInterfaceImplementationForMember, + GetInterfaceLocation(interfaceMember, implementingType), + implicitImpl, interfaceMember, implementingType, + feature.Localize(), + availableVersion.GetValueOrDefault().ToDisplayString(), + new CSharpRequiredLanguageVersion(requiredVersion)); + } + + if (!(isStatic ? + implementingType.ContainingAssembly.RuntimeSupportsStaticAbstractMembersInInterfaces : + implementingType.ContainingAssembly.RuntimeSupportsDefaultInterfaceImplementation)) + { + diagnostics.Add(isStatic ? + ErrorCode.ERR_RuntimeDoesNotSupportStaticAbstractMembersInInterfacesForMember : + ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, + GetInterfaceLocation(interfaceMember, implementingType), + implicitImpl, interfaceMember, implementingType); + } } } } @@ -1885,9 +1895,21 @@ static void checkMethodOverride( if (implementingMethod.HasUnscopedRefAttributeOnMethodOrProperty()) { - diagnostics.Add( - ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, - GetImplicitImplementationDiagnosticLocation(implementedMethod, implementingType, implementingMethod)); + if (implementedMethod.HasUnscopedRefAttributeOnMethodOrProperty()) + { + if (!implementingMethod.IsExplicitInterfaceImplementation && implementingMethod is SourceMethodSymbolWithAttributes && + implementedMethod.ContainingModule != implementingMethod.ContainingModule) + { + checkRefStructInterfacesFeatureAvailabilityOnUnscopedRefAttribute(implementingMethod.HasUnscopedRefAttribute ? implementingMethod : implementingMethod.AssociatedSymbol, diagnostics); + } + } + else + { + diagnostics.Add( + ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, + GetImplicitImplementationDiagnosticLocation(implementedMethod, implementingType, implementingMethod), + implementedMethod); + } } } @@ -1951,6 +1973,21 @@ static void checkMethodOverride( } } } + + static void checkRefStructInterfacesFeatureAvailabilityOnUnscopedRefAttribute(Symbol implementingSymbol, BindingDiagnosticBag diagnostics) + { + foreach (var attributeData in implementingSymbol.GetAttributes()) + { + if (attributeData is SourceAttributeData { ApplicationSyntaxReference: { } applicationSyntaxReference } && + attributeData.IsTargetAttribute(AttributeDescription.UnscopedRefAttribute)) + { + MessageID.IDS_FeatureRefStructInterfaces.CheckFeatureAvailability(diagnostics, implementingSymbol.DeclaringCompilation, applicationSyntaxReference.GetLocation()); + return; + } + } + + Debug.Assert(false); + } } /// diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs index 0e8e38d085d93..3e95df90575a1 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs @@ -527,9 +527,14 @@ public static bool IsPossibleArrayGenericInterface(this TypeSymbol type) return false; } - internal static bool IsErrorTypeOrRefLikeType(this TypeSymbol type) + internal static bool IsErrorOrRefLikeOrAllowsRefLikeType(this TypeSymbol type) { - return type.IsErrorType() || type.IsRefLikeType; + return type.IsErrorType() || type.IsRefLikeOrAllowsRefLikeType(); + } + + internal static bool IsRefLikeOrAllowsRefLikeType(this TypeSymbol type) + { + return type is { IsRefLikeType: true } or TypeParameterSymbol { AllowsRefLikeType: true }; } private static readonly string[] s_expressionsNamespaceName = { "Expressions", "Linq", MetadataHelpers.SystemString, "" }; @@ -1386,9 +1391,7 @@ internal static bool IsRestrictedType(this TypeSymbol type, return true; } - return ignoreSpanLikeTypes ? - false : - type.IsRefLikeType; + return ignoreSpanLikeTypes ? false : type.IsRefLikeOrAllowsRefLikeType(); } public static bool IsIntrinsicType(this TypeSymbol type) diff --git a/src/Compilers/CSharp/Portable/Symbols/TypeWithAnnotations.cs b/src/Compilers/CSharp/Portable/Symbols/TypeWithAnnotations.cs index e8718c13ff302..b578c9e24164f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/TypeWithAnnotations.cs +++ b/src/Compilers/CSharp/Portable/Symbols/TypeWithAnnotations.cs @@ -278,6 +278,8 @@ public bool IsSZArray() => _extensions.IsSZArray(DefaultType); public bool IsRefLikeType() => _extensions.IsRefLikeType(DefaultType); + public bool IsRefLikeOrAllowsRefLikeType() => + _extensions.IsRefLikeOrAllowsRefLikeType(DefaultType); public bool IsStatic => _extensions.IsStatic(DefaultType); public bool IsRestrictedType(bool ignoreSpanLikeTypes = false) => @@ -865,6 +867,7 @@ internal static Extensions Create(ImmutableArray customModifiers internal abstract bool IsVoid(TypeSymbol typeSymbol); internal abstract bool IsSZArray(TypeSymbol typeSymbol); internal abstract bool IsRefLikeType(TypeSymbol typeSymbol); + internal abstract bool IsRefLikeOrAllowsRefLikeType(TypeSymbol typeSymbol); internal abstract TypeWithAnnotations WithTypeAndModifiers(TypeWithAnnotations type, TypeSymbol typeSymbol, ImmutableArray customModifiers); @@ -896,6 +899,7 @@ public NonLazyType(ImmutableArray customModifiers) internal override bool IsVoid(TypeSymbol typeSymbol) => typeSymbol.IsVoidType(); internal override bool IsSZArray(TypeSymbol typeSymbol) => typeSymbol.IsSZArray(); internal override bool IsRefLikeType(TypeSymbol typeSymbol) => typeSymbol.IsRefLikeType; + internal override bool IsRefLikeOrAllowsRefLikeType(TypeSymbol typeSymbol) => typeSymbol.IsRefLikeOrAllowsRefLikeType(); internal override TypeSymbol GetNullableUnderlyingTypeOrSelf(TypeSymbol typeSymbol) => typeSymbol.StrippedType(); @@ -968,6 +972,7 @@ public LazySubstitutedType(ImmutableArray customModifiers, TypeP internal override bool IsVoid(TypeSymbol typeSymbol) => typeSymbol.IsVoidType(); internal override bool IsSZArray(TypeSymbol typeSymbol) => typeSymbol.IsSZArray(); internal override bool IsRefLikeType(TypeSymbol typeSymbol) => typeSymbol.IsRefLikeType; + internal override bool IsRefLikeOrAllowsRefLikeType(TypeSymbol typeSymbol) => typeSymbol.IsRefLikeOrAllowsRefLikeType(); internal override NullableAnnotation GetResolvedAnnotation(NullableAnnotation defaultAnnotation) { @@ -1068,6 +1073,7 @@ public LazyNullableTypeParameter(CSharpCompilation compilation, TypeWithAnnotati internal override bool IsVoid(TypeSymbol typeSymbol) => false; internal override bool IsSZArray(TypeSymbol typeSymbol) => false; internal override bool IsRefLikeType(TypeSymbol typeSymbol) => false; + internal override bool IsRefLikeOrAllowsRefLikeType(TypeSymbol typeSymbol) => typeSymbol.IsRefLikeOrAllowsRefLikeType(); internal override bool IsStatic(TypeSymbol typeSymbol) => false; private TypeSymbol GetResolvedType() diff --git a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.cs index f1bd03a8c40ea..b394472d3e507 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.cs @@ -117,6 +117,14 @@ public override bool HasValueTypeConstraint } } + public override bool AllowsRefLikeType + { + get + { + return _underlyingTypeParameter.AllowsRefLikeType; + } + } + public override bool IsValueTypeFromConstraintTypes { get diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index d3ae1190b9c23..6dc00ef5262e5 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -3738,6 +3738,47 @@ + + + + The allows type parameter constraint clause. + + + + + + + + Gets the constraints list. + + + + + + + Base type for allow constraint syntax. + + + + + + Ref struct constraint syntax. + + + + + Gets the "ref" keyword. + + + + + + Gets the "struct" keyword. + + + + + diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs index c8d16b0633525..bd23d70560c3d 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs @@ -7,6 +7,7 @@ using System.Collections.Immutable; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading; @@ -1677,6 +1678,7 @@ public static IEnumerable ParseTokens(string text, int offset = 0, /// /// The source to parse tokens from. /// Parse options for the source. + [Experimental(RoslynExperiments.SyntaxTokenParser, UrlFormat = RoslynExperiments.SyntaxTokenParser_Url)] public static SyntaxTokenParser CreateTokenParser(SourceText sourceText, CSharpParseOptions? options = null) { return new SyntaxTokenParser(new InternalSyntax.Lexer(sourceText, options ?? CSharpParseOptions.Default)); diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs index 69c3de99c3b5a..f5c5b69c74910 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs @@ -419,6 +419,8 @@ public enum SyntaxKind : ushort ScopedKeyword = 8448, /// Represents . FileKeyword = 8449, + /// Represents . + AllowsKeyword = 8450, // when adding a contextual keyword following functions must be adapted: // @@ -526,6 +528,7 @@ public enum SyntaxKind : ushort Utf8StringLiteralToken = 8520, Utf8SingleLineRawStringLiteralToken = 8521, Utf8MultiLineRawStringLiteralToken = 8522, + RazorContentToken = 8523, // trivia EndOfLineTrivia = 8539, @@ -810,6 +813,8 @@ public enum SyntaxKind : ushort OperatorDeclaration = 8876, ConversionOperatorDeclaration = 8877, ConstructorDeclaration = 8878, + AllowsConstraintClause = 8879, + RefStructConstraint = 8880, BaseConstructorInitializer = 8889, ThisConstructorInitializer = 8890, diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs index 6a19e29e2e469..17382780cb90e 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKindFacts.cs @@ -1166,7 +1166,7 @@ public static SyntaxKind GetPreprocessorKeywordKind(string text) public static IEnumerable GetContextualKeywordKinds() { - for (int i = (int)SyntaxKind.YieldKeyword; i <= (int)SyntaxKind.FileKeyword; i++) + for (int i = (int)SyntaxKind.YieldKeyword; i <= (int)SyntaxKind.AllowsKeyword; i++) { // 8441 corresponds to a deleted kind (DataKeyword) that was previously shipped. if (i != 8441) @@ -1227,6 +1227,7 @@ public static bool IsContextualKeyword(SyntaxKind kind) case SyntaxKind.RequiredKeyword: case SyntaxKind.ScopedKeyword: case SyntaxKind.FileKeyword: + case SyntaxKind.AllowsKeyword: return true; default: return false; @@ -1352,6 +1353,8 @@ public static SyntaxKind GetContextualKeywordKind(string text) return SyntaxKind.ScopedKeyword; case "file": return SyntaxKind.FileKeyword; + case "allows": + return SyntaxKind.AllowsKeyword; default: return SyntaxKind.None; } @@ -1797,6 +1800,8 @@ public static string GetText(SyntaxKind kind) return "scoped"; case SyntaxKind.FileKeyword: return "file"; + case SyntaxKind.AllowsKeyword: + return "allows"; default: return string.Empty; } diff --git a/src/Compilers/CSharp/Portable/Syntax/SourceTextTokenParser.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxTokenParser.cs similarity index 66% rename from src/Compilers/CSharp/Portable/Syntax/SourceTextTokenParser.cs rename to src/Compilers/CSharp/Portable/Syntax/SyntaxTokenParser.cs index 8c701e1797c1d..887b31df9f759 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SourceTextTokenParser.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxTokenParser.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; using System.Threading; using InternalSyntax = Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax; @@ -20,6 +21,7 @@ namespace Microsoft.CodeAnalysis.CSharp; /// /// This type is not thread safe. /// +[Experimental(RoslynExperiments.SyntaxTokenParser, UrlFormat = RoslynExperiments.SyntaxTokenParser_Url)] public sealed class SyntaxTokenParser : IDisposable { private InternalSyntax.Lexer _lexer; @@ -54,6 +56,36 @@ public Result ParseNextToken() return new Result(new SyntaxToken(parent: null, token, startingPosition, index: 0), startingDirectiveStack); } + /// + /// Parse the leading trivia of the next token from the input at the current position. This will advance the internal position of the + /// token parser to the end of the leading trivia of the next token. The returned result will have a token with + /// of , set to , and a parent of . The + /// parsed trivia will be set as the of the token. + /// + public Result ParseLeadingTrivia() + { + var startingDirectiveStack = _lexer.Directives; + var startingPosition = _lexer.TextWindow.Position; + var leadingTrivia = _lexer.LexSyntaxLeadingTrivia(); + var containingToken = InternalSyntax.SyntaxFactory.MissingToken(leading: leadingTrivia.Node, SyntaxKind.None, trailing: null); + return new Result(new SyntaxToken(parent: null, containingToken, startingPosition, index: 0), startingDirectiveStack); + } + + /// + /// Parse syntax trivia from the current position, according to the rules of trailing syntax trivia. This will advance the internal position of the + /// token parser to the end of the trailing trivia from the current location. The returned result will have a token with + /// of , set to , and a parent of . The + /// parsed trivia will be set as the of the token. + /// + public Result ParseTrailingTrivia() + { + var startingDirectiveStack = _lexer.Directives; + var startingPosition = _lexer.TextWindow.Position; + var trailingTrivia = _lexer.LexSyntaxTrailingTrivia(); + var containingToken = InternalSyntax.SyntaxFactory.MissingToken(leading: null, SyntaxKind.None, trailing: trailingTrivia.Node); + return new Result(new SyntaxToken(parent: null, containingToken, startingPosition, index: 0), startingDirectiveStack); + } + /// /// Skip forward in the input to the specified position. Current directive state is preserved during the skip. /// diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 08aa73d9ec729..482f74b8c1b7e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -32,6 +32,11 @@ {0}: abstraktní událost nemůže používat syntaxi přístupového objektu události. + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees '&' pro skupiny metod se nedá použít ve stromech výrazů. @@ -42,6 +47,11 @@ Skupina &method {0} se nedá převést na typ ukazatele, který neukazuje na funkci ({1}). + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Pokud chcete pro interpolovaný doslovný řetězec použít @$ místo $@, použijte verzi jazyka {0} nebo vyšší. @@ -182,6 +192,11 @@ Parametr unárního operátoru musí být nadřazeného typu nebo jeho parametrem obecného typu, který se na něj omezuje. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. Argument {0} nelze předat s klíčovým slovem ref v jazykové verzi {1}. Pokud chcete argumenty ref předat parametrům in, upgradujte na verzi jazyka {2} nebo vyšší. @@ -232,6 +247,11 @@ Přístupový objekt init není platný pro statické členy. + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Neplatná možnost {0} pro /nullable. Je třeba použít disable, enable, warnings nebo annotations. @@ -267,14 +287,14 @@ Člen záznamu {0} musí být čitelná vlastnost instance nebo pole typu {1}, která se bude shodovat s pozičním parametrem {2}. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Příkaz lock pro hodnotu typu System.Threading.Lock nejde použít v asynchronních metodách nebo asynchronních výrazech lambda. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Prostředek použitého příkazu typu {0} nejde použít v asynchronních metodách ani v asynchronních výrazech lambda. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ Typ {0} není platný pro using static. Lze použít pouze třídu, strukturu, rozhraní, výčet, delegáta nebo obor názvů. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. Atribut AsyncMethodBuilder je u anonymních metod bez explicitního návratového typu zakázaný. @@ -382,11 +407,6 @@ {0} nelze převést na typ {1}, protože návratový typ se neshoduje s návratovým typem delegáta. - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Argumenty typu pro metodu {0} nelze odvodit z použití, protože je použit argument s dynamickým typem a metoda má parametr kolekce parametrů mimo pole. Zkuste argumenty typu zadat explicitně. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist nemůže mít argument předávaný pomocí in nebo out @@ -402,6 +422,11 @@ Operátor {0} vyžaduje, aby byla definována také odpovídající nezaškrtnuté verze operátoru. + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Členy s názvem Clone se v záznamech nepovolují. @@ -587,6 +612,11 @@ Pro přístupové objekty vlastnosti i indexeru {0} nelze zadat modifikátory readonly. Místo toho zadejte modifikátor readonly jenom pro vlastnost. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. Příkaz nemůže začínat na else. @@ -1497,6 +1527,11 @@ {0} musí povolovat přepisování, protože obsahující záznam není zapečetěný. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null není platný název parametru. Pokud chcete získat přístup k příjemci instanční metody, použijte jako název parametru prázdný řetězec. @@ -1742,6 +1777,11 @@ Pole ref lze deklarovat pouze ve struktuře ref. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. Levá strana přiřazení odkazu musí být parametr Ref. @@ -1802,6 +1842,16 @@ Ref vracející vlastnosti se nedá vyžadovat. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Relační vzory se nedají použít pro hodnotu Není číslo s plovoucí desetinnou čárkou. @@ -1847,6 +1897,11 @@ Typy a aliasy nemůžou mít název required. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' {0}: Cílový modul runtime nepodporuje v přepisech kovariantní typy. Typ musí být {2}, aby odpovídal přepsanému členu {1}. @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute nelze použít na implementaci rozhraní. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - Atribut UnscopedRefAttribute lze použít pouze pro metody a vlastnosti instance struktury a nelze ho použít u konstruktorů nebo členů init-only. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + Atribut UnscopedRefAttribute lze použít pouze pro metody a vlastnosti instance struktury a nelze ho použít u konstruktorů nebo členů init-only. @@ -2377,6 +2432,16 @@ parametry ref readonly + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator uvolněný operátor směny @@ -2552,6 +2617,16 @@ Modifikátor ref pro argument odpovídající parametru in je ekvivalentem in. Místo toho zvažte použití in. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. Je nutné zadat parametr atributu SizeConst. @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - Omezení new() musí být poslední zadané omezení. + The new() constraint must be the last restrictive constraint specified + Omezení new() musí být poslední zadané omezení. @@ -7907,11 +7982,6 @@ Pokud se taková třída používá jako základní třída a pokud odvozující {0}: Statické třídy nemůžou implementovat rozhraní. - - '{0}': ref structs cannot implement interfaces - {0}: Struktury REF nemůžou implementovat rozhraní. - - '{0}': static classes cannot contain user-defined operators {0}: Statické třídy nemůžou obsahovat operátory definované uživatelem. @@ -9181,11 +9251,6 @@ Blok catch() po bloku catch (System.Exception e) může zachytit výjimky, kter Parametr ref, out nebo in {0} nejde použít uvnitř anonymní metody, výrazu lambda, výrazu dotazu nebo lokální funkce. - - Unsafe code may not appear in iterators - Iterátory nesmí obsahovat nezabezpečený kód. - - Cannot yield a value in the body of a catch clause V těle klauzule catch nejde použít hodnotu získanou příkazem yield. @@ -10570,8 +10635,8 @@ Poskytněte kompilátoru nějaký způsob, jak metody rozlišit. Můžete např - 'await' cannot be used in an expression containing the type '{0}' - 'Operátor await nejde použít ve výrazu, který obsahuje typ {0}. + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'Operátor await nejde použít ve výrazu, který obsahuje typ {0}. @@ -10639,16 +10704,6 @@ Poskytněte kompilátoru nějaký způsob, jak metody rozlišit. Můžete např Modifikátor async se dá použít jenom v metodách, které mají tělo. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Parametry nebo lokální proměnné typu {0} nemůžou být deklarované v asynchronních metodách nebo asynchronních výrazech lambda. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - Výraz foreach nejde použít na enumerátorech typu {0} v asynchronních metodách nebo metodách iterátoru, protože {0} je struktura REF. - - Security attribute '{0}' cannot be applied to an Async method. Atribut zabezpečení {0} nejde použít pro metodu Async. @@ -11168,7 +11223,7 @@ Potlačení upozornění zvažte jenom v případě, když určitě nechcete če Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - Instance typu {0} nelze použít uvnitř vnořené funkce, výrazu dotazu, bloku iterátoru nebo asynchronní metody. + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Pokud chcete odstranit toto varování, můžete místo toho použít /reference Místní hodnotu odkazu {0} nejde použít uvnitř anonymní metody, výrazu lambda nebo výrazu dotazu. - - Iterators cannot have by-reference locals - Iterátory nemůžou mít lokální proměnné podle odkazu. - - - - Async methods cannot have by-reference locals - Asynchronní metody nemůžou mít lokální proměnné podle odkazu. - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Odkaz vrácený voláním funkce {0} nelze zachovat v rámci hranice await nebo yield. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 7afd5f798ca1d..458820646f0bd 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -32,6 +32,11 @@ {0}: Das abstrakte Ereignis kann die Ereignisaccessorsyntax nicht verwenden. + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees "&" für Methodengruppen kann in Ausdrucksbaumstrukturen nicht verwendet werden. @@ -42,6 +47,11 @@ Die &Methodengruppe "{0}" kann nicht in den Nicht-Funktionszeigertyp "{1}" konvertiert werden. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Um für eine interpolierte ausführliche Zeichenfolge "@$" anstelle von "$@" zu verwenden, benötigen Sie Sprachversion {0} oder höher. @@ -182,6 +192,11 @@ Ein Parameter eines unären Operators muss der enthaltende Typ sein oder sein zugehöriger Typparameter, der darauf beschränkt ist. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. Das Argument "{0}" darf nicht mit dem Schlüsselwort "ref" in der Sprachversion {1} übergeben werden. Um ref-Argumente an in-Parameter zu übergeben, führen Sie ein Upgrade auf die Sprachversion {2} oder höher durch. @@ -232,6 +247,11 @@ Die init-Zugriffsmethode ist für statische Member ungültig. + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Ungültige Option "{0}" für "/nullable". Zulässig sind nur "disable", "enable", "warnings" oder "annotations". @@ -267,14 +287,14 @@ Das Datensatzelement "{0}" muss eine lesbare Instanzeigenschaft oder ein Feld vom Typ "{1}" sein, um dem Positionsparameter "{2}" zu entsprechen. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Eine Sperranweisung für einen Wert vom Typ „System.Threading.Lock“ kann nicht in asynchronen Methoden oder asynchronen Lambdaausdrücken verwendet werden. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Eine using-Anweisungsressource vom Typ „{0}“ kann nicht in asynchronen Methoden oder asynchronen Lambdaausdrücken verwendet werden. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ Der Typ "{0}" ist für "using static" ungültig. Nur eine Klasse, Struktur, Schnittstelle, Enumeration, ein Delegat oder ein Namespace kann verwendet werden. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. Das AsyncMethodBuilder-Attribut ist für anonyme Methoden ohne expliziten Rückgabetyp unzulässig. @@ -382,11 +407,6 @@ {0} kann nicht in den Typ „{1}“ konvertiert werden, da der Rückgabetyp nicht mit dem Rückgabetyp des Delegaten übereinstimmt - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Die Typargumente für die Methode "{0}" können nicht aus der Verwendung abgeleitet werden, da ein Argument mit dynamischem Typ verwendet wird und die Methode einen nicht arraybasierten Params-Auflistungsparameter aufweist. Geben Sie die Typargumente explizit an. - - __arglist cannot have an argument passed by 'in' or 'out' "__arglist" darf kein über "in" oder "out" übergebenes Argument umfassen. @@ -402,6 +422,11 @@ Für den Operator "{0}" muss auch eine übereinstimmende nicht überprüfte Version des Operators definiert werden. + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Member mit dem Namen "Clone" sind in Datensätzen nicht zulässig. @@ -587,6 +612,11 @@ readonly-Modifizierer können nicht für beide Accessoren der Eigenschaft oder des Indexers "{0}" angegeben werden. Legen Sie stattdessen einen readonly-Modifizierer für die Eigenschaft selbst fest. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. Eine Anweisung kann nicht mit "else" beginnen. @@ -1497,6 +1527,11 @@ "{0}" muss Überschreibungen zulassen, weil der enthaltende Datensatz nicht versiegelt ist. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. NULL ist kein gültiger Parametername. Um auf den Empfänger einer Instanzmethode zuzugreifen, verwenden Sie die leere Zeichenfolge als Parameternamen. @@ -1742,6 +1777,11 @@ Ein Verweisfeld kann nur in einer Verweisstruktur deklariert werden. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. Die linke Seite einer Ref-Zuweisung muss eine Ref-Variable sein. @@ -1802,6 +1842,16 @@ Der Verweis, der Eigenschaften zurückgibt, kann nicht erfordert werden. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Relationale Muster dürfen nicht für Gleitkomma-NaNs verwendet werden. @@ -1847,6 +1897,11 @@ Typen und Aliase können nicht als "erforderlich" bezeichnet werden. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' {0}: Die Zielruntime unterstützt keine covarianten Typen in Überschreibungen. Der Typ muss "{2}" sein, um dem überschriebenen Member "{1}" zu entsprechen. @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - "UnscopedRefAttribute" kann nicht auf eine Schnittstellenimplementierung angewendet werden. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - "UnscopedRefAttribute" kann nur auf Strukturinstanzmethoden und -eigenschaften und nicht auf Konstruktoren oder init-only-Member angewendet werden. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + "UnscopedRefAttribute" kann nur auf Strukturinstanzmethoden und -eigenschaften und nicht auf Konstruktoren oder init-only-Member angewendet werden. @@ -2377,6 +2432,16 @@ ref readonly-Parameter + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator entspannter Schichtoperator @@ -2552,6 +2617,16 @@ Der ref-Modifizierer für ein Argument, das dem in-Parameter entspricht, entspricht "in". Erwägen Sie stattdessen die Verwendung von "in". + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. Der Attributparameter "SizeConst" muss angegeben werden. @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - Die new()-Einschränkung muss zuletzt angegeben werden. + The new() constraint must be the last restrictive constraint specified + Die new()-Einschränkung muss zuletzt angegeben werden. @@ -7907,11 +7982,6 @@ Wenn solch eine Klasse als Basisklasse verwendet wird und die ableitende Klasse "{0}": Statische Klassen können keine Schnittstellen implementieren. - - '{0}': ref structs cannot implement interfaces - '{0}: Referenzstrukturen können keine Schnittstellen implementieren. - - '{0}': static classes cannot contain user-defined operators "{0}": Statische Klassen können keine benutzerdefinierten Operatoren enthalten. @@ -9181,11 +9251,6 @@ Ein catch()-Block nach einem catch (System.Exception e)-Block kann nicht-CLS-Aus Der ref-, out-, oder in-Parameter "{0}" kann nicht in einer anonymen Methode, einem Lambdaausdruck, einem Abfrageausdruck oder einer lokalen Funktion verwendet werden. - - Unsafe code may not appear in iterators - Unsicherer Code wird möglicherweise nicht in Iteratoren angezeigt. - - Cannot yield a value in the body of a catch clause Mit "yield" kann im Text einer catch-Klausel kein Wert zurückgegeben werden. @@ -10570,8 +10635,8 @@ Unterstützen Sie den Compiler bei der Unterscheidung zwischen den Methoden. Daz - 'await' cannot be used in an expression containing the type '{0}' - '"await" kann nicht in einem Ausdruck verwendet werden, der den Typ "{0}" enthält + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + '"await" kann nicht in einem Ausdruck verwendet werden, der den Typ "{0}" enthält @@ -10639,16 +10704,6 @@ Unterstützen Sie den Compiler bei der Unterscheidung zwischen den Methoden. Daz Der Modifizierer "async" kann nur in Methoden verwendet werden, die über einen Textkörper verfügen. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Parameter oder lokale Variablen des Typs "{0}" können nicht in asynchronen Methoden oder in asynchronen Lambdaausdrücken deklariert werden. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - Die foreach-Anweisung kann nicht für Enumeratoren vom Typ "{0}" in asynchronen oder Iteratormethoden verwendet werden, weil "{0}" eine Referenzstruktur ist. - - Security attribute '{0}' cannot be applied to an Async method. Das Sicherheitsattribut "{0}" kann nicht auf eine Async-Methode angewendet werden. @@ -11168,7 +11223,7 @@ Sie sollten das Unterdrücken der Warnung nur in Betracht ziehen, wenn Sie siche Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - Eine Instanz des Typs "{0}" kann nicht in einer geschachtelten Funktion, einem Abfrageausdruck, einem Iteratorblock oder einer Async-Methode verwendet werden. + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Um die Warnung zu beheben, können Sie stattdessen /reference verwenden (Einbett Der lokale Verweis "{0}" kann nicht in einer anonymen Methode, einem Lambdaausdruck oder einem Abfrageausdruck verwendet werden. - - Iterators cannot have by-reference locals - Iteratoren dürfen keine lokalen by-reference-Elemente aufweisen. - - - - Async methods cannot have by-reference locals - Asynchrone Methoden dürfen keine lokalen by-reference-Elemente aufweisen. - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Ein Verweis, der von einem Aufruf von "{0}" zurückgegeben wird, kann nicht über die Grenzen "await" oder "yield" hinweg beibehalten werden. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 333531f33ebcb..de96942b43ca1 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -32,6 +32,11 @@ "{0}": un evento abstracto no puede usar la sintaxis de descriptor de acceso de eventos + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees No se puede usar "&" para los grupos de métodos en los árboles de expresión. @@ -42,6 +47,11 @@ No se puede convertir el grupo de &métodos "{0}" en un tipo de puntero "{1}" que no es de función. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Para usar "@$" en lugar de "$@" para una cadena textual interpolada, use la versión "{0}" del lenguaje o una posterior. @@ -182,6 +192,11 @@ El parámetro de un operador unario debe ser el tipo contenedor o su parámetro de tipo restringido a él. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. No se puede pasar el argumento {0} con la palabra clave "ref" en la versión de idioma {1}. Para pasar argumentos "ref" a parámetros "in", actualice a la versión de idioma {2} o superior. @@ -232,6 +247,11 @@ El descriptor de acceso "init" no es válido en miembros estáticos + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Opción no válida "{0}" para /nullable; debe ser "deshabilitar", ·"habilitar", "advertencias" o "anotaciones" @@ -267,14 +287,14 @@ El miembro de registro '{0}' debe ser una propiedad de instancia legible o un campo de tipo '{1}' para coincidir con el parámetro posicional '{2}'. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - No se puede usar una instrucción de bloqueo en un valor de tipo 'System.Threading.Lock' en métodos asincrónicos ni expresiones lambda asincrónicas. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Un recurso de instrucción using de tipo '{0}' no se puede usar en métodos asincrónicos ni expresiones lambda asincrónicas. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ El tipo '{0}' no es válido para 'using static'. Solo se puede usar una clase, estructura, interfaz, enumeración, delegado o espacio de nombres. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. El atributo AsyncMethodBuilder no se permite en métodos anónimos sin un tipo de valor devuelto explícito. @@ -382,11 +407,6 @@ No se puede convertir {0} al tipo "{1}" porque el tipo de valor devuelto no coincide con el tipo de valor devuelto delegado - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Los argumentos de tipo para el método "{0}" no se pueden inferir del uso porque se usa un argumento con tipo dinámico y el método tiene un parámetro de colección params no matriz. Intente especificar los argumentos de tipo explícitamente. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist no puede tener un argumento que se ha pasado con "in" o "out" @@ -402,6 +422,11 @@ El operador '{0}' requiere que también se defina una versión no comprobada coincidente del operador + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. No se permiten los miembros denominados "Clone" en los registros. @@ -587,6 +612,11 @@ No se pueden especificar modificadores "readonly" en ambos descriptores de acceso de la propiedad o del indizador "{0}". En su lugar, coloque un modificador "readonly" en la propiedad. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. “else” no puede iniciar una instrucción. @@ -1497,6 +1527,11 @@ "{0}" debe permitir la invalidación porque el registro contenedor no está sellado. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null no es un nombre de parámetro válido. Para obtener acceso al receptor de un método de instancia, use la cadena vacía como nombre del parámetro. @@ -1742,6 +1777,11 @@ Un campo ref solo se puede declarar en una estructura ref. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. La parte izquierda de una asignación de referencias debe ser una variable local. @@ -1802,6 +1842,16 @@ La referencia que devuelve propiedades no puede ser obligatoria. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. No se pueden usar patrones relacionales para un valor NaN de punto flotante. @@ -1847,6 +1897,11 @@ Los tipos y alias no se pueden denominar 'required'. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' "{0}": el entorno de ejecución de destino no admite los tipos de covariante en las invalidaciones. El tipo debe ser "{2}" para que coincida con el miembro "{1}" invalidado. @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute no se puede aplicar a una implementación de interfaz. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute solo se puede aplicar a propiedades y métodos de instancia de struct, y no se puede aplicar a constructores o miembros de solo inicialización. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute solo se puede aplicar a propiedades y métodos de instancia de struct, y no se puede aplicar a constructores o miembros de solo inicialización. @@ -2377,6 +2432,16 @@ parámetros ref readonly + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator operador de cambios relajado @@ -2552,6 +2617,16 @@ El modificador "ref" de un argumento correspondiente al parámetro "in" es equivalente a "in". Considere la posibilidad de usar "in" en su lugar. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. Se debe especificar el parámetro de atributo "SizeConst". @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - La restricción new() debe ser la última restricción especificada + The new() constraint must be the last restrictive constraint specified + La restricción new() debe ser la última restricción especificada @@ -7907,11 +7982,6 @@ Si se utiliza una clase de este tipo como clase base y si la clase derivada defi '{0}': las clases estáticas no pueden implementar interfaces - - '{0}': ref structs cannot implement interfaces - "{0}": las estructuras ref no pueden implementar interfaces. - - '{0}': static classes cannot contain user-defined operators '{0}': las clases estáticas no pueden contener operadores definidos por el usuario @@ -9181,11 +9251,6 @@ Un bloque catch() después de un bloque catch (System.Exception e) puede abarcar No se puede usar el parámetro ref, out o in "{0}" dentro de un método anónimo, una expresión lambda, una expresión de consulta o una función local - - Unsafe code may not appear in iterators - No puede aparecer código no seguro en iteradores - - Cannot yield a value in the body of a catch clause No se puede proporcionar ningún valor en el cuerpo de una cláusula catch @@ -10570,8 +10635,8 @@ Indique al compilador alguna forma de diferenciar los métodos. Por ejemplo, pue - 'await' cannot be used in an expression containing the type '{0}' - 'await' no se puede usar en una expresión que contenga el tipo '{0}' + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'await' no se puede usar en una expresión que contenga el tipo '{0}' @@ -10639,16 +10704,6 @@ Indique al compilador alguna forma de diferenciar los métodos. Por ejemplo, pue El modificador 'async' solo se puede usar en métodos que tengan un cuerpo. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Los parámetros o locales de tipo '{0}' no pueden declararse en expresiones lambda o métodos asincrónicos. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - La instrucción foreach no puede funcionar en enumeradores de tipo "{0}" en métodos async o iterator porque "{0}" es una estructura ref. - - Security attribute '{0}' cannot be applied to an Async method. El atributo de seguridad '{0}' no se puede aplicar a un método Async. @@ -11168,7 +11223,7 @@ Considere la posibilidad de suprimir la advertencia solo si tiene la seguridad d Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - La instancia de tipo "{0}" no se puede usar dentro de una función anidada, una expresión de consulta, un bloque iterador ni un método asincrónico. + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Para eliminar la advertencia puede usar /reference (establezca la propiedad Embe No se puede usar la variable local de tipo ref '{0}' dentro de un método anónimo, una expresión lambda o una expresión de consulta. - - Iterators cannot have by-reference locals - Los iteradores no pueden tener variables locales por referencia. - - - - Async methods cannot have by-reference locals - Los métodos asincrónicos no pueden tener variables locales por referencia. - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Una referencia devuelta por una llamada a '{0}' no se puede conservar a través del límite "await" o "yield". diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 5670acdf1bfd3..cd8e3b4571564 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -32,6 +32,11 @@ '{0}' : un événement abstrait ne peut pas utiliser une syntaxe d'accesseur d'événement + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees '&' des groupes de méthodes ne peut pas être utilisé dans les arborescences d'expression @@ -42,6 +47,11 @@ Impossible de convertir le groupe '{0}' de &method en type de pointeur non-fonction '{1}'. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Pour utiliser '@$' à la place de '$@' pour une chaîne verbatim interpolée, utilisez la version de langage '{0}' ou une version ultérieure. @@ -182,6 +192,11 @@ Le paramètre d’un opérateur unaire doit être le type conteneur ou son paramètre de type lui être contraint. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. L’argument {0} ne peut pas être passé avec le mot clé « ref » dans la version de langage {1}. Pour passer les arguments « ref » aux paramètres « in », effectuez une mise à niveau vers la version de langage {2} ou une version ultérieure. @@ -232,6 +247,11 @@ L'accesseur 'init' est non valide sur les membres statiques + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Option '{0}' non valide pour /nullable ; utilisez 'disable', 'enable', 'warnings' ou 'annotations' @@ -267,14 +287,14 @@ Le membre d'enregistrement '{0}' doit être une propriété d'instance our champ lisible de type '{1}' pour correspondre au paramètre positionnel '{2}'. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Vous ne pouvez pas utiliser une instruction lock sur une valeur de type « System.Threading.Lock » dans des méthodes asynchrones ou des expressions lambda asynchrones. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Une ressource d’instruction d’utilisation de type '{0}' ne peut pas être utilisée dans des méthodes asynchrones ou des expressions lambda asynchrones. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ Le type '{0}' n'est pas valide pour 'en utilisant statique'. Seuls une classe, une structure, une interface, une énumération, un délégué ou un espace de noms peuvent être utilisés. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. L'attribut AsyncMethodBuilder n'est pas autorisé pour les méthodes anonymes sans type de retour explicite. @@ -382,11 +407,6 @@ Impossible de convertir {0} en type « {1} », car le type de retour ne correspond pas au type de retour délégué - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Désolé... Nous ne pouvons pas déduire les arguments de type pour la méthode « {0} » à partir de l’utilisation, car un argument avec un type dynamique est utilisé et la méthode a un paramètre de collection de params non-tableau. Essayez de spécifier explicitement les arguments de type. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist ne peut pas avoir un argument passé par 'in' ou 'out' @@ -402,6 +422,11 @@ L’opérateur '{0}' nécessite également la définition d’une version correspondante non vérifiée de l’opérateur + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Les membres nommés 'Clone' ne sont pas autorisés dans les enregistrements. @@ -587,6 +612,11 @@ Impossible de spécifier des modificateurs 'readonly' sur les deux accesseurs de la propriété ou de l'indexeur '{0}'. À la place, mettez un modificateur 'readonly' sur la propriété elle-même. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. 'else' ne peut pas démarrer d'instruction. @@ -1497,6 +1527,11 @@ '{0}' doit autoriser la substitution, car l'enregistrement contenant n'est pas sealed. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null n'est pas un nom de paramètre valide. Pour avoir accès au récepteur d'une méthode d'instance, utilisez la chaîne vide comme nom de paramètre. @@ -1742,6 +1777,11 @@ Un champ de référence ne peut être déclaré que dans une sructure de référence. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. Le côté gauche d’une affectation ref doit être une variable ref. @@ -1802,6 +1842,16 @@ Impossible d’exiger une référence retournant des propriétés. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Les modèles relationnels ne peuvent pas être utilisés pour une valeur NaN à virgule flottante. @@ -1847,6 +1897,11 @@ Les types et alias ne peuvent pas être nommés « required ». + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}' : le runtime cible ne prend pas en charge les types covariants dans les substitutions. Le type doit être '{2}' pour correspondre au membre substitué '{1}' @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute ne peut pas être appliqué à une implémentation d’interface. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute peut uniquement être appliqué aux méthodes et propriétés d’instance de struct, et ne peut pas être appliqué aux constructeurs ou aux membres init uniquement. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute peut uniquement être appliqué aux méthodes et propriétés d’instance de struct, et ne peut pas être appliqué aux constructeurs ou aux membres init uniquement. @@ -2377,6 +2432,16 @@ paramètres ref readonly + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator opérateur shift souple @@ -2552,6 +2617,16 @@ Le modificateur « ref » d’un argument correspondant au paramètre « in » est équivalent à « in ». Envisagez d’utiliser « in » à la place. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. Vous devez spécifier un paramètre d’attribut « SizeConst ». @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - La contrainte new() doit être la dernière contrainte spécifiée + The new() constraint must be the last restrictive constraint specified + La contrainte new() doit être la dernière contrainte spécifiée @@ -7907,11 +7982,6 @@ Si une telle classe est utilisée en tant que classe de base et si la classe dé '{0}' : les classes static ne peuvent pas implémenter d'interfaces - - '{0}': ref structs cannot implement interfaces - '{0}' : les structs par référence ne peuvent pas implémenter d'interfaces - - '{0}': static classes cannot contain user-defined operators '{0}' : les classes static ne peuvent pas contenir d'opérateurs définis par l'utilisateur @@ -9181,11 +9251,6 @@ Un bloc catch() après un bloc catch (System.Exception e) peut intercepter des e Impossible d'utiliser le paramètre ref, out ou in '{0}' dans une méthode anonyme, une expression lambda, une expression de requête ou une fonction locale - - Unsafe code may not appear in iterators - Du code unsafe ne peut pas s'afficher dans des itérateurs - - Cannot yield a value in the body of a catch clause Impossible de générer une valeur dans le corps d'une clause catch @@ -10570,8 +10635,8 @@ Permettez au compilateur de différencier les méthodes. Par exemple, vous pouve - 'await' cannot be used in an expression containing the type '{0}' - 'await' ne peut pas être utilisé dans une expression contenant le type '{0}' + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'await' ne peut pas être utilisé dans une expression contenant le type '{0}' @@ -10639,16 +10704,6 @@ Permettez au compilateur de différencier les méthodes. Par exemple, vous pouve Le modificateur 'async' ne peut être utilisé que dans des méthodes ayant un corps. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Les paramètres ou variables locales de type '{0}' ne peuvent pas être déclarés dans des méthodes asynchrones ou des expressions asynchrones lambda. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - L'instruction foreach ne peut pas fonctionner sur les énumérateurs de type '{0}' dans les méthodes asynchrones ou les méthodes d'itérateurs, car '{0}' est un struct par référence. - - Security attribute '{0}' cannot be applied to an Async method. Impossible d'appliquer l'attribut de sécurité '{0}' à une méthode Async. @@ -11168,7 +11223,7 @@ Supprimez l'avertissement seulement si vous êtes sûr de ne pas vouloir attendr Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - Impossible d'utiliser une instance de type '{0}' dans une fonction imbriquée, une expression de requête, un bloc itérateur ou une méthode async + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Pour supprimer l'avertissement, vous pouvez utiliser la commande /reference (dé Impossible d'utiliser ref local '{0}' dans une méthode anonyme, une expression lambda ou une expression de requête - - Iterators cannot have by-reference locals - Les itérateurs ne peuvent pas avoir de variables locales par référence - - - - Async methods cannot have by-reference locals - Les méthodes async ne peuvent pas avoir de variables locales par référence - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Une référence renvoyée par un appel à '{0}' ne peut pas être conservée à travers la limite 'wait' ou 'yield'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 5ae57a81ba5f6..ee6c972ccf03d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -32,6 +32,11 @@ '{0}': l'evento astratto non può usare la sintassi della funzione di accesso agli eventi + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees Non è possibile usare '&' su gruppi di metodi in alberi delle espressioni @@ -42,6 +47,11 @@ Non è possibile convertire il gruppo di &metodi '{0}' nel tipo di puntatore non a funzione '{1}'. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Per usare '@$' invece di '$@' per una stringa verbatim interpolata, usare la versione '{0}' o versioni successive del linguaggio. @@ -182,6 +192,11 @@ I parametri di un operatore unario deve essere il tipo che lo contiene o il relativo parametro di tipo vincolato ad esso. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. Non è possibile passare l'argomento {0} con la parola chiave 'ref' nella versione del linguaggio {1}. Per passare gli argomenti 'ref' ai parametri 'in', eseguire l'aggiornamento alla versione del linguaggio {2} o versione successiva. @@ -232,6 +247,11 @@ La funzione di accesso 'init' non è valida nei membri statici + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' L'opzione '{0}' non è valida per /nullable. Deve essere 'disable', 'enable', 'warnings' o 'annotations' @@ -267,14 +287,14 @@ Il membro di record '{0}' deve essere una proprietà di istanza leggibile o campo di tipo '{1}' per corrispondere al parametro posizionale '{2}'. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Non è possibile usare un'istruzione lock in un valore di tipo 'System.Threading.Lock' nei metodi asincroni o nelle espressioni lambda asincrone. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Non è possibile usare una risorsa di istruzione using di tipo '{0}' in metodi asincroni o espressioni lambda asincrone. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ '{0}' tipo non valido per 'using static'. È possibile usare solo una classe, una struttura, un'interfaccia, un'enumerazione, un delegato o uno spazio dei nomi. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. L'attributo AsyncMethodBuilder non è consentito in metodi anonimi senza un tipo restituito esplicito. @@ -382,11 +407,6 @@ Non è possibile convertire {0} nel tipo ' {1}' perché il tipo restituito non corrisponde al tipo restituito del delegato - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Impossibile dedurre dall'utilizzo gli argomenti di tipo generico per il metodo '{0}' poiché è utilizzato un argomento con tipo dinamico e il metodo include un parametro di raccolta dei parametri non di matrice. Provare a specificare gli argomenti di tipo generico in modo esplicito. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist non può contenere un argomento passato da 'in' o 'out' @@ -402,6 +422,11 @@ L'operatore '{0}' richiede che sia definita anche una versione non controllata corrispondente dell’operatore + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Nei record non sono consentiti membri denominati 'Clone'. @@ -587,6 +612,11 @@ Non è possibile specificare i modificatori 'readonly' in entrambe le funzioni di accesso della proprietà o dell'indicizzatore '{0}'. Inserire invece un modificatore 'readonly' nella proprietà stessa. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. Un'istruzione non può iniziare con 'else'. @@ -1497,6 +1527,11 @@ '{0}' deve consentire l'override perché il record contenitore non è sealed. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. Null non è un nome di parametro valido. Per ottenere l'accesso al ricevitore di un metodo di istanza, usare la stringa vuota come nome del parametro. @@ -1742,6 +1777,11 @@ Un campo ref può essere dichiarato solo in uno struct ref. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. La parte sinistra di un'assegnazione ref deve essere una variabile ref. @@ -1802,6 +1842,16 @@ Il riferimento che restituisce le proprietà non può essere obbligatorio. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Non è possibile usare i criteri relazionali per un valore NaN a virgola mobile. @@ -1847,6 +1897,11 @@ I tipi e gli alias non possono essere denominati 'obbligatori'. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}': il runtime di destinazione non supporta tipi covarianti negli override. Il tipo deve essere '{2}' in modo da corrispondere al membro '{1}' di cui è stato eseguito l'override @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - Non è possibile applicare UnscopedRefAttribute a un'implementazione di interfaccia. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute può essere applicato solo ai metodi e alle proprietà dell'istanza di struct e non può essere applicato a costruttori o membri solo init. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute può essere applicato solo ai metodi e alle proprietà dell'istanza di struct e non può essere applicato a costruttori o membri solo init. @@ -2377,6 +2432,16 @@ parametri di sola lettura ref + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator operatore di spostamento rilassato @@ -2552,6 +2617,16 @@ Il modificatore 'ref' per un argomento corrispondente al parametro 'in' equivale a 'in'. Provare a usare 'in'. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. È necessario specificare il parametro di attributo 'SizeConst'. @@ -6609,8 +6684,8 @@ target:module Compila un modulo che può essere aggiunto ad altro - The new() constraint must be the last constraint specified - Il vincolo new() deve essere l'ultimo vincolo specificato + The new() constraint must be the last restrictive constraint specified + Il vincolo new() deve essere l'ultimo vincolo specificato @@ -7907,11 +7982,6 @@ Se si usa tale classe come classe base e se la classe di derivazione definisce u '{0}': le classi statiche non possono implementare interfacce - - '{0}': ref structs cannot implement interfaces - '{0}': gli struct ref non possono implementare interfacce - - '{0}': static classes cannot contain user-defined operators '{0}': le classi statiche non possono contenere operatori definiti dall'utente @@ -9181,11 +9251,6 @@ Un blocco catch() dopo un blocco catch (System.Exception e) può rilevare eccezi Non è possibile usare il parametro ref, out o in '{0}' all'interno di un metodo anonimo, di un'espressione lambda, di un'espressione di query o di una funzione locale - - Unsafe code may not appear in iterators - Gli iteratori non possono contenere codice unsafe - - Cannot yield a value in the body of a catch clause Impossibile produrre un valore nel corpo di una clausola catch @@ -10570,8 +10635,8 @@ Impostare il compilatore in modo tale da distinguere i metodi, ad esempio assegn - 'await' cannot be used in an expression containing the type '{0}' - 'non è possibile usare 'await' in un'espressione contenente il tipo '{0}' + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'non è possibile usare 'await' in un'espressione contenente il tipo '{0}' @@ -10639,16 +10704,6 @@ Impostare il compilatore in modo tale da distinguere i metodi, ad esempio assegn Il modificatore 'async' può essere usato solo nei metodi con un corpo. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Non è possibile dichiarare parametri o variabili locali di tipo '{0}' in metodi asincroni o espressioni lambda asincrone. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - L'istruzione foreach non può funzionare con enumeratori di tipo '{0}' in metodi async o iterator perché '{0}' è uno struct ref. - - Security attribute '{0}' cannot be applied to an Async method. Non è possibile applicare l'attributo di sicurezza '{0}' a un metodo Async @@ -11168,7 +11223,7 @@ Come procedura consigliata, è consigliabile attendere sempre la chiamata. Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - L'istanza di tipo '{0}' non può essere usata all'interno di una funzione annidata, un'espressione di query, un blocco iteratore o un metodo asincrono + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Per rimuovere l'avviso, è invece possibile usare /reference (impostare la propr Non è possibile usare la variabile locale ref '{0}' in un metodo anonimo, in un'espressione lambda o in un'espressione di query - - Iterators cannot have by-reference locals - Gli iteratori non possono includere variabili locali per riferimento - - - - Async methods cannot have by-reference locals - I metodi Async non possono includere variabili locali per riferimento - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Non è possibile mantenere un riferimento restituito da una chiamata a '{0}' oltre il limite 'await' o 'yield'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 660b612454dae..049964d81ce3a 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -32,6 +32,11 @@ '{0}': 抽象イベントはイベント アクセサーの構文を使用できません + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees メソッド グループの '&' を式ツリーで使用することはできません @@ -42,6 +47,11 @@ &method グループ '{0}' を関数以外のポインター型 '{1}' に変換することはできません。 + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 挿入される逐語的文字列で '$@' の代わりに '@$' を使用するには、言語バージョン '{0}' 以上をご使用ください。 @@ -182,6 +192,11 @@ 単項演算子のパラメーターは、それを含む型であるか、それに制約された型パラメーターである必要があります。 + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. 言語バージョン {1} では、引数 {0} を 'ref' キーワードと共に渡すことはできません。'ref' 引数を 'in' パラメーターに渡すには、言語バージョン {2} 以上にアップグレードしてください。 @@ -232,6 +247,11 @@ 静的メンバー上で 'init' アクセサーは有効ではありません + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' /nullable のオプション '{0}' が無効です。'disable'、'enable'、'warnings'、'annotations' のいずれかにする必要があります @@ -267,14 +287,14 @@ レコード メンバー '{0}' は、位置指定パラメーター '{2}' に一致させるための型 '{1}' の読み取り可能なインスタンス プロパティまたはフィールドである必要があります。 - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - 型 'System.Threading.Lock' の値に対する lock ステートメントは、非同期メソッドまたは非同期ラムダ式では使用できません。 + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - 型 '{0}' の using ステートメント リソースは、非同期メソッドまたは非同期ラムダ式では使用できません。 + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ '{0}' 型は 'using static' では無効です。使用できるのは、クラス、構造体、インターフェイス、列挙型、デリゲート、名前空間のみです。 + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. AsyncMethodBuilder 属性は、明示的な戻り値の型のない匿名メソッドでは許可されていません。 @@ -382,11 +407,6 @@ 戻り値の型がデリゲート戻り値の型と一致しないため、{0} を型 '{1}' に変換できません - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - メソッド '{0}' の型引数を使用法から推論できません。これは動的型のある引数が使用され、メソッドに配列以外の params コレクション パラメーターがあるためです。型引数を明示的に指定してみてください。 - - __arglist cannot have an argument passed by 'in' or 'out' __arglist では、'in' や 'out' で引数を渡すことができません @@ -402,6 +422,11 @@ 演算子 '{0}' を定義するには、チェックされていないバージョンの合致する演算子が必要です + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. 'Clone' という名前のメンバーはレコードでは許可されていません。 @@ -587,6 +612,11 @@ プロパティまたはインデクサー '{0}' の両方のアクセサーで 'readonly' 修飾子を指定することはできません。代わりに、プロパティ自体に 'readonly' 修飾子を指定してください。 + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. 'else' でステートメントを開始することはできません。 @@ -1497,6 +1527,11 @@ '{0}' ではオーバーライドを許可する必要があります。これが含まれているレコードが sealed ではないためです。 + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null は有効なパラメーター名ではありません。インスタンス メソッドのレシーバーへのアクセスを取得するには、パラメーター名として空の文字列を使用します。 @@ -1742,6 +1777,11 @@ ref フィールドは ref 構造体でのみ宣言できます。 + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. ref 代入の左辺は ref 変数である必要があります。 @@ -1802,6 +1842,16 @@ プロパティを返す参照は必要ありません。 + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. リレーショナル パターンは、浮動小数点の NaN に使用することはできません。 @@ -1847,6 +1897,11 @@ 型とエイリアスに 'required' という名前を付けることはできません。 + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}': ターゲットのランタイムはオーバーライドで covariant 型をサポートしていません。型は、オーバーライドされるメンバー '{1}' と一致する '{2}' にする必要があります @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute をインターフェイスの実装に適用することはできません。 + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute は構造体インスタンスのメソッドとプロパティにのみ適用でき、コンストラクターまたは init のみのメンバーには適用できません。 + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute は構造体インスタンスのメソッドとプロパティにのみ適用でき、コンストラクターまたは init のみのメンバーには適用できません。 @@ -2377,6 +2432,16 @@ ref readonly パラメーター + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator 緩和されたシフト演算子 @@ -2552,6 +2617,16 @@ 'in' パラメーターに対応する引数の 'ref' 修飾子は 'in' と同じです。代わりに 'in' を使用することを検討してください。 + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. 属性パラメーター 'SizeConst' を指定する必要があります。 @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - new() 制約は最後に指定する制約でなければなりません + The new() constraint must be the last restrictive constraint specified + new() 制約は最後に指定する制約でなければなりません @@ -7907,11 +7982,6 @@ If such a class is used as a base class and if the deriving class defines a dest '{0}': 静的クラスはインターフェイスを実装することができません - - '{0}': ref structs cannot implement interfaces - '{0}': ref 構造体はインターフェイスを実装できません - - '{0}': static classes cannot contain user-defined operators '{0}': 静的クラスにユーザー定義の演算子を含めることはできません @@ -9181,11 +9251,6 @@ AssemblyInfo.cs ファイルで RuntimeCompatibilityAttribute が false に設 ref、out、in パラメーター '{0}' は、匿名メソッド、ラムダ式、クエリ式、ローカル関数の内部では使用できません - - Unsafe code may not appear in iterators - アンセーフ コードは反復子には記述できません - - Cannot yield a value in the body of a catch clause catch 句の本体で値を生成することはできません @@ -10570,8 +10635,8 @@ C# では out と ref を区別しますが、CLR では同じと認識します - 'await' cannot be used in an expression containing the type '{0}' - 'await' は、型 '{0}' を含む式では使用できません + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'await' は、型 '{0}' を含む式では使用できません @@ -10639,16 +10704,6 @@ C# では out と ref を区別しますが、CLR では同じと認識します async' 修飾子は、本体があるメソッドでのみ使用できます。 - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - '{0}' 型のパラメーターまたはローカルは、非同期メソッドまたは非同期ラムダ式で宣言することができません。 - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - '{0}' は ref 構造体であるため、非同期または反復子のメソッド内で型 '{0}' の列挙子に対して foreach ステートメントは機能しません。 - - Security attribute '{0}' cannot be applied to an Async method. セキュリティ属性 '{0}' を非同期メソッドに適用することはできません。 @@ -11168,7 +11223,7 @@ You should consider suppressing the warning only if you're sure that you don't w Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - 型 '{0}' のインスタンスは、入れ子になった関数、クエリ式、反復子ブロック、または非同期メソッドの中では使用できません + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 匿名メソッド、ラムダ式、クエリ式内で ref ローカル変数 '{0}' は使用できません - - Iterators cannot have by-reference locals - 反復子は参照渡しのローカル変数を持つことができません - - - - Async methods cannot have by-reference locals - 非同期メソッドは参照渡しのローカル変数を持つことができません - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. '{0}' への呼び出しによって返された参照は、'await' または 'yield' 境界を越えて保持することはできません。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 4dcbb46c1279f..dd8ef848b9a66 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -32,6 +32,11 @@ '{0}': 추상 이벤트는 이벤트 접근자 구문을 사용할 수 없습니다. + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees 식 트리에서는 메서드 그룹에 '&'를 사용할 수 없습니다. @@ -42,6 +47,11 @@ 메서드 그룹 '{0}'을(를) 비함수 포인터 형식 '{1}'(으)로 변환할 수 없습니다(&M). + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 보간된 축자 문자열에 '$@' 대신 '@$'를 사용하려면 언어 버전 '{0}' 이상을 사용하세요. @@ -182,6 +192,11 @@ 단항 연산자의 매개 변수는 포함하는 유형이거나 이에 제한되는 유형 매개 변수여야 합니다. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. {0} 인수는 언어 버전 {1}의 'ref' 키워드와 함께 전달될 수 없습니다. 'ref' 인수를 'in' 매개 변수에 전달하려면 언어 버전 {2} 이상으로 업그레이드하세요. @@ -232,6 +247,11 @@ 'init' 접근자는 정적 멤버에 사용할 수 없습니다. + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' /nullable의 '{0}' 옵션이 잘못되었습니다. 'disable', 'enable', 'warnings' 또는 'annotations'여야 합니다. @@ -267,14 +287,14 @@ 위치 매개 변수 '{0}'과(와) 일치하려면 레코드 멤버 '{1}'이(가) 유형 '{2}'의 읽을 수 있는 인스턴스 속성 또는 필드여야 합니다. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - 'System.Threading.Lock' 형식의 값에 대한 lock 문은 비동기 메서드 또는 비동기 람다 식에서 사용할 수 없습니다. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - '{0}' 형식의 using 문 리소스는 비동기 메서드 또는 비동기 람다 식에 사용할 수 없습니다. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ '{0}' 유형은 '정적 사용'에 유효하지 않습니다. 클래스, 구조체, 인터페이스, 열거형, 대리자 또는 네임스페이스만 사용할 수 있습니다. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. AsyncMethodBuilder 특성은 명시적 반환 형식이 없는 익명 메서드에서 허용되지 않습니다. @@ -382,11 +407,6 @@ 반환 형식이 대리자 반환 형식과 일치하지 않기 때문에 {0}을(를) '{1}' 형식으로 변환할 수 없습니다. - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - 동적 형식을 가진 인수가 사용되고 메서드에 배열 매개 변수가 아닌 params 컬렉션 매개 변수가 있으므로 메서드 '{0}' 형식 인수를 사용법에서 유추할 수 없습니다. 형식 인수를 명시적으로 지정해 보세요. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist는 'in' 또는 'out'으로 전달되는 인수를 가질 수 없습니다. @@ -402,6 +422,11 @@ 연산자 '{0}'에는 일치하는 확인되지 않은 버전의 연산자도 정의해야 합니다. + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. 'Clone'이라는 멤버는 레코드에서 허용되지 않습니다. @@ -587,6 +612,11 @@ '{0}' 속성 또는 인덱서의 두 접근자에 'readonly' 한정자를 지정할 수 없습니다. 대신 속성 자체에 'readonly' 한정자를 지정하세요. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. 'else'로 문을 시작할 수 없습니다. @@ -1497,6 +1527,11 @@ 포함된 레코드가 봉인되지 않았으므로 '{0}'은(는) 재정의를 허용해야 합니다. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null은 유효한 매개 변수 이름이 아닙니다. 인스턴스 메소드의 수신자에 액세스하려면 빈 문자열을 매개 변수 이름으로 사용하세요. @@ -1742,6 +1777,11 @@ ref 필드는 ref 구조체에서만 선언할 수 있습니다. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. ref 할당의 왼쪽은 ref 변수여야 합니다. @@ -1802,6 +1842,16 @@ 참조 반환 속성은 필요하지 않습니다. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. 부동 소수점 NaN에는 관계형 패턴을 사용할 수 없습니다. @@ -1847,6 +1897,11 @@ 유형 및 별칭은 '필수'로 지정할 수 없습니다. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}': 대상 런타임이 재정의에서 공변(covariant) 형식을 지원하지 않습니다. 재정의된 멤버 '{1}'과(와) 일치하려면 '{2}' 형식이어야 합니다. @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute는 인터페이스 구현에 적용할 수 없습니다. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute는 구조체 인스턴스 메서드 및 속성에만 적용할 수 있으며 생성자 또는 초기화 전용 멤버에는 적용할 수 없습니다. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute는 구조체 인스턴스 메서드 및 속성에만 적용할 수 있으며 생성자 또는 초기화 전용 멤버에는 적용할 수 없습니다. @@ -2377,6 +2432,16 @@ ref readonly 매개 변수 + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator 완화된 시프트 연산자 @@ -2552,6 +2617,16 @@ 'in' 매개 변수에 해당하는 인수의 'ref' 한정자는 'in'에 해당합니다. 대신 'in'을 사용하는 것이 좋습니다. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. 특성 매개 변수 'SizeConst'를 지정해야 합니다. @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - new() 제약 조건은 마지막에 지정해야 합니다. + The new() constraint must be the last restrictive constraint specified + new() 제약 조건은 마지막에 지정해야 합니다. @@ -7907,11 +7982,6 @@ If such a class is used as a base class and if the deriving class defines a dest '{0}': 정적 클래스는 인터페이스를 구현할 수 없습니다. - - '{0}': ref structs cannot implement interfaces - '{0}': ref struct에서 인터페이스를 구현할 수 없습니다. - - '{0}': static classes cannot contain user-defined operators '{0}': 정적 클래스는 사용자 정의 연산자를 포함할 수 없습니다. @@ -9181,11 +9251,6 @@ catch (System.Exception e) 블록 뒤의 catch() 블록은 RuntimeCompatibilityA 무명 메서드, 람다 식, 쿼리 식 또는 로컬 함수 안에서는 ref, out 또는 in 매개 변수 '{0}'을(를) 사용할 수 없습니다. - - Unsafe code may not appear in iterators - 반복기에는 안전하지 않은 코드를 사용할 수 없습니다. - - Cannot yield a value in the body of a catch clause catch 절 본문에서는 값을 생성할 수 없습니다. @@ -10570,8 +10635,8 @@ C#에서는 out과 ref를 구분하지만 CLR에서는 동일한 것으로 간 - 'await' cannot be used in an expression containing the type '{0}' - 'await'는 '{0}' 형식이 포함된 식에 사용할 수 없습니다. + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'await'는 '{0}' 형식이 포함된 식에 사용할 수 없습니다. @@ -10639,16 +10704,6 @@ C#에서는 out과 ref를 구분하지만 CLR에서는 동일한 것으로 간 async' 한정자는 본문이 있는 메서드에서만 사용할 수 있습니다. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - '{0}' 형식의 매개 변수 또는 로컬은 비동기 메서드나 비동기 람다 식에서 선언할 수 없습니다. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - '{0}'은(는) ref struct이므로 비동기 또는 반복기 메서드의 '{0}' 형식 열거자에서 foreach 문을 수행할 수 없습니다. - - Security attribute '{0}' cannot be applied to an Async method. '{0}' 보안 특성은 비동기 메서드에 적용할 수 없습니다. @@ -11168,7 +11223,7 @@ You should consider suppressing the warning only if you're sure that you don't w Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - '{0}' 형식의 인스턴스는 중첩된 함수, 쿼리 식, 반복기 블록 또는 비동기 메서드 내에서 사용할 수 없습니다. + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 무명 메서드, 람다 식 또는 쿼리 식에는 참조 로컬 '{0}'을(를) 사용할 수 없습니다. - - Iterators cannot have by-reference locals - 반복기에 by-reference 로컬을 사용할 수 없습니다. - - - - Async methods cannot have by-reference locals - 비동기 메서드에 by-reference 로컬을 사용할 수 없습니다. - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. '{0}'에 대한 호출로 반환된 참조는 'await' 또는 'yield' 경계에서 보존할 수 없습니다. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 15e03b63e52c2..871593fc5cad5 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -32,6 +32,11 @@ „{0}”: zdarzenie abstrakcyjne nie może używać składni metody dostępu zdarzenia + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees Znak „&” dla grup metod nie może być używany w drzewach wyrażeń @@ -42,6 +47,11 @@ Nie można przekonwertować grupy &metod „{0}” na typ wskaźnikowy elementu innego niż funkcja „{1}”. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Aby użyć elementu „@$” zamiast elementu „$@” w interpolowanym ciągu dosłownym, użyj wersji języka „{0}” lub nowszej. @@ -182,6 +192,11 @@ Parametr operatora jednoargumentowego musi być typem zawierającym lub jest on parametrem typu ograniczonym do niego. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. Argument {0} nie może być przekazywany ze słowem kluczowym „ref” w wersji językowej {1}. Aby przekazać argumenty „ref” do parametrów „in”, uaktualnij do wersji językowej {2} lub nowszej. @@ -232,6 +247,11 @@ Metoda dostępu „init” jest nieprawidłowa w składowych statycznych + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Nieprawidłowa opcja „{0}” dla parametru /nullable; należy użyć opcji „disable”, „enable”, „warnings” lub „annotations” @@ -267,14 +287,14 @@ Składowa rekordu "{0}" musi być możliwą do odczytu właściwością wystąpienia typu "{1}", aby dopasować parametr pozycyjny "{2}". - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Instrukcja blokady na wartości typu „System.Threading.Lock” nie może być używana w metodach asynchronicznych lub asynchronicznych wyrażeniach lambda. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Zasobu instrukcji przy użyciu typu '{0}' nie można używać w metodach asynchronicznych ani asynchronicznych wyrażeniach lambda. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ Typ „{0}” jest nieprawidłowy dla „using static”. Można używać tylko klasy, struktury, interfejsu, wyliczenia, delegata lub przestrzeni nazw. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. Atrybut AsyncMethodBuilder jest niedozwolony w metodach anonimowych bez jawnego zwracanego typu. @@ -382,11 +407,6 @@ Nie można przekonwertować {0} na typ "{1}", ponieważ zwracany typ jest niezgodny ze zwracanym typem delegowania - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Argumenty typu dla metody „{0}” nie mogą być wywnioskowane z użycia, ponieważ używany jest argument typu dynamicznego, a metoda ma parametr kolekcji params inny niż tablica. Spróbuj jawnie określić argumenty typu. - - __arglist cannot have an argument passed by 'in' or 'out' Element __arglist nie może mieć argumentu przekazywanego przez parametr „in” ani „out” @@ -402,6 +422,11 @@ Operator „{0}” wymaga, aby była zdefiniowana również pasująca niesprawdzona wersja operatora + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Składowe o nazwie „Clone” są niedozwolone w rekordach. @@ -587,6 +612,11 @@ Nie można określić modyfikatorów „readonly” dla obu metod dostępu właściwości lub indeksatora „{0}”. Zamiast tego dodaj modyfikator „readonly” do samej właściwości. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. Instrukcja nie może rozpoczynać się od elementu „else”. @@ -1497,6 +1527,11 @@ Element „{0}” musi zezwalać na przesłanianie, ponieważ zawierający go rekord nie jest zapieczętowany. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. Wartość null nie jest prawidłową nazwą parametru. Aby uzyskać dostęp do odbiorcy metody wystąpienia, użyj pustego ciągu jako nazwy parametru. @@ -1742,6 +1777,11 @@ Pole referencyjne można zadeklarować tylko w strukturze referencyjnej. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. Lewa strona przypisania referencyjnego musi być zmienną referencyjną. @@ -1802,6 +1842,16 @@ Odwołanie zwracające właściwości nie może być wymagane. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Wzorców relacyjnych nie można używać na potrzeby zmiennoprzecinkowej wartości NaN. @@ -1847,6 +1897,11 @@ Typy i aliasy nie mogą mieć nazwy „required”. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' „{0}”: docelowe środowisko uruchomieniowe nie obsługuje typów kowariantnych w przesłonięciach. Typem musi być „{2}”, aby zachować zgodność z przesłoniętą składową „{1}”. @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - Nie można zastosować atrybutu UnscopedRefAttribute do implementacji interfejsu. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - Atrybut UnscopedRefAttribute można stosować tylko do metod i właściwości wystąpienia struktury i nie można go stosować do konstruktorów ani składowych tylko do inicjowania. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + Atrybut UnscopedRefAttribute można stosować tylko do metod i właściwości wystąpienia struktury i nie można go stosować do konstruktorów ani składowych tylko do inicjowania. @@ -2377,6 +2432,16 @@ parametry tylko do odczytu ref + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator operator swobodnej zmiany @@ -2552,6 +2617,16 @@ Modyfikator „ref” dla argumentu odpowiadającego parametrowi „in” jest równoważny parametrowi „in”. Zamiast tego rozważ użycie parametru „in”. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. Należy określić parametr atrybutu „SizeConst”. @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - Ograniczenie new() musi być ostatnim określonym ograniczeniem + The new() constraint must be the last restrictive constraint specified + Ograniczenie new() musi być ostatnim określonym ograniczeniem @@ -7907,11 +7982,6 @@ Jeśli taka klasa zostanie użyta jako klasa bazowa i klasa pochodna definiuje d „{0}”: klasy statyczne nie mogą implementować interfejsów - - '{0}': ref structs cannot implement interfaces - „{0}”: Struktury ref nie mogą implementować interfejsów - - '{0}': static classes cannot contain user-defined operators „{0}”: klasy statyczne nie mogą zawierać operatorów zdefiniowanych przez użytkownika @@ -9181,11 +9251,6 @@ Blok catch() po bloku catch (System.Exception e) może przechwytywać wyjątki n Nie można użyć parametru ref, out ani in „{0}” wewnątrz metody anonimowej, wyrażenia lambda, wyrażenia zapytania lub funkcji lokalnej - - Unsafe code may not appear in iterators - Niebezpieczny kod nie może występować w iteratorach. - - Cannot yield a value in the body of a catch clause Nie można użyć instrukcji yield z wartością w treści klauzuli catch. @@ -10570,8 +10635,8 @@ Musisz umożliwić kompilatorowi rozróżnienie metod. Możesz na przykład nada - 'await' cannot be used in an expression containing the type '{0}' - 'Operatora „await” nie można użyć w wyrażeniu zawierającym typ „{0}” + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'Operatora „await” nie można użyć w wyrażeniu zawierającym typ „{0}” @@ -10639,16 +10704,6 @@ Musisz umożliwić kompilatorowi rozróżnienie metod. Możesz na przykład nada Modyfikatora „async” można używać tylko w metodach mających treść. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Parametrów ani elementów lokalnych typu „{0}” nie można deklarować w metodach asynchronicznych ani wyrażeniach lambda. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - Instrukcja foreach nie może działać na modułach wyliczających typu „{0}” w metodach asynchronicznych lub iteratora, ponieważ element „{0}” jest strukturą ref. - - Security attribute '{0}' cannot be applied to an Async method. Atrybutu zabezpieczeń „{0}” nie można zastosować dla metody asynchronicznej. @@ -11168,7 +11223,7 @@ Pominięcie ostrzeżenia należy wziąć pod uwagę tylko w sytuacji, gdy na pew Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - Wystąpienia typu „{0}” nie można użyć wewnątrz funkcji zagnieżdżonej, wyrażenia zapytania, bloku iteratora ani metody asynchronicznej + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Aby usunąć ostrzeżenie, możesz zamiast tego użyć opcji /reference (ustaw w Nie można użyć zmiennej lokalnej typu ref „{0}” wewnątrz metody anonimowej, wyrażenia lambda ani wyrażenia zapytania - - Iterators cannot have by-reference locals - Iteratory nie mogą mieć zmiennych lokalnych dostępnych przez odwołanie - - - - Async methods cannot have by-reference locals - Metody asynchroniczne nie mogą mieć zmiennych lokalnych dostępnych przez odwołanie - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Odwołanie zwrócone przez wywołanie „{0}” nie może zostać zachowane w granicach „await” lub „yield”. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index 94452e162657f..a4f21ff34b491 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -32,6 +32,11 @@ '{0}': o evento abstrato não pode usar a sintaxe do acessador de eventos + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees '&' nos grupos de métodos não pode ser usado em árvores de expressão @@ -42,6 +47,11 @@ Não é possível converter o grupo de &métodos '{0}' no tipo de ponteiro que não é de função '{1}'. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Para usar '@$' em vez de '$@' em uma cadeia de caracteres verbatim interpolada, use a versão de linguagem {0} ou superior. @@ -182,6 +192,11 @@ O parâmetro de um operador unário deve ser do tipo recipiente ou seu parâmetro de tipo restrito a ele. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. O argumento {0} não pode ser passado com o palavra-chave 'ref' na versão {1} da linguagem. Para passar argumentos 'ref' para parâmetros 'in', atualize para a versão {2} ou superior da linguagem. @@ -232,6 +247,11 @@ O acessador 'init' não é válido em membros estáticos + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Opção inválida '{0}' para /nullable; precisa ser 'disable', 'enable', 'safeonly', 'warnings' ou 'safeonlywarnings' @@ -267,14 +287,14 @@ O membro do registro '{0}' precisa ser uma propriedade de instância legível ou campo do tipo '{1}' para corresponder ao parâmetro posicional '{2}'. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Uma instrução lock em um valor do tipo "System.Threading.Lock" não pode ser usada em métodos assíncronos ou em expressões lambda assíncronas. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Um recurso de instrução using do tipo "{0}" não pode ser usado em métodos assíncronos ou expressões lambda assíncronas. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ '{0}' tipo não é válido para 'using static'. Somente uma classe, struct, interface, enumeração, delegado ou namespace podem ser usados. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. O atributo AsyncMethodBuilder não é permitido em métodos anônimos sem um tipo de retorno explícito. @@ -382,11 +407,6 @@ Não é possível converter {0} para o tipo '{1}' porque o tipo de retorno não corresponde ao tipo de retorno delegado - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Os argumentos de tipo para o método '{0}' não podem ser inferidos a partir do uso porque um argumento com tipo dinâmico é usado e o método tem um parâmetro de coleção de params que não é uma matriz. Tente especificar explicitamente os argumentos de tipo. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist não pode ter um argumento passado por 'in' ou 'out' @@ -402,6 +422,11 @@ O operador "{0}" requer que uma versão correspondente não verificada do operador para também ser definido + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Os membros chamados 'Clone' não são permitidos nos registros. @@ -587,6 +612,11 @@ Não é possível especificar modificadores 'readonly' em ambos os acessadores de propriedade ou de indexador '{0}'. Nesse caso, coloque um modificador 'readonly' na própria propriedade. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. 'else' não pode iniciar uma instrução. @@ -1497,6 +1527,11 @@ '{0}' precisa permitir a substituição porque o registro contentor não está selado. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null não é um nome de parâmetro válido. Para obter acesso ao receptor de um método de instância, use a cadeia de caracteres vazia como o nome do parâmetro. @@ -1742,6 +1777,11 @@ Um campo ref só pode ser declarado em uma estrutura ref. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. O lado esquerdo de uma atribuição ref deve ser uma variável ref. @@ -1802,6 +1842,16 @@ Não se pode exigir a devolução de propriedades de referência. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Os padrões relacionais não podem ser usados para um NaN de ponto flutuante. @@ -1847,6 +1897,11 @@ Tipos e pseudônimos não podem ser nomeados 'requeridos'. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}': o runtime de destino não dá suporte a tipos covariantes em substituições. O tipo precisa ser '{2}' para corresponder ao membro substituído '{1}' @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute não pode ser aplicado a uma implementação de interface. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute só pode ser aplicado a métodos e propriedades de instância struct e não pode ser aplicado a construtores ou membros somente init. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute só pode ser aplicado a métodos e propriedades de instância struct e não pode ser aplicado a construtores ou membros somente init. @@ -2377,6 +2432,16 @@ parâmetros ref readonly + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator operador de deslocamento flexível @@ -2552,6 +2617,16 @@ O modificador 'ref' do argumento correspondente ao parâmetro 'in' é equivalente a 'in'. Considere usar 'in' em vez disso. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. O parâmetro de atribuição 'SizeConst' deve ser especificado. @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - A restrição new() deve ser a última especificada + The new() constraint must be the last restrictive constraint specified + A restrição new() deve ser a última especificada @@ -7907,11 +7982,6 @@ Se tal classe for usada como uma classe base e se a classe derivada definir um d "{0}": classes static não podem implementar interfaces - - '{0}': ref structs cannot implement interfaces - '{0}': structs de referência não podem implementar interfaces - - '{0}': static classes cannot contain user-defined operators "{0}": classes static não podem conter operadores definidos pelo usuário @@ -9181,11 +9251,6 @@ Um bloco catch() depois de um bloco catch (System.Exception e) poderá capturar Não é possível usar os parâmetro ref, out ou in '{0}' dentro de um método anônimo, de uma expressão lambda de uma expressão de consulta ou de uma função local - - Unsafe code may not appear in iterators - Código sem segurança só pode aparecer em iteradores - - Cannot yield a value in the body of a catch clause Não é possível usar a instrução yield no corpo de uma cláusula catch @@ -10570,8 +10635,8 @@ Forneça ao compilador alguma forma de diferenciar os métodos. Por exemplo, voc - 'await' cannot be used in an expression containing the type '{0}' - 'aguardar' não pode ser usado em uma expressão que contém o tipo '{0}' + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'aguardar' não pode ser usado em uma expressão que contém o tipo '{0}' @@ -10639,16 +10704,6 @@ Forneça ao compilador alguma forma de diferenciar os métodos. Por exemplo, voc O modificador 'async' só pode ser usado em métodos que têm um corpo. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Os parâmetros ou locais do tipo '{0}' não podem ser declarados nos métodos async ou expressões async lambda. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - a instrução foreach não pode operar em enumeradores do tipo '{0}' em métodos assíncronos ou iteradores porque '{0}' é uma struct de referência. - - Security attribute '{0}' cannot be applied to an Async method. Atributo de segurança "{0}" não pode ser aplicado a um método Assíncrono. @@ -11168,7 +11223,7 @@ Você pode suprimir o aviso se tiver certeza de que não vai querer aguardar a c Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - A instância do tipo '{0}' não pode ser usada dentro de uma função aninhada, expressão de consulta, bloco de iteradores ou método assíncrono + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Para incorporar informações de tipo de interoperabilidade para os dois assembl Não é possível usar a referência local '{0}' em um método anônimo, expressão lambda ou expressão de consulta - - Iterators cannot have by-reference locals - Os iteradores não podem ter locais por referência - - - - Async methods cannot have by-reference locals - Os métodos assíncronos não podem ter locais por referência - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Uma referência retornada por uma chamada para '{0}' não pode ser preservada no limite 'await' ou 'yield'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 695213d92f5f9..7bc750767181d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -32,6 +32,11 @@ "{0}": абстрактное событие не может использовать синтаксис метода доступа к событиям. + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees "&" в группах методов не может использоваться в деревьях выражений @@ -42,6 +47,11 @@ Невозможно преобразовать тип группы &методов "{0}" в указатель не на функцию "{1}". + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. Чтобы применять "@$" вместо "$@" для интерполированной буквальной строки, следует использовать версию языка "{0}" или более позднюю. @@ -182,6 +192,11 @@ Параметр унарного оператора должен быть содержащим типом, или параметр его типа должен ограничиваться только этим параметром. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. Аргумент {0} не может передаваться с ключевым словом "ref" в языке версии {1}. Чтобы передать аргументы "ref" в параметры "in", повысьте статус до языка версии {2} или более поздней. @@ -232,6 +247,11 @@ Метод доступа "init" не может использоваться для статических элементов. + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' Недопустимый параметр "{0}" для /nullable. Допустимые значения: "disable", "enable", "warnings" или "annotations" @@ -267,14 +287,14 @@ Элемент записи "{0}" должен быть доступным для чтения свойством экземпляра или полем типа "{1}", чтобы соответствовать позиционному параметру "{2}". - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - Оператор блокировки над значением типа "System.Threading.Lock" нельзя использовать в асинхронных методах и в асинхронных лямбда-выражениях. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - Ресурс оператора использования типа "{0}" нельзя применять в асинхронных методах или асинхронных лямбда-выражениях. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ ' {0} ' недопустим для 'использования статики'. Можно использовать только класс, структуру, интерфейс, перечисление, делегат или пространство имен. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. Атрибут AsyncMethodBuilder запрещен для анонимных методов без явного типа возвращаемого значения. @@ -382,11 +407,6 @@ Невозможно преобразовать {0} в тип "{1}", поскольку возвращаемый тип не совпадает с возвращаемым типом делегата - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Аргументы типа для метода "{0}" не могут быть выведены из использования, поскольку используется аргумент с динамическим типом и метод имеет параметр коллекции params, не являющийся массивом. Попробуйте явно указать аргументы типа. - - __arglist cannot have an argument passed by 'in' or 'out' В __arglist невозможно передать аргумент с помощью in или out @@ -402,6 +422,11 @@ Для оператора "{0}" требуется, чтобы была определена соответствующая непроверенная версия этого оператора + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. Элементы с именем "Clone" не могут использоваться в записях. @@ -587,6 +612,11 @@ Запрещено указывать модификаторы readonly для обоих методов доступа свойства или индексатора "{0}". Вместо этого укажите модификатор readonly для самого свойства. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. "else" не может запускать оператор. @@ -1497,6 +1527,11 @@ "{0}" должен допускать переопределение, поскольку содержащая его запись не является запечатанной. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. "Null" не является допустимым именем параметра. Для получения доступа к приемнику метода экземпляра используйте пустую строку в качестве имени параметра. @@ -1742,6 +1777,11 @@ Поле ссылки может быть объявлено только в структуре ссылки. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. Левая сторона назначения ref должна быть переменной ref. @@ -1802,6 +1842,16 @@ Возвращаемые свойства ссылки не могут быть обязательными. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. Реляционные шаблоны не могут использоваться для NaN с плавающей запятой. @@ -1847,6 +1897,11 @@ У типов и псевдонимов не может быть имя "required". + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' "{0}": целевая среда выполнения не поддерживает ковариантные типы в переопределениях. Для сопоставления переопределенного элемента "{1}" необходимо использовать тип "{2}". @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute не может применяться к реализации интерфейса. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute может применяться только к методам и свойствам экземпляров структуры и не может применяться к конструкторам или элементам только для инициализации. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute может применяться только к методам и свойствам экземпляров структуры и не может применяться к конструкторам или элементам только для инициализации. @@ -2377,6 +2432,16 @@ Параметры ref, доступные только для чтения + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator нестрогий оператор сдвига @@ -2552,6 +2617,16 @@ Модификатор "ref" для аргумента, соответствующего параметру "in", эквивалентен "in". Попробуйте вместо этого использовать "in". + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. Должен быть указан параметр атрибута "SizeConst". @@ -6610,8 +6685,8 @@ - The new() constraint must be the last constraint specified - Ограничение new() должно быть последним указанным ограничением. + The new() constraint must be the last restrictive constraint specified + Ограничение new() должно быть последним указанным ограничением. @@ -7908,11 +7983,6 @@ If such a class is used as a base class and if the deriving class defines a dest "{0}": реализация интерфейсов статическими классами невозможна. - - '{0}': ref structs cannot implement interfaces - "{0}": ссылочные структуры не могут реализовывать интерфейсы - - '{0}': static classes cannot contain user-defined operators "{0}": статические классы не могут содержать определяемых пользователем операторов. @@ -9182,11 +9252,6 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep Недопустимо использовать параметр "{0}" с модификаторами ref, out или in внутри анонимного метода, лямбда-выражения, выражения запроса или локальной функции - - Unsafe code may not appear in iterators - Небезопасный код не может использоваться в итераторах. - - Cannot yield a value in the body of a catch clause Нельзя использовать оператор yield в теле предложения catch. @@ -10571,8 +10636,8 @@ Give the compiler some way to differentiate the methods. For example, you can gi - 'await' cannot be used in an expression containing the type '{0}' - '"await" нельзя использовать в выражении, содержащем тип "{0}" + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + '"await" нельзя использовать в выражении, содержащем тип "{0}" @@ -10640,16 +10705,6 @@ Give the compiler some way to differentiate the methods. For example, you can gi Модификатор "async" можно использовать только в методах, имеющих тело. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Параметры или локальные переменные типа "{0}" не могут объявляться в асинхронных методах и в асинхронных лямбда-выражениях. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - Оператор foreach нельзя использовать с перечислителями типа "{0}" в методах с модификатором Async или Iterator, так как "{0}" является ссылочной структурой. - - Security attribute '{0}' cannot be applied to an Async method. Атрибут безопасности "{0}" нельзя применить к асинхронному методу. @@ -11169,7 +11224,7 @@ You should consider suppressing the warning only if you're sure that you don't w Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - Экземпляр типа "{0}" нельзя использовать внутри вложенной функции, выражения запроса, блока итератора или асинхронного метода. + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12480,16 +12535,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Невозможно использовать локальную переменную ref "{0}" внутри анонимного метода, лямбда-выражения или выражения запроса - - Iterators cannot have by-reference locals - Итераторы не могут иметь локальных переменных по ссылке - - - - Async methods cannot have by-reference locals - Асинхронные методы не могут иметь локальных переменных по ссылке - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. Ссылка, возвращенная вызовом ' {0} ', не может быть сохранена за границей 'wait' или 'yield'. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 721552b2359e5..61a78dded475d 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -32,6 +32,11 @@ '{0}': soyut olay, olay erişeni söz dizimini kullanamaz + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees Metot gruplarındaki '&', ifade ağaçlarında kullanılamaz @@ -42,6 +47,11 @@ '{0}' &metot grubu, işlev dışı '{1}' işaretçi türüne dönüştürülemiyor. + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. İlişkilendirilmiş tam bir dize için '$@' yerine '@$' kullanmak amacıyla lütfen '{0}' veya daha yüksek bir dil sürümü kullanın. @@ -182,6 +192,11 @@ Birli işlecin parametresi, içeren tür veya tür parametresi ile kısıtlanmış olmalıdır. + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. {0} bağımsız değişkeni, {1} dil sürümündeki 'ref' anahtar sözcüğüyle geçirilemez. 'ref' bağımsız değişkenlerini 'in' parametrelerine geçirmek için{2} dil sürümüne yükseltin. @@ -232,6 +247,11 @@ 'init' erişimcisi statik üyelerde geçerli değil + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' /nullable için geçersiz '{0}' seçeneği; 'disable', 'enable', 'warnings' veya 'annotations' olmalıdır @@ -267,14 +287,14 @@ {0} kayıt üyesi, {1} konumsal parametresi ile eşleşmesi için {2} türünde okunabilir bir örnek özelliği veya alan olmalıdır. - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - 'System.Threading.Lock' türündeki bir değere ilişkin lock deyimi, asenkron yöntemlerde veya asenkron lambda ifadelerinde kullanılamaz. + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - '{0}' türündeki bir using deyimi kaynağı, asenkron yöntemlerde veya asenkron lambda ifadelerinde kullanılamaz. + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ '{0}' türü 'using static' için geçerli değil. Yalnızca bir sınıf, yapı, arabirim, sabit liste, temsilci veya ad alanı kullanılabilir. + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. Açık dönüş türü olmadan, anonim yöntemlerde AsyncMethodBuilder özniteliğine izin verilmez. @@ -382,11 +407,6 @@ Dönüş türü temsilci dönüş türüyle eşleşmediğinden {0}, ' {1} ' türüne dönüştürülemiyor - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - Dinamik türe sahip bir bağımsız değişken kullanıldığından ve metot dizi olmayan params koleksiyon parametresine sahip olduğundan, '{0}' metodu için tür bağımsız değişkeni kullanımdan çıkarsanamıyor. Tür bağımsız değişkenlerini açıkça belirtmeyi deneyin. - - __arglist cannot have an argument passed by 'in' or 'out' __arglist, 'in' veya 'out' tarafından geçirilen bir bağımsız değişkene sahip olamaz @@ -402,6 +422,11 @@ '{0}' işleci, işlecin eşleşen denetlenmemiş bir sürümünün de tanımlanmasını gerektirir + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. 'Clone' adlı üyelere kayıtlarda izin verilmez. @@ -587,6 +612,11 @@ 'readonly' değiştiricileri, '{0}' özelliğinin veya dizin oluşturucusunun her iki erişimcisinde de belirtilemez. Bunun yerine özelliğin kendisine bir 'readonly' değiştiricisi koyun. + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. 'else' bir deyim başlatamaz. @@ -1497,6 +1527,11 @@ '{0}', kapsayan kayıt mühürlü olmadığından geçersiz kılmaya izin vermelidir. + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null geçerli bir parametre adı değil. Örnek metodu alıcısı için erişim almak için parametre adı olarak boş dizeyi kullanın. @@ -1742,6 +1777,11 @@ Başvuru alanı yalnızca başvuru yapısında bildirilebilir. + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. ref atamasının sol tarafı, ref değişkeni olmalıdır. @@ -1802,6 +1842,16 @@ Başvuru döndüren özellikler gerekli kılınamaz. + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. İlişkisel desenler, kayan noktalı NaN için kullanılamaz. @@ -1847,6 +1897,11 @@ Türler ve diğer adlar 'gerekli' olarak adlandırılamaz. + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}': Hedef çalışma zamanı, geçersiz kılmalarda birlikte değişken türleri desteklemiyor. Tür, geçersiz kılınan '{1}' üyesiyle eşleşmek için '{2}' olmalıdır @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute bir arabirim uygulamasına uygulanamaz. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute yalnızca örnek metodları ve özellikleri yapılandırmak için uygulanabilir ve oluşturuculara veya yalnızca init üyelerine uygulanamaz. + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute yalnızca örnek metodları ve özellikleri yapılandırmak için uygulanabilir ve oluşturuculara veya yalnızca init üyelerine uygulanamaz. @@ -2377,6 +2432,16 @@ ref salt okunur parametreleri + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator esnek kaydırma işleci @@ -2552,6 +2617,16 @@ 'in' parametresine karşılık gelen bir bağımsız değişken için 'ref' değiştiricisi 'in' ile eşdeğerdir. Bunun yerine 'in' kullanmayı düşünün. + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. 'SizeConst' öznitelik parametresi belirtilmelidir. @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - new() kısıtlaması belirtilen son kısıtlama olmalıdır + The new() constraint must be the last restrictive constraint specified + new() kısıtlaması belirtilen son kısıtlama olmalıdır @@ -7907,11 +7982,6 @@ Bu sınıf temel sınıf olarak kullanılırsa ve türetilen sınıf bir yıkıc '{0}': statik sınıfları arabirimler uygulayamaz - - '{0}': ref structs cannot implement interfaces - '{0}': başvuru yapı birimleri arabirim uygulayamaz - - '{0}': static classes cannot contain user-defined operators '{0}': statik sınıflar kullanıcı tanımlı işleçler içeremez @@ -9181,11 +9251,6 @@ RuntimeCompatibilityAttribute AssemblyInfo.cs dosyasında false olarak ayarlanm Anonim metot, lambda ifadesi, sorgu ifadesi veya yerel işlev içinde '{0}' ref, out veya in parametresi kullanılamaz - - Unsafe code may not appear in iterators - Güvenli olmayan kod yineleyicilerde görünmeyebilir - - Cannot yield a value in the body of a catch clause Catch yan tümcesinin gövdesinde yield ile bir değer döndürülemez @@ -10570,8 +10635,8 @@ Derleyiciye yöntemleri ayrıştırma yolu verin. Örneğin, bunlara farklı adl - 'await' cannot be used in an expression containing the type '{0}' - 'await', '{0}' türünü içeren bir ifadede kullanılamaz + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'await', '{0}' türünü içeren bir ifadede kullanılamaz @@ -10639,16 +10704,6 @@ Derleyiciye yöntemleri ayrıştırma yolu verin. Örneğin, bunlara farklı adl Async' değiştiricisi yalnızca gövdesi olan metotlarda kullanılabilir. - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - Zaman uyumsuz yöntemlerde veya zaman uyumsuz lambda ifadelerinde '{0}' türündeki parametreler veya yerel öğeler bildirilemez. - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - '{0}' bir başvuru yapısı olduğundan foreach deyimi, async veya iterator metotlarındaki '{0}' türü numaralandırıcılar üzerinde çalışamaz. - - Security attribute '{0}' cannot be applied to an Async method. '{0}' güvenlik özniteliği bir Async yöntemine uygulanamaz. @@ -11168,7 +11223,7 @@ Yalnızca asenkron çağrının tamamlanmasını beklemek istemediğinizden ve Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - '{0}' türünün örneği iç içe geçmiş bir işlevde, sorgu ifadesinde, yineleyici bloğunda veya zaman uyumsuz bir metotta kullanılamaz + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ Uyarıyı kaldırmak için, /reference kullanabilirsiniz (Birlikte Çalışma T '{0}' ref yerel değeri bir anonim metotta, lambda ifadesinde veya sorgu ifadesinde kullanılamaz - - Iterators cannot have by-reference locals - Yineleyiciler başvuruya göre yerel değerlere sahip olamaz - - - - Async methods cannot have by-reference locals - Zaman uyumsuz metotlar başvuruya göre yerel değerlere sahip olamaz - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. '{0}' hedefine bir çağrı tarafından döndürülen başvuru, 'await' veya 'yield' sınırında korunamıyor. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index d61012d7e3da5..b0175426fa302 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -32,6 +32,11 @@ “{0}”: 抽象事件不可使用事件访问器语法 + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees 不可在表达式树中使用方法组上的 "&" @@ -42,6 +47,11 @@ 无法将方法组“{0}”转换为非函数指针类型“{1}”(&M)。 + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 若要对内插逐字字符串使用 "@$" 而不是 "$@",请使用语言版本 {0} 或更高版本。 @@ -182,6 +192,11 @@ 一元运算符的参数必须是包含类型或被其约束的类型参数。 + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. 不能在语言版本 {1} 中使用 “ref” 关键字传递参数 {0}。要将 “ref” 参数传递给 “in” 参数,请升级到语言版本 {2} 或更高版本。 @@ -232,6 +247,11 @@ "Init" 访问器对静态成员无效 + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' /nullable 的选项“{0}”无效;必须为“禁用”、“启用”、“警告”或“注释” @@ -267,14 +287,14 @@ 记录成员 '{0}' 必须为类型 '{1}' 的可读实例属性或字段,以匹配位置参数 '{2}'。 - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - 类型“System.Threading.Lock”的值的 lock 语句不能用于异步方法或异步 lambda 表达式。 + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - 无法在异步方法或异步 lambda 表达式中使用类型为“{0}”的 using 语句资源。 + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ “{0}”类型对于 "using static" 无效。只能使用类、结构、接口、枚举、委托或命名空间。 + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. 没有显式返回类型的匿名方法不允许使用 AsyncMethodBuilder 属性。 @@ -382,11 +407,6 @@ 无法将 {0} 转换为类型“{1}”,因为返回类型与委托返回类型不匹配 - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - 无法从用法推断出方法“{0}”的类型参数,因为使用了动态类型参数,并且该方法具有非数组 params 集合参数。请尝试显式指定类型参数。 - - __arglist cannot have an argument passed by 'in' or 'out' __arglist 不能有 "in" 或 "out" 传递的参数 @@ -402,6 +422,11 @@ 运算符 '{0}' 需要同时定义匹配的未选中版本的运算符 + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. 记录中不允许使用名为 "Clone" 的成员。 @@ -587,6 +612,11 @@ 不能在属性或索引器 "{0}" 的两个访问器上指定 "readonly" 修饰符。而应在属性本身上指定 "readonly" 修饰符。 + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. "else" 不能用在语句的开头。 @@ -1497,6 +1527,11 @@ “{0}”必须允许替代,因为包含的记录未密封。 + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null 不是有效的参数名称。若要获取对实例方法接收器的访问权限,请使用空字符串作为参数名。 @@ -1742,6 +1777,11 @@ ref 字段只能在 ref 结构中声明。 + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. ref 赋值的左侧必须为 ref 变量。 @@ -1802,6 +1842,16 @@ Ref 返回属性是必需的。 + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. 关系模式可能不能用于浮点 NaN。 @@ -1847,6 +1897,11 @@ 类型和别名不能命名为 “required”。 + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' “{0}”: 目标运行时不支持替代中的协变类型。类型必须为“{2}”才能匹配替代成员“{1}” @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute 无法应用于接口实现。 + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute 只能应用于结构实例方法和属性,不能应用于构造函数或仅初始化成员。 + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute 只能应用于结构实例方法和属性,不能应用于构造函数或仅初始化成员。 @@ -2377,6 +2432,16 @@ ref readonly 参数 + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator 移位运算符 @@ -2552,6 +2617,16 @@ 与 “in” 参数对应的参数的 “ref” 修饰符等效于 “in”。请考虑改用 “in”。 + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. 必须指定属性参数 “SizeConst”。 @@ -6609,8 +6684,8 @@ - The new() constraint must be the last constraint specified - new() 约束必须是指定的最后一个约束 + The new() constraint must be the last restrictive constraint specified + new() 约束必须是指定的最后一个约束 @@ -7907,11 +7982,6 @@ If such a class is used as a base class and if the deriving class defines a dest “{0}”: 静态类不能实现接口 - - '{0}': ref structs cannot implement interfaces - '{0}': ref 结构不能实现接口 - - '{0}': static classes cannot contain user-defined operators “{0}”: 静态类不能包含用户定义的运算符 @@ -9181,11 +9251,6 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep 不能在匿名方法、lambda 表达式、查询表达式或本地函数中使用 ref、out 或 in 参数“{0}” - - Unsafe code may not appear in iterators - 迭代器中不能出现不安全的代码 - - Cannot yield a value in the body of a catch clause 无法在 catch 子句体中生成值 @@ -10570,8 +10635,8 @@ Give the compiler some way to differentiate the methods. For example, you can gi - 'await' cannot be used in an expression containing the type '{0}' - '“等待”不能在包含“{0}”类型的表达式中使用 + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + '“等待”不能在包含“{0}”类型的表达式中使用 @@ -10639,16 +10704,6 @@ Give the compiler some way to differentiate the methods. For example, you can gi 只能在具有正文的方法中使用 "async" 修饰符。 - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - 不能在异步方法或异步 lambda 表达式中声明类型“{0}”的参数或局部变量。 - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - foreach 语句无法在类型“{0}”的枚举器上使用异步或迭代器方法操作,因为“{0}”是 ref 结构。 - - Security attribute '{0}' cannot be applied to an Async method. 安全特性“{0}”不可应用于异步方法。 @@ -11168,7 +11223,7 @@ You should consider suppressing the warning only if you're sure that you don't w Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - “{0}”类型的实例不能在嵌套函数、查询表达式、迭代器块或异步方法中使用 + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 不能在匿名方法、lambda 表达式或查询表达式内使用 ref 局部变量“{0}” - - Iterators cannot have by-reference locals - 迭代器不能有按引用局部变量 - - - - Async methods cannot have by-reference locals - 异步方法不能有按引用局部变量 - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. 调用“{0}”所返回的引用不能跨 "await" 或 "yield" 边界保留。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 01ddee39364a5..59932f5945760 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -32,6 +32,11 @@ '{0}' 抽象事件無法使用事件存取子語法 + + The '&' operator cannot be used on parameters or local variables in iterator methods. + The '&' operator cannot be used on parameters or local variables in iterator methods. + + '&' on method groups cannot be used in expression trees 不得在運算式樹狀架構中對方法群組使用 '&' @@ -42,6 +47,11 @@ 無法將方法群組 '{0}' 轉換成非函式指標類型 '{1}'(&M) + + The 'allows' constraint clause must be the last constraint specified + The 'allows' constraint clause must be the last constraint specified + + To use '@$' instead of '$@' for an interpolated verbatim string, please use language version '{0}' or greater. 若要在插入的逐字字串使用 '@$' 而不是 '$@',請使用 '{0}' 或更高的語言版本。 @@ -182,6 +192,11 @@ 一元運算子的其中一個參數必須是包含類型,或其型別參數受其限制。 + + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + foreach statement cannot operate on enumerators of type '{0}' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + + Argument {0} may not be passed with the 'ref' keyword in language version {1}. To pass 'ref' arguments to 'in' parameters, upgrade to language version {2} or greater. 引數 {0} 可能無法以語言版本 {1} 中的 'ref' 關鍵字傳遞。若要將 'ref' 引數傳遞至 'in' 參數,請升級為語言版本 {2} 或更新版本。 @@ -232,6 +247,11 @@ 靜態成員上的 'Init' 存取子無效 + + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + + Invalid option '{0}' for /nullable; must be 'disable', 'enable', 'warnings' or 'annotations' /nullable 的選項 '{0}' 無效; 必須為 'disable'、'enable'、'warnings' 或 'annotations' @@ -267,14 +287,14 @@ 記錄成員 '{0}' 必須是類型 '{1}' 的可讀取執行個體屬性或欄位,才能符合位置參數 '{2}'。 - - A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - 型別 'System.Threading.Lock' 的值上的 lock 陳述式不能用在非同步方法或非同步 Lambda 運算式中。 + + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. + foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct or a type parameter that allows ref struct. - - A using statement resource of type '{0}' cannot be used in async methods or async lambda expressions. - 類型 '{0}' 的 using 陳述式資源不能用於非同步方法或非同步 Lambda 運算式。 + + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. + Parameters of type '{0}' cannot be declared in async methods or async lambda expressions. @@ -302,6 +322,11 @@ '{0}' 類型對 'using static' 無效。只能使用類別、結構、介面、列舉、委派或命名空間。 + + Cannot use 'yield return' in an 'unsafe' block + Cannot use 'yield return' in an 'unsafe' block + + The AsyncMethodBuilder attribute is disallowed on anonymous methods without an explicit return type. 沒有明確傳回型別的匿名方法上不允許 AsyncMethodBuilder 屬性。 @@ -382,11 +407,6 @@ 無法將 {0} 轉換成類型 '{1}',因為傳回型別不符合委派傳回型別 - - The type arguments for method '{0}' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. - 無法從使用方式推斷方法 '{0}' 的型別引數,因為使用了具有動態型別的引述,而且該方法具有非陣列參數集合參數。請嘗試明確指定型別引數。 - - __arglist cannot have an argument passed by 'in' or 'out' __arglist 不得包含 'in' 或 'out' 傳遞的引數 @@ -402,6 +422,11 @@ 運算子 '{0}' 需要也同時定義運算子的相符未檢查版本 + + Cannot allow ref structs for a type parameter known from other constraints to be a class + Cannot allow ref structs for a type parameter known from other constraints to be a class + + Members named 'Clone' are disallowed in records. 記錄中不允許名為 'Clone' 的成員。 @@ -587,6 +612,11 @@ 在屬性和索引子 '{0}' 的存取子上均無法指定 'readonly' 修飾元。請改在屬性自身上放置 'readonly' 修飾元。 + + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + '{0}' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + + 'else' cannot start a statement. 'else' 無法開始陳述式。 @@ -1497,6 +1527,11 @@ '{0}' 必須允許覆寫,因為包含的記錄並未密封。 + + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + The type '{2}' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '{1}' in the generic type or method '{0}' + + null is not a valid parameter name. To get access to the receiver of an instance method, use the empty string as the parameter name. null 不是有效的參數名稱。若要取得執行個體方法接收器的存取權,請使用空字串做為參數名稱。 @@ -1742,6 +1777,11 @@ ref 欄位只能在 ref 結構中宣告。 + + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + + The left-hand side of a ref assignment must be a ref variable. 參考指派的左側必須為 ref 變數。 @@ -1802,6 +1842,16 @@ 無法要求 Ref 傳回屬性。 + + 'ref struct' is already specified. + 'ref struct' is already specified. + + + + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + '{0}' cannot implement interface member '{1}' for ref struct '{2}'. + + Relational patterns may not be used for a floating-point NaN. 浮點 NaN 不可使用關聯性模式。 @@ -1847,6 +1897,11 @@ 類型和別名不能命名為 'required'。 + + Target runtime doesn't support by-ref-like generics. + Target runtime doesn't support by-ref-like generics. + + '{0}': Target runtime doesn't support covariant types in overrides. Type must be '{2}' to match overridden member '{1}' '{0}': 在覆寫中,目標執行階段不支援 Covariant 類型。類型必須是 '{2}',才符合覆寫的成員 '{1}' @@ -2123,13 +2178,13 @@ - UnscopedRefAttribute cannot be applied to an interface implementation. - UnscopedRefAttribute 無法套用至介面實作。 + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. + UnscopedRefAttribute cannot be applied to an interface implementation because implemented member '{0}' doesn't have this attribute. - UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - UnscopedRefAttribute 只能套用至結構執行個體方法和屬性,且無法套用至建構函式或僅 init 成員。 + UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + UnscopedRefAttribute 只能套用至結構執行個體方法和屬性,且無法套用至建構函式或僅 init 成員。 @@ -2377,6 +2432,16 @@ ref readonly 參數 + + ref struct interfaces + ref struct interfaces + + + + ref and unsafe in async and iterator methods + ref and unsafe in async and iterator methods + + relaxed shift operator 寬鬆移位 (Shift) 運算子 @@ -2552,6 +2617,16 @@ 對應至 'in' 參數之引數的 'ref' 修飾元相當於 'in'。請考慮改為使用 'in'。 + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + + + 'yield return' should not be used in the body of a lock statement + 'yield return' should not be used in the body of a lock statement + + Attribute parameter 'SizeConst' must be specified. 必須指定屬性參數 'SizeConst'。 @@ -6609,8 +6684,8 @@ strument:TestCoverage 產生檢測要收集 - The new() constraint must be the last constraint specified - new() 條件約束必須是最後指定的條件約束 + The new() constraint must be the last restrictive constraint specified + new() 條件約束必須是最後指定的條件約束 @@ -7907,11 +7982,6 @@ If such a class is used as a base class and if the deriving class defines a dest '{0}': 靜態類別無法實作介面 - - '{0}': ref structs cannot implement interfaces - '{0}': ref struct 無法實作介面 - - '{0}': static classes cannot contain user-defined operators '{0}': 靜態類別不可包含使用者定義的運算子 @@ -9181,11 +9251,6 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep 無法在匿名方法、Lambda 運算式、查詢運算式或區域函式中使用 ref、out 或 in 參數 '{0}' - - Unsafe code may not appear in iterators - Unsafe 程式碼不可出現在迭代器中 - - Cannot yield a value in the body of a catch clause 無法在 catch 子句主體中使用 yield 產生值 @@ -10570,8 +10635,8 @@ Give the compiler some way to differentiate the methods. For example, you can gi - 'await' cannot be used in an expression containing the type '{0}' - 'await' 不得用於包含類型 '{0}' 的運算式中 + Instance of type '{0}' cannot be preserved across 'await' or 'yield' boundary. + 'await' 不得用於包含類型 '{0}' 的運算式中 @@ -10639,16 +10704,6 @@ Give the compiler some way to differentiate the methods. For example, you can gi async' 修飾元只可用於具有主體的方法。 - - Parameters or locals of type '{0}' cannot be declared in async methods or async lambda expressions. - 類型 '{0}' 的參數或區域變數,不可在非同步方法或非同步 Lambda 運算式中宣告。 - - - - foreach statement cannot operate on enumerators of type '{0}' in async or iterator methods because '{0}' is a ref struct. - foreach 陳述式無法對 async 或 iterator 方法中類型 '{0}' 的列舉值進行操作,因為 '{0}' 為 ref struct。 - - Security attribute '{0}' cannot be applied to an Async method. 安全屬性 '{0}' 無法套用至非同步方法。 @@ -11168,7 +11223,7 @@ You should consider suppressing the warning only if you're sure that you don't w Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method - 類型 '{0}' 的執行個體不可用於巢狀函式、查詢運算式、迭代區塊或非同步方法中 + Instance of type '{0}' cannot be used inside a nested function, query expression, iterator block or async method @@ -12479,16 +12534,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ 無法在匿名方法、Lambda 運算式或查詢運算式中使用參考本機 '{0}' - - Iterators cannot have by-reference locals - Iterator 不可有 by-reference local - - - - Async methods cannot have by-reference locals - 非同步方法不可有 by-reference local - - A reference returned by a call to '{0}' cannot be preserved across 'await' or 'yield' boundary. 對 '{0}' 之呼叫所傳回的參考無法在 'await' 或 'yield' 界限間保留。 diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTestBase.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTestBase.cs index 50e51c9e3b42d..e6ddad5f5b487 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTestBase.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTestBase.cs @@ -39,7 +39,7 @@ string getSdkDirectory(TempRoot temp) if (ExecutionConditionUtil.IsCoreClr) { var dir = temp.CreateDirectory(); - File.WriteAllBytes(Path.Combine(dir.Path, "mscorlib.dll"), Net461.References.mscorlib.ImageBytes); + File.WriteAllBytes(Path.Combine(dir.Path, "mscorlib.dll"), Net461.ReferenceInfos.mscorlib.ImageBytes); return dir.Path; } diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index 63c7e533907ee..223d10d5847d3 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -210,6 +210,63 @@ class C Assert.Null(cmd.AnalyzerOptions); } + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/72657")] + public void AnalyzerConfig_DoubleSlash(bool doubleSlashAnalyzerConfig, bool doubleSlashSource) + { + var dir = Temp.CreateDirectory(); + var analyzer = new CompilationAnalyzerWithSeverity(DiagnosticSeverity.Warning, configurable: true); + var src = dir.CreateFile("Class1.cs").WriteAllText(""" + public class C + { + public void M() { } + } + """); + + // The analyzer should produce a warning. + var output = VerifyOutput(dir, src, includeCurrentAssemblyAsAnalyzerReference: false, analyzers: [analyzer], expectedWarningCount: 1); + AssertEx.Equal("Class1.cs(1,1): warning ID1000:", output.Trim()); + + // But not when this editorconfig is applied. + var editorconfig = dir.CreateFile(".editorconfig").WriteAllText(""" + root = true + + [*.cs] + dotnet_analyzer_diagnostic.severity = none + + generated_code = true + """); + var cmd = CreateCSharpCompiler( + [ + "/nologo", + "/preferreduilang:en", + "/t:library", + "/analyzerconfig:" + modifyPath(editorconfig.Path, doubleSlashAnalyzerConfig), + modifyPath(src.Path, doubleSlashSource), + ], + [analyzer]); + var outWriter = new StringWriter(CultureInfo.InvariantCulture); + var exitCode = cmd.Run(outWriter); + Assert.Equal(0, exitCode); + AssertEx.Equal("", outWriter.ToString()); + + static string modifyPath(string path, bool doubleSlash) + { + if (!doubleSlash) + { + return path; + } + + // Find the second-to-last slash. + char[] separators = ['/', '\\']; + var lastSlashIndex = path.LastIndexOfAny(separators); + lastSlashIndex = path.LastIndexOfAny(separators, lastSlashIndex - 1); + + // Duplicate that slash. + var lastSlash = path[lastSlashIndex]; + return path[0..lastSlashIndex] + lastSlash + path[lastSlashIndex..]; + } + } + [Fact] public void AnalyzerConfigWithOptions() { @@ -11986,7 +12043,7 @@ public sealed class DiagnosticDescriptor var minSystemCollectionsImmutableImage = CSharpCompilation.Create( "System.Collections.Immutable", new[] { SyntaxFactory.ParseSyntaxTree(minSystemCollectionsImmutableSource) }, - new MetadataReference[] { NetStandard13.SystemRuntime }, + new MetadataReference[] { NetStandard13.References.SystemRuntime }, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, cryptoPublicKey: TestResources.TestKeys.PublicKey_b03f5f7f11d50a3a)).EmitToArray(); var minSystemCollectionsImmutableRef = MetadataReference.CreateFromImage(minSystemCollectionsImmutableImage); @@ -11996,7 +12053,7 @@ public sealed class DiagnosticDescriptor new[] { SyntaxFactory.ParseSyntaxTree(minCodeAnalysisSource) }, new MetadataReference[] { - NetStandard13.SystemRuntime, + NetStandard13.References.SystemRuntime, minSystemCollectionsImmutableRef }, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, cryptoPublicKey: TestResources.TestKeys.PublicKey_31bf3856ad364e35)).EmitToArray(); @@ -12087,7 +12144,7 @@ public override void Initialize(AnalysisContext context) minCodeAnalysisRef, minSystemCollectionsImmutableRef }; - references = references.Concat(NetStandard13.All).ToArray(); + references = references.Concat(NetStandard13.References.All).ToArray(); var analyzerImage = CSharpCompilation.Create( analyzerAssemblyName, diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 778817985654a..d3c9217c79637 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -133,7 +133,7 @@ private static void VerifyMissingType(string source, WellKnownType type, params // Instrumentation to investigate CI failure: https://github.com/dotnet/roslyn/issues/34207 private CSharpCompilation CreateCompilationWithAsyncIterator(string source, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null) => CreateCompilationWithTasksExtensions(new[] { (CSharpTestSource)CSharpTestBase.Parse(source, filename: "source", parseOptions), CSharpTestBase.Parse(AsyncStreamsTypes, filename: "AsyncStreamsTypes", parseOptions) }, - options: options, parseOptions: parseOptions); + options: options); private CSharpCompilation CreateCompilationWithAsyncIterator(CSharpTestSource source, CSharpCompilationOptions options = null, CSharpParseOptions parseOptions = null) => CreateCompilationWithTasksExtensions(new[] { source, AsyncStreamsTypes }, options: options, parseOptions: parseOptions); @@ -631,15 +631,288 @@ static async System.Threading.Tasks.Task Main() ref struct S { }"; + + var expectedDiagnostics = new[] + { + // source(4,65): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'IAsyncEnumerable' + // static async System.Collections.Generic.IAsyncEnumerable M() + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("System.Collections.Generic.IAsyncEnumerable", "T", "S").WithLocation(4, 65) + }; + var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe); + comp.VerifyDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext); + comp.VerifyDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12); comp.VerifyDiagnostics( - // source(4,65): error CS0306: The type 'S' may not be used as a type argument + // source(4,65): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'IAsyncEnumerable' // static async System.Collections.Generic.IAsyncEnumerable M() - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("S").WithLocation(4, 65), - // source(11,24): error CS4012: Parameters or locals of type 'S' cannot be declared in async methods or async lambda expressions. + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("System.Collections.Generic.IAsyncEnumerable", "T", "S").WithLocation(4, 65), + // source(11,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // await foreach (var s in M()) - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("S").WithLocation(11, 24) - ); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 24)); + } + + [Fact] + public void RefStructElementType_NonGeneric() + { + string source = """ + using System.Threading.Tasks; + + class C + { + public E GetAsyncEnumerator() => new E(); + static async Task Main() + { + await foreach (var s in new C()) + { + System.Console.Write(s.F); + } + } + } + class E + { + bool _done; + public S Current => new S { F = 123 }; + public async Task MoveNextAsync() + { + await Task.Yield(); + return !_done ? (_done = true) : false; + } + } + ref struct S + { + public int F; + } + """; + + var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12); + comp.VerifyDiagnostics( + // source(8,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 24)); + + comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe); + var verifier = CompileAndVerify(comp, expectedOutput: "123", verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 238 (0xee) + .maxstack 3 + .locals init (int V_0, + S V_1, //s + System.Runtime.CompilerServices.TaskAwaiter V_2, + C.
d__1 V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__1.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0016 + IL_0012: br.s IL_0082 + IL_0014: br.s IL_0082 + IL_0016: nop + IL_0017: nop + IL_0018: ldarg.0 + IL_0019: newobj "C..ctor()" + IL_001e: call "E C.GetAsyncEnumerator()" + IL_0023: stfld "E C.
d__1.<>s__1" + IL_0028: br.s IL_0044 + IL_002a: ldarg.0 + IL_002b: ldfld "E C.
d__1.<>s__1" + IL_0030: callvirt "S E.Current.get" + IL_0035: stloc.1 + IL_0036: nop + IL_0037: ldloc.1 + IL_0038: ldfld "int S.F" + IL_003d: call "void System.Console.Write(int)" + IL_0042: nop + IL_0043: nop + IL_0044: ldarg.0 + IL_0045: ldfld "E C.
d__1.<>s__1" + IL_004a: callvirt "System.Threading.Tasks.Task E.MoveNextAsync()" + IL_004f: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0054: stloc.2 + IL_0055: ldloca.s V_2 + IL_0057: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_005c: brtrue.s IL_009e + IL_005e: ldarg.0 + IL_005f: ldc.i4.0 + IL_0060: dup + IL_0061: stloc.0 + IL_0062: stfld "int C.
d__1.<>1__state" + IL_0067: ldarg.0 + IL_0068: ldloc.2 + IL_0069: stfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__1.<>u__1" + IL_006e: ldarg.0 + IL_006f: stloc.3 + IL_0070: ldarg.0 + IL_0071: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_0076: ldloca.s V_2 + IL_0078: ldloca.s V_3 + IL_007a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__1)" + IL_007f: nop + IL_0080: leave.s IL_00ed + IL_0082: ldarg.0 + IL_0083: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__1.<>u__1" + IL_0088: stloc.2 + IL_0089: ldarg.0 + IL_008a: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.
d__1.<>u__1" + IL_008f: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0095: ldarg.0 + IL_0096: ldc.i4.m1 + IL_0097: dup + IL_0098: stloc.0 + IL_0099: stfld "int C.
d__1.<>1__state" + IL_009e: ldarg.0 + IL_009f: ldloca.s V_2 + IL_00a1: call "bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00a6: stfld "bool C.
d__1.<>s__2" + IL_00ab: ldarg.0 + IL_00ac: ldfld "bool C.
d__1.<>s__2" + IL_00b1: brtrue IL_002a + IL_00b6: ldarg.0 + IL_00b7: ldnull + IL_00b8: stfld "E C.
d__1.<>s__1" + IL_00bd: leave.s IL_00d9 + } + catch System.Exception + { + IL_00bf: stloc.s V_4 + IL_00c1: ldarg.0 + IL_00c2: ldc.i4.s -2 + IL_00c4: stfld "int C.
d__1.<>1__state" + IL_00c9: ldarg.0 + IL_00ca: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_00cf: ldloc.s V_4 + IL_00d1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_00d6: nop + IL_00d7: leave.s IL_00ed + } + IL_00d9: ldarg.0 + IL_00da: ldc.i4.s -2 + IL_00dc: stfld "int C.
d__1.<>1__state" + IL_00e1: ldarg.0 + IL_00e2: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__1.<>t__builder" + IL_00e7: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_00ec: nop + IL_00ed: ret + } + """); + } + + [Fact] + public void RefStructElementType_NonGeneric_AwaitAfter() + { + string source = """ + using System.Threading.Tasks; + + class C + { + public E GetAsyncEnumerator() => new E(); + static async Task Main() + { + await foreach (var s in new C()) + { + System.Console.Write(s.F); + await Task.Yield(); + } + } + } + class E + { + bool _done; + public S Current => new S { F = 123 }; + public async Task MoveNextAsync() + { + await Task.Yield(); + return !_done ? (_done = true) : false; + } + } + ref struct S + { + public int F; + } + """; + + var comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12); + comp.VerifyDiagnostics( + // source(8,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 24)); + + comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilationWithAsyncIterator(source, options: TestOptions.DebugExe); + var verifier = CompileAndVerify(comp, expectedOutput: "123", verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + } + + [Fact] + public void RefStructElementType_NonGeneric_AwaitBefore() + { + string source = """ + using System.Threading.Tasks; + + class C + { + public E GetAsyncEnumerator() => new E(); + static async Task Main() + { + await foreach (var s in new C()) + { + await Task.Yield(); + System.Console.Write(s.F); + } + } + } + class E + { + bool _done; + public S Current => new S { F = 123 }; + public async Task MoveNextAsync() + { + await Task.Yield(); + return !_done ? (_done = true) : false; + } + } + ref struct S + { + public int F; + } + """; + + var comp = CreateCompilationWithAsyncIterator(source, parseOptions: TestOptions.Regular12); + comp.VerifyDiagnostics( + // source(8,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 24)); + + var expectedDiagnostics = new[] + { + // source(11,34): error CS4007: Instance of type 'S' cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(s.F); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s.F").WithArguments("S").WithLocation(11, 34) + }; + + comp = CreateCompilationWithAsyncIterator(source, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithAsyncIterator(source); + comp.VerifyEmitDiagnostics(expectedDiagnostics); } [Fact] diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs index 0a7f649ff7d64..999bf6667331d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs @@ -3789,9 +3789,11 @@ static async Task Main() var comp = CreateCompilationWithMscorlibAndSpan(source, options: options); comp.VerifyDiagnostics(); comp.VerifyEmitDiagnostics( - // (9,66): error CS4007: 'await' cannot be used in an expression containing the type 'System.Span' - // await Async1(F1(), G(F2(), stackalloc int[] { 1, 2, 3 }, await F3())); - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await F3()").WithArguments("System.Span").WithLocation(9, 66) + // (8,5): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // { + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"{ + await Async1(F1(), G(F2(), stackalloc int[] { 1, 2, 3 }, await F3())); + }").WithArguments("System.Span").WithLocation(8, 5) ); } } @@ -3897,16 +3899,16 @@ public ref struct S public bool P2 => true; } "; - CreateCompilation(source, options: TestOptions.DebugDll).VerifyDiagnostics().VerifyEmitDiagnostics( - // (9,17): error CS4013: Instance of type 'S' cannot be used inside a nested function, query expression, iterator block or async method - // Q { F: { P1: true } } when await c => r, // error: cached Q.F is alive - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "F").WithArguments("S").WithLocation(9, 17) - ); - CreateCompilation(source, options: TestOptions.ReleaseDll).VerifyDiagnostics().VerifyEmitDiagnostics( - // (9,17): error CS4013: Instance of type 'S' cannot be used inside a nested function, query expression, iterator block or async method + + var expectedDiagnostics = new[] + { + // (9,17): error CS4007: Instance of type 'S' cannot be preserved across 'await' or 'yield' boundary. // Q { F: { P1: true } } when await c => r, // error: cached Q.F is alive - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "F").WithArguments("S").WithLocation(9, 17) - ); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "F").WithArguments("S").WithLocation(9, 17) + }; + + CreateCompilation(source, options: TestOptions.DebugDll).VerifyDiagnostics().VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.ReleaseDll).VerifyDiagnostics().VerifyEmitDiagnostics(expectedDiagnostics); } [Fact] diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs index bce2519fce4d0..2dcb0b215b19d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs @@ -1695,12 +1695,26 @@ public System.Threading.Tasks.Task MoveNextAsync() => throw null; public int Current { get => throw null; } } -}"; - var comp = CreateCompilationWithTasksExtensions(source + s_IAsyncEnumerable); +}" + s_IAsyncEnumerable; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12); comp.VerifyDiagnostics( - // (6,32): error CS8177: Async methods cannot have by-reference locals + // (6,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // await foreach (ref var i in new C()) - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "i").WithLocation(6, 32)); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 32)); + + var expectedDiagnostics = new[] + { + // (6,37): error CS1510: A ref or out value must be an assignable variable + // await foreach (ref var i in new C()) + Diagnostic(ErrorCode.ERR_RefLvalueExpected, "new C()").WithLocation(6, 37) + }; + + comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext); + comp.VerifyDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithTasksExtensions(source); + comp.VerifyDiagnostics(expectedDiagnostics); var tree = comp.SyntaxTrees.Single(); var model = (SyntaxTreeSemanticModel)comp.GetSemanticModel(tree, ignoreAccessibility: false); @@ -1708,6 +1722,119 @@ public System.Threading.Tasks.Task MoveNextAsync() Assert.Equal(default, model.GetForEachStatementInfo(foreachSyntax)); } + [Theory, CombinatorialData] + public void TestWithPattern_Ref_Iterator([CombinatorialValues(" ", "readonly")] string modifier) + { + var source = $$""" + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + class C + { + static async Task Main() + { + await foreach (int i in F()) + { + Console.Write(i); + } + } + + static async IAsyncEnumerable F() + { + await foreach (ref {{modifier}} var i in new C()) + { + yield return i; + } + } + + public Enumerator GetAsyncEnumerator(System.Threading.CancellationToken token = default) => new(); + + public sealed class Enumerator + { + private readonly int[] _array = [1, 2, 3]; + private int _index = -1; + public Task MoveNextAsync() + { + if (_index < _array.Length) _index++; + return Task.FromResult(_index < _array.Length); + } + public ref int Current => ref _array[_index]; + } + } + """ + AsyncStreamsTypes; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12); + comp.VerifyDiagnostics( + // (17,41): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (ref readonly var i in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(17, 41)); + + var expectedOutput = "123"; + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_Ref_Iterator_Used() + { + var source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + + class C + { + static async IAsyncEnumerable F() + { + await foreach (ref var i in new C()) + { + yield return i; + M(ref i); + } + } + + static void M(ref int i) { } + + public Enumerator GetAsyncEnumerator(System.Threading.CancellationToken token = default) => new(); + + public sealed class Enumerator + { + private readonly int[] _array = [1, 2, 3]; + private int _index = -1; + public Task MoveNextAsync() + { + if (_index < _array.Length) _index++; + return Task.FromResult(_index < _array.Length); + } + public ref int Current => ref _array[_index]; + } + } + """ + AsyncStreamsTypes; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12); + comp.VerifyDiagnostics( + // (8,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (ref var i in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 32)); + + var expectedDiagnostics = new[] + { + // (11,19): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // M(ref i); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "i").WithLocation(11, 19) + }; + + comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithTasksExtensions(source); + comp.VerifyEmitDiagnostics(expectedDiagnostics); + } + [Fact] public void TestWithPattern_PointerType() { @@ -1935,7 +2062,427 @@ public S(int i) } [Fact] - public void TestWithPattern_RefReturningCurrent() + public void TestWithPattern_RefStructEnumerator_Async() + { + var source = """ + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (var s in new C()) + { + } + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public ref struct Enumerator + { + public int Current => 0; + public Task MoveNextAsync() => throw null; + } + } + """; + + var expectedDiagnostics = new[] + { + // (6,15): error CS8344: foreach statement cannot operate on enumerators of type 'C.Enumerator' in async or iterator methods because 'C.Enumerator' is a ref struct. + // await foreach (var s in new C()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("C.Enumerator").WithLocation(6, 15) + }; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void TestWithPattern_RefStructEnumerator_AsyncIterator() + { + var source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + public class C + { + public static async IAsyncEnumerable M() + { + await foreach (var x in new C()) + { + yield return x; + } + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public ref struct Enumerator + { + public int Current => 0; + public Task MoveNextAsync() => throw null; + } + } + """ + s_IAsyncEnumerable; + + var expectedDiagnostics = new[] + { + // (7,15): error CS8344: foreach statement cannot operate on enumerators of type 'C.Enumerator' in async or iterator methods because 'C.Enumerator' is a ref struct. + // await foreach (var x in new C()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("C.Enumerator").WithLocation(7, 15) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilationWithTasksExtensions(source).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void TestWithPattern_RefStructEnumerator_Iterator() + { + var source = """ + using System.Collections.Generic; + public class C + { + public static IEnumerable M() + { + foreach (var x in new C()) + { + yield return x; + } + } + public Enumerator GetEnumerator() => new Enumerator(); + public ref struct Enumerator + { + public int Current => 0; + public bool MoveNext() => throw null; + } + } + """; + + var expectedDiagnostics = new[] + { + // (6,9): error CS8344: foreach statement cannot operate on enumerators of type 'C.Enumerator' in async or iterator methods because 'C.Enumerator' is a ref struct. + // foreach (var x in new C()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("C.Enumerator").WithLocation(6, 9) + }; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void TestWithPattern_RefStructEnumerable_Async() + { + var source = """ + using System; + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (var x in new Enumerable()) + { + await Task.Yield(); + Console.Write($"{x} "); + } + Console.Write("Done"); + } + public ref struct Enumerable + { + public Enumerator GetAsyncEnumerator() => new(); + } + public class Enumerator + { + int i = 0; + public int Current => i; + public async Task MoveNextAsync() + { + i++; + await Task.Yield(); + return i < 3; + } + } + } + """ + s_IAsyncEnumerable; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "1 2 Done").VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefStructEnumerable_AsyncIterator() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (var i in M()) + { + Console.Write($"{i} "); + } + Console.Write("Done"); + } + public static async IAsyncEnumerable M() + { + await foreach (var x in new Enumerable()) + { + await Task.Yield(); + yield return x * 2; + } + yield return -1; + } + public ref struct Enumerable + { + public Enumerator GetAsyncEnumerator() => new(); + } + public class Enumerator + { + int i = 0; + public int Current => i; + public async Task MoveNextAsync() + { + i++; + await Task.Yield(); + return i < 3; + } + } + } + """ + AsyncStreamsTypes; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "2 4 -1 Done").VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefStructEnumerable_Iterator() + { + var source = """ + using System; + using System.Collections.Generic; + public class C + { + public static void Main() + { + foreach (var i in M()) + { + Console.Write($"{i} "); + } + Console.Write("Done"); + } + public static IEnumerable M() + { + foreach (var x in new Enumerable()) + { + yield return x * 2; + } + yield return -1; + } + public ref struct Enumerable + { + public Enumerator GetEnumerator() => new(); + } + public class Enumerator + { + int i = 0; + public int Current => i; + public bool MoveNext() + { + i++; + return i < 3; + } + } + } + """; + CompileAndVerify(source, expectedOutput: "2 4 -1 Done").VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefStructCurrent_Async() + { + var source = """ + using System; + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (var s in new C()) + { + Console.Write($"{s.ToString()} "); + } + Console.Write("Done"); + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public sealed class Enumerator : IAsyncDisposable + { + int i = 0; + public S Current => new S(i); + public async Task MoveNextAsync() + { + i++; + await Task.Yield(); + return i < 3; + } + public async ValueTask DisposeAsync() + { + await Task.Yield(); + } + } + } + public ref struct S + { + int i; + public S(int i) + { + this.i = i; + } + public override string ToString() => i.ToString(); + } + """ + s_IAsyncEnumerable; + + var expectedDiagnostics = new[] + { + // (7,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 24) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + + var expectedOutput = "1 2 Done"; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefStructCurrent_AsyncIterator() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (var s in M()) + { + Console.Write($"M:{s} "); + } + Console.Write("MainDone"); + } + public static async IAsyncEnumerable M() + { + await foreach (var s in new C()) + { + yield return s.ToString(); + } + yield return "Done"; + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public sealed class Enumerator : IAsyncDisposable + { + int i = 0; + public S Current => new S(i); + public async Task MoveNextAsync() + { + i++; + await Task.Yield(); + return i < 3; + } + public async ValueTask DisposeAsync() + { + await Task.Yield(); + } + } + } + public ref struct S + { + int i; + public S(int i) + { + this.i = i; + } + public override string ToString() => i.ToString(); + } + """ + AsyncStreamsTypes; + + var expectedDiagnostics = new[] + { + // (16,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(16, 24) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + + var expectedOutput = "M:1 M:2 M:Done MainDone"; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefStructCurrent_Iterator() + { + var source = """ + using System; + using System.Collections.Generic; + public class C + { + public static void Main() + { + foreach (var s in M()) + { + Console.Write($"M:{s} "); + } + Console.Write("MainDone"); + } + public static IEnumerable M() + { + foreach (var s in new C()) + { + yield return s.ToString(); + } + yield return "Done"; + } + public Enumerator GetEnumerator() => new Enumerator(); + public sealed class Enumerator + { + int i = 0; + public S Current => new S(i); + public bool MoveNext() + { + i++; + return i < 3; + } + } + } + public ref struct S + { + int i; + public S(int i) + { + this.i = i; + } + public override string ToString() => i.ToString(); + } + """; + + var expectedOutput = "M:1 M:2 M:Done MainDone"; + + CompileAndVerify(source, parseOptions: TestOptions.Regular12, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + CompileAndVerify(source, parseOptions: TestOptions.RegularNext, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefReturningCurrent_Async() { string source = @" using static System.Console; @@ -1986,6 +2533,275 @@ public override string ToString() CompileAndVerify(comp, expectedOutput: "1 2 3 Done", verify: Verification.Fails); } + [Fact] + public void TestWithPattern_RefReturningCurrent_Async_RefVariable() + { + string source = """ + using System; + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (ref var s in new C()) + { + Console.Write($"{s} "); + s.F++; + } + Console.Write("Done"); + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public sealed class Enumerator + { + S _current; + public ref S Current => ref _current; + public async Task MoveNextAsync() + { + Current = new S(Current.F + 1); + await Task.Yield(); + return Current.F < 4; + } + } + } + public struct S + { + public int F; + public S(int i) + { + this.F = i; + } + public override string ToString() => F.ToString(); + } + """ + s_IAsyncEnumerable; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (ref var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "s").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 32)); + + var expectedOutput = "1 3 Done"; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefReturningCurrent_AsyncIterator_RefVariable_01() + { + string source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + public class C + { + public static async Task Main() + { + await foreach (var s in M()) + { + Console.Write($"M:{s} "); + } + Console.Write("MainDone"); + } + public static async IAsyncEnumerable M() + { + await foreach (ref var s in new C()) + { + s.F++; + yield return s.ToString(); + } + yield return "Done"; + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public sealed class Enumerator + { + S _current; + public ref S Current => ref _current; + public async Task MoveNextAsync() + { + Current = new S(Current.F + 1); + await Task.Yield(); + return Current.F < 4; + } + } + } + public struct S + { + public int F; + public S(int i) + { + this.F = i; + } + public override string ToString() => F.ToString(); + } + """ + AsyncStreamsTypes; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (16,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (ref var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "s").WithArguments("ref and unsafe in async and iterator methods").WithLocation(16, 32)); + + var expectedOutput = "M:2 M:4 M:Done MainDone"; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefReturningCurrent_AsyncIterator_RefVariable_02() + { + string source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + public class C + { + public static async IAsyncEnumerable M() + { + await foreach (ref var s in new C()) + { + yield return s.ToString(); + s.F++; + } + yield return "Done"; + } + public Enumerator GetAsyncEnumerator() => new Enumerator(); + public sealed class Enumerator + { + public ref S Current => throw null; + public Task MoveNextAsync() => throw null; + } + } + public struct S + { + public int F; + } + """ + AsyncStreamsTypes; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,32): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (ref var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "s").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 32)); + + var expectedDiagnostics = new[] + { + // (10,13): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // s.F++; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "s.F").WithLocation(10, 13) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilationWithTasksExtensions(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void TestWithPattern_RefReturningCurrent_Iterator_RefVariable_01() + { + string source = """ + using System; + using System.Collections.Generic; + public class C + { + public static void Main() + { + foreach (var s in M()) + { + Console.Write($"M:{s} "); + } + Console.Write("MainDone"); + } + public static IEnumerable M() + { + foreach (ref var s in new C()) + { + s.F++; + yield return s.ToString(); + } + yield return "Done"; + } + public Enumerator GetEnumerator() => new Enumerator(); + public sealed class Enumerator + { + S _current; + public ref S Current => ref _current; + public bool MoveNext() + { + Current = new S(Current.F + 1); + return Current.F < 4; + } + } + } + public struct S + { + public int F; + public S(int i) + { + this.F = i; + } + public override string ToString() => F.ToString(); + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (15,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "s").WithArguments("ref and unsafe in async and iterator methods").WithLocation(15, 26)); + + var expectedOutput = "M:2 M:4 M:Done MainDone"; + + CompileAndVerify(source, parseOptions: TestOptions.RegularNext, expectedOutput: expectedOutput).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void TestWithPattern_RefReturningCurrent_Iterator_RefVariable_02() + { + string source = """ + using System.Collections.Generic; + public class C + { + public static IEnumerable M() + { + foreach (ref var s in new C()) + { + yield return s.ToString(); + s.F++; + } + yield return "Done"; + } + public Enumerator GetEnumerator() => new Enumerator(); + public sealed class Enumerator + { + public ref S Current => throw null; + public bool MoveNext() => throw null; + } + } + public struct S + { + public int F; + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref var s in new C()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "s").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 26)); + + var expectedDiagnostics = new[] + { + // (9,13): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // s.F++; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "s.F").WithLocation(9, 13) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + [Fact] public void TestWithPattern_IterationVariableIsReadOnly() { diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs index c388178fb6771..7282e99ed475f 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitUsingTests.cs @@ -3084,5 +3084,440 @@ public void Dispose() comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "DISPOSED"); } + + [Fact] + public void RefStruct_AwaitInside() + { + var source = """ + using System.Threading.Tasks; + class C + { + async Task M() + { + using (new R()) + { + await Task.Yield(); + } + } + } + ref struct R + { + public void Dispose() { } + } + """; + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,16): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // using (new R()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new R()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 16)); + + var expectedDiagnostics = new[] + { + // (6,16): error CS4007: Instance of type 'R' cannot be preserved across 'await' or 'yield' boundary. + // using (new R()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new R()").WithArguments("R").WithLocation(6, 16) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_YieldReturnInside() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M() + { + using (new R()) + { + yield return 1; + } + } + } + ref struct R + { + public void Dispose() { } + } + """; + + var expectedDiagnostics = new[] + { + // (6,16): error CS4007: Instance of type 'R' cannot be preserved across 'await' or 'yield' boundary. + // using (new R()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new R()").WithArguments("R").WithLocation(6, 16) + }; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_YieldBreakInside() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var x in M(true)) { Console.Write(x); } + Console.Write(" "); + foreach (var x in M(false)) { Console.Write(x); } + } + static IEnumerable M(bool b) + { + yield return 123; + using (new R()) + { + if (b) { yield break; } + } + yield return 456; + } + } + ref struct R + { + public R() => Console.Write("C"); + public void Dispose() => Console.Write("D"); + } + """; + + var expectedOutput = "123CD 123CD456"; + + CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_AwaitResource() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + Console.Write("1"); + using ((await GetC()).GetR()) + { + Console.Write("2"); + } + Console.Write("3"); + } + static async Task GetC() + { + Console.Write("Ga"); + await Task.Yield(); + Console.Write("Gb"); + return new C(); + } + R GetR() => new R(); + } + ref struct R + { + public R() => Console.Write("C"); + public void Dispose() => Console.Write("D"); + } + """; + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,16): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // using ((await GetC()).GetR()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "(await GetC()).GetR()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 16)); + + var expectedOutput = "1GaGbC2D3"; + + CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext, verify: Verification.FailsILVerify).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput, verify: Verification.FailsILVerify).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_AwaitOutside() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + Console.Write("1"); + await Task.Yield(); + Console.Write("2"); + using (new R()) + { + Console.Write("3"); + } + Console.Write("4"); + await Task.Yield(); + Console.Write("5"); + } + } + ref struct R + { + public R() => Console.Write("C"); + public void Dispose() => Console.Write("D"); + } + """; + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (10,16): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // using (new R()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new R()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 16)); + + var expectedOutput = "12C3D45"; + + CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_YieldReturnOutside() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var x in M()) + { + Console.Write(x); + } + } + static IEnumerable M() + { + Console.Write("1"); + yield return "a"; + Console.Write("2"); + using (new R()) + { + Console.Write("3"); + } + Console.Write("4"); + yield return "b"; + Console.Write("5"); + } + } + ref struct R + { + public R() => Console.Write("C"); + public void Dispose() => Console.Write("D"); + } + """; + + var expectedOutput = "1a2C3D4b5"; + + CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_AwaitUsing() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + Console.Write("1"); + await using (new R()) + { + Console.Write("2"); + } + Console.Write("3"); + } + } + ref struct R + { + public R() => Console.Write("C"); + public ValueTask DisposeAsync() + { + Console.Write("D"); + return default; + } + } + """; + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new R()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new R()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 22)); + + var expectedOutput = "1C2D3"; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_AwaitUsing_AwaitInside() + { + var source = """ + using System.Threading.Tasks; + class C + { + async Task M() + { + await using (new R()) + { + await Task.Yield(); + } + } + } + ref struct R + { + public ValueTask DisposeAsync() => default; + } + """; + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new R()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new R()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 22)); + + var expectedDiagnostics = new[] + { + // (6,22): error CS4007: Instance of type 'R' cannot be preserved across 'await' or 'yield' boundary. + // await using (new R()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new R()").WithArguments("R").WithLocation(6, 22) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilationWithTasksExtensions(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_AwaitUsing_YieldReturnInside() + { + var source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + async IAsyncEnumerable M() + { + await using (new R()) + { + yield return 123; + } + } + } + ref struct R + { + public ValueTask DisposeAsync() => default; + } + """ + AsyncStreamsTypes; + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new R()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new R()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 22)); + + var expectedDiagnostics = new[] + { + // (7,22): error CS4007: Instance of type 'R' cannot be preserved across 'await' or 'yield' boundary. + // await using (new R()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new R()").WithArguments("R").WithLocation(7, 22) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilationWithTasksExtensions(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_AwaitUsing_YieldReturnInside_Var() + { + var source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + async IAsyncEnumerable M() + { + await using var _ = new R(); + yield return 123; + } + } + ref struct R + { + public ValueTask DisposeAsync() => default; + } + """ + AsyncStreamsTypes; + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,21): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using var _ = new R(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 21)); + + var expectedDiagnostics = new[] + { + // (7,25): error CS4007: Instance of type 'R' cannot be preserved across 'await' or 'yield' boundary. + // await using var _ = new R(); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "_ = new R()").WithArguments("R").WithLocation(7, 25) + }; + + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilationWithTasksExtensions(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_AwaitUsing_YieldBreakInside() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var x in M(true)) { Console.Write(x); } + Console.Write(" "); + await foreach (var x in M(false)) { Console.Write(x); } + } + static async IAsyncEnumerable M(bool b) + { + yield return 1; + await using (new R()) + { + if (b) { yield break; } + } + yield return 2; + } + } + ref struct R + { + public R() => Console.Write("C"); + public ValueTask DisposeAsync() + { + Console.Write("D"); + return default; + } + } + """ + AsyncStreamsTypes; + CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (15,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new R()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new R()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(15, 22)); + + var expectedOutput = "1CD 1CD2"; + + var comp = CreateCompilationWithTasksExtensions(source, parseOptions: TestOptions.RegularNext, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs index 03ec7e35918cc..f6560bb991044 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDynamicTests.cs @@ -8985,38 +8985,66 @@ public void M(C1 c1) "; CompileAndVerifyIL(source, "C.M", @" { - // Code size 91 (0x5b) - .maxstack 5 + // Code size 142 (0x8e) + .maxstack 9 .locals init (object V_0, //lo - object V_1, //ld - bool V_2) + object V_1) //ld IL_0000: ldnull IL_0001: stloc.0 - IL_0002: ldarg.1 - IL_0003: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__1.<>p__0"" - IL_0008: brtrue.s IL_002e - IL_000a: ldc.i4.0 - IL_000b: ldtoken ""bool"" - IL_0010: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0015: ldtoken ""C"" - IL_001a: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_001f: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)"" - IL_0024: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" - IL_0029: stsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__1.<>p__0"" - IL_002e: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__1.<>p__0"" - IL_0033: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" - IL_0038: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__1.<>p__0"" - IL_003d: ldarg.0 - IL_003e: ldfld ""dynamic C.d"" - IL_0043: callvirt ""bool System.Func.Invoke(System.Runtime.CompilerServices.CallSite, object)"" - IL_0048: stloc.2 - IL_0049: ldloca.s V_2 - IL_004b: ldarg.0 - IL_004c: ldflda ""dynamic C.d"" - IL_0051: ldloca.s V_0 - IL_0053: ldloca.s V_1 - IL_0055: callvirt ""void C1.f(ref bool, out dynamic, ref dynamic, out object)"" - IL_005a: ret + IL_0002: ldsfld ""System.Runtime.CompilerServices.CallSite<<>A{00009200}> C.<>o__1.<>p__0"" + IL_0007: brtrue.s IL_0068 + IL_0009: ldc.i4 0x100 + IL_000e: ldstr ""f"" + IL_0013: ldnull + IL_0014: ldtoken ""C"" + IL_0019: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_001e: ldc.i4.5 + IL_001f: newarr ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"" + IL_0024: dup + IL_0025: ldc.i4.0 + IL_0026: ldc.i4.1 + IL_0027: ldnull + IL_0028: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_002d: stelem.ref + IL_002e: dup + IL_002f: ldc.i4.1 + IL_0030: ldc.i4.0 + IL_0031: ldnull + IL_0032: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0037: stelem.ref + IL_0038: dup + IL_0039: ldc.i4.2 + IL_003a: ldc.i4.s 17 + IL_003c: ldnull + IL_003d: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0042: stelem.ref + IL_0043: dup + IL_0044: ldc.i4.3 + IL_0045: ldc.i4.s 9 + IL_0047: ldnull + IL_0048: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_004d: stelem.ref + IL_004e: dup + IL_004f: ldc.i4.4 + IL_0050: ldc.i4.s 17 + IL_0052: ldnull + IL_0053: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0058: stelem.ref + IL_0059: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)"" + IL_005e: call ""System.Runtime.CompilerServices.CallSite<<>A{00009200}> System.Runtime.CompilerServices.CallSite<<>A{00009200}>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" + IL_0063: stsfld ""System.Runtime.CompilerServices.CallSite<<>A{00009200}> C.<>o__1.<>p__0"" + IL_0068: ldsfld ""System.Runtime.CompilerServices.CallSite<<>A{00009200}> C.<>o__1.<>p__0"" + IL_006d: ldfld ""<>A{00009200} System.Runtime.CompilerServices.CallSite<<>A{00009200}>.Target"" + IL_0072: ldsfld ""System.Runtime.CompilerServices.CallSite<<>A{00009200}> C.<>o__1.<>p__0"" + IL_0077: ldarg.1 + IL_0078: ldarg.0 + IL_0079: ldfld ""dynamic C.d"" + IL_007e: ldarg.0 + IL_007f: ldflda ""dynamic C.d"" + IL_0084: ldloca.s V_0 + IL_0086: ldloca.s V_1 + IL_0088: callvirt ""void <>A{00009200}.Invoke(System.Runtime.CompilerServices.CallSite, C1, object, ref object, ref object, ref object)"" + IL_008d: ret } ").VerifyDiagnostics(); } @@ -10433,57 +10461,51 @@ public dynamic M(F f, dynamic d) }"; CompileAndVerifyIL(source, "C.M", @" { - // Code size 204 (0xcc) - .maxstack 6 - IL_0000: ldarg.1 - IL_0001: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_0006: brtrue.s IL_002c - IL_0008: ldc.i4.0 - IL_0009: ldtoken ""int"" - IL_000e: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0013: ldtoken ""C"" - IL_0018: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_001d: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)"" - IL_0022: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" - IL_0027: stsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_002c: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_0031: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" - IL_0036: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_003b: ldarg.2 - IL_003c: callvirt ""int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, object)"" - IL_0041: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__1"" - IL_0046: brtrue.s IL_006c - IL_0048: ldc.i4.0 - IL_0049: ldtoken ""bool"" - IL_004e: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0053: ldtoken ""C"" - IL_0058: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_005d: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)"" - IL_0062: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" - IL_0067: stsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__1"" - IL_006c: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__1"" - IL_0071: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" - IL_0076: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__1"" - IL_007b: ldarg.2 - IL_007c: callvirt ""bool System.Func.Invoke(System.Runtime.CompilerServices.CallSite, object)"" - IL_0081: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__2"" - IL_0086: brtrue.s IL_00ac - IL_0088: ldc.i4.0 - IL_0089: ldtoken ""C"" - IL_008e: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0093: ldtoken ""C"" - IL_0098: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_009d: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)"" - IL_00a2: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" - IL_00a7: stsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__2"" - IL_00ac: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__2"" - IL_00b1: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" - IL_00b6: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__2"" - IL_00bb: ldarg.2 - IL_00bc: callvirt ""C System.Func.Invoke(System.Runtime.CompilerServices.CallSite, object)"" - IL_00c1: callvirt ""int F.Invoke(int, bool, C)"" - IL_00c6: box ""int"" - IL_00cb: ret + // Code size 104 (0x68) + .maxstack 7 + IL_0000: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" + IL_0005: brtrue.s IL_004f + IL_0007: ldc.i4.0 + IL_0008: ldtoken ""C"" + IL_000d: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_0012: ldc.i4.4 + IL_0013: newarr ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"" + IL_0018: dup + IL_0019: ldc.i4.0 + IL_001a: ldc.i4.1 + IL_001b: ldnull + IL_001c: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0021: stelem.ref + IL_0022: dup + IL_0023: ldc.i4.1 + IL_0024: ldc.i4.0 + IL_0025: ldnull + IL_0026: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_002b: stelem.ref + IL_002c: dup + IL_002d: ldc.i4.2 + IL_002e: ldc.i4.0 + IL_002f: ldnull + IL_0030: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0035: stelem.ref + IL_0036: dup + IL_0037: ldc.i4.3 + IL_0038: ldc.i4.0 + IL_0039: ldnull + IL_003a: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_003f: stelem.ref + IL_0040: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Invoke(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Collections.Generic.IEnumerable)"" + IL_0045: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" + IL_004a: stsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" + IL_004f: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" + IL_0054: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" + IL_0059: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" + IL_005e: ldarg.1 + IL_005f: ldarg.2 + IL_0060: ldarg.2 + IL_0061: ldarg.2 + IL_0062: callvirt ""object System.Func.Invoke(System.Runtime.CompilerServices.CallSite, F, object, object, object)"" + IL_0067: ret } "); } @@ -12222,30 +12244,48 @@ public struct S CompileAndVerifyIL(source, "C.M", @" { - // Code size 81 (0x51) - .maxstack 4 + // Code size 104 (0x68) + .maxstack 7 .locals init (S V_0) //s IL_0000: ldloca.s V_0 IL_0002: initobj ""S"" - IL_0008: ldloca.s V_0 - IL_000a: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_000f: brtrue.s IL_0035 - IL_0011: ldc.i4.0 - IL_0012: ldtoken ""int"" - IL_0017: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_001c: ldtoken ""C"" - IL_0021: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0026: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)"" - IL_002b: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" - IL_0030: stsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_0035: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_003a: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" - IL_003f: ldsfld ""System.Runtime.CompilerServices.CallSite> C.<>o__0.<>p__0"" - IL_0044: ldarg.1 - IL_0045: callvirt ""int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, object)"" - IL_004a: ldc.i4.1 - IL_004b: call ""void S.this[int].set"" - IL_0050: ret + IL_0008: ldsfld ""System.Runtime.CompilerServices.CallSite<<>F{00000008}> C.<>o__0.<>p__0"" + IL_000d: brtrue.s IL_004e + IL_000f: ldc.i4.0 + IL_0010: ldtoken ""C"" + IL_0015: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_001a: ldc.i4.3 + IL_001b: newarr ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"" + IL_0020: dup + IL_0021: ldc.i4.0 + IL_0022: ldc.i4.s 9 + IL_0024: ldnull + IL_0025: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_002a: stelem.ref + IL_002b: dup + IL_002c: ldc.i4.1 + IL_002d: ldc.i4.0 + IL_002e: ldnull + IL_002f: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0034: stelem.ref + IL_0035: dup + IL_0036: ldc.i4.2 + IL_0037: ldc.i4.3 + IL_0038: ldnull + IL_0039: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_003e: stelem.ref + IL_003f: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.SetIndex(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Collections.Generic.IEnumerable)"" + IL_0044: call ""System.Runtime.CompilerServices.CallSite<<>F{00000008}> System.Runtime.CompilerServices.CallSite<<>F{00000008}>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" + IL_0049: stsfld ""System.Runtime.CompilerServices.CallSite<<>F{00000008}> C.<>o__0.<>p__0"" + IL_004e: ldsfld ""System.Runtime.CompilerServices.CallSite<<>F{00000008}> C.<>o__0.<>p__0"" + IL_0053: ldfld ""<>F{00000008} System.Runtime.CompilerServices.CallSite<<>F{00000008}>.Target"" + IL_0058: ldsfld ""System.Runtime.CompilerServices.CallSite<<>F{00000008}> C.<>o__0.<>p__0"" + IL_005d: ldloca.s V_0 + IL_005f: ldarg.1 + IL_0060: ldc.i4.1 + IL_0061: callvirt ""object <>F{00000008}.Invoke(System.Runtime.CompilerServices.CallSite, ref S, object, int)"" + IL_0066: pop + IL_0067: ret } "); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs index 02e78c10d25be..8e3f8539de191 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCoalescingAssignmentTests.cs @@ -2709,9 +2709,10 @@ void M() // (8,9): error CS0019: Operator '??=' cannot be applied to operands of type 'Span' and 'Span' // s1 ??= new Span(); Diagnostic(ErrorCode.ERR_BadBinaryOps, "s1 ??= new Span()").WithArguments("??=", "System.Span", "System.Span").WithLocation(8, 9), - // (9,9): error CS0306: The type 'Span' may not be used as a type argument + // (9,9): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // Span? s2 = null; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "Span?").WithArguments("System.Span").WithLocation(9, 9)); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Span?").WithArguments("System.Nullable", "T", "System.Span").WithLocation(9, 9) + ); } [Fact] diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenOptimizedNullableOperators.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenOptimizedNullableOperators.cs index 53e966a5b90ad..dff16da5b01e6 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenOptimizedNullableOperators.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenOptimizedNullableOperators.cs @@ -3391,10 +3391,59 @@ .locals init (int? V_0, verifier.VerifyIL("C.M", il); } + [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Double_E0([CombinatorialValues("0d", "0.0")] string rhs) + { + var source = $$""" + C.Run(0d); + C.Run(0.0); + C.Run(1.0); + C.Run(1.2); + C.Run(null); + + class C + { + public static void Run(double? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(double? x) => x == {{rhs}}; + } + """; + var output = "11000"; + var il = """ + { + // Code size 31 (0x1f) + .maxstack 2 + .locals init (double? V_0, + double V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.r8 0 + IL_000b: stloc.1 + IL_000c: ldloca.s V_0 + IL_000e: call "double double?.GetValueOrDefault()" + IL_0013: ldloc.1 + IL_0014: ceq + IL_0016: ldloca.s V_0 + IL_0018: call "bool double?.HasValue.get" + IL_001d: and + IL_001e: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] public void NullableConstant_Double_G1() { var source = """ + C.Run(0d); C.Run(0.0); C.Run(1.0); C.Run(1.2); @@ -3409,7 +3458,7 @@ public static void Run(double? x) static bool M(double? x) => x > 1.0; } """; - var output = "0010"; + var output = "00010"; var il = """ { // Code size 31 (0x1f) @@ -3442,6 +3491,7 @@ .locals init (double? V_0, public void NullableConstant_Double_LE1() { var source = """ + C.Run(0d); C.Run(0.0); C.Run(1.0); C.Run(1.2); @@ -3456,7 +3506,7 @@ public static void Run(double? x) static bool M(double? x) => x <= 1.0; } """; - var output = "1100"; + var output = "11100"; var il = """ { // Code size 34 (0x22) @@ -3486,5 +3536,1585 @@ .locals init (double? V_0, verifier.VerifyDiagnostics(); verifier.VerifyIL("C.M", il); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Decimal_E0() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => x == 0m; + } + """; + var output = "1100011"; + var il = """ + { + // Code size 32 (0x20) + .maxstack 2 + .locals init (decimal? V_0, + decimal V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_1 + IL_0004: initobj "decimal" + IL_000a: ldloca.s V_0 + IL_000c: call "decimal decimal?.GetValueOrDefault()" + IL_0011: ldloc.1 + IL_0012: call "bool decimal.op_Equality(decimal, decimal)" + IL_0017: ldloca.s V_0 + IL_0019: call "bool decimal?.HasValue.get" + IL_001e: and + IL_001f: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + [WorkItem("https://github.com/dotnet/roslyn/issues/73510")] + public void NullableConstant_Decimal_E00() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => x == 0.0m; + } + """; + var output = "1100011"; + var il = """ + { + // Code size 36 (0x24) + .maxstack 6 + .locals init (decimal? V_0, + decimal V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_1 + IL_0004: ldc.i4.0 + IL_0005: ldc.i4.0 + IL_0006: ldc.i4.0 + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: call "decimal..ctor(int, int, int, bool, byte)" + IL_000e: ldloca.s V_0 + IL_0010: call "decimal decimal?.GetValueOrDefault()" + IL_0015: ldloc.1 + IL_0016: call "bool decimal.op_Equality(decimal, decimal)" + IL_001b: ldloca.s V_0 + IL_001d: call "bool decimal?.HasValue.get" + IL_0022: and + IL_0023: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + [WorkItem("https://github.com/dotnet/roslyn/issues/73510")] + public void NullableConstant_Decimal_00E() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => 0.0m == x; + } + """; + var output = "1100011"; + var il = """ + { + // Code size 33 (0x21) + .maxstack 5 + .locals init (decimal? V_0) + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.0 + IL_0004: ldc.i4.1 + IL_0005: newobj "decimal..ctor(int, int, int, bool, byte)" + IL_000a: ldarg.0 + IL_000b: stloc.0 + IL_000c: ldloca.s V_0 + IL_000e: call "decimal decimal?.GetValueOrDefault()" + IL_0013: call "bool decimal.op_Equality(decimal, decimal)" + IL_0018: ldloca.s V_0 + IL_001a: call "bool decimal?.HasValue.get" + IL_001f: and + IL_0020: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + [WorkItem("https://github.com/dotnet/roslyn/issues/73510")] + public void NullableConstant_Decimal_E000() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => x == 0.00m; + } + """; + var output = "1100011"; + var il = """ + { + // Code size 36 (0x24) + .maxstack 6 + .locals init (decimal? V_0, + decimal V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_1 + IL_0004: ldc.i4.0 + IL_0005: ldc.i4.0 + IL_0006: ldc.i4.0 + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.2 + IL_0009: call "decimal..ctor(int, int, int, bool, byte)" + IL_000e: ldloca.s V_0 + IL_0010: call "decimal decimal?.GetValueOrDefault()" + IL_0015: ldloc.1 + IL_0016: call "bool decimal.op_Equality(decimal, decimal)" + IL_001b: ldloca.s V_0 + IL_001d: call "bool decimal?.HasValue.get" + IL_0022: and + IL_0023: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + [WorkItem("https://github.com/dotnet/roslyn/issues/73510")] + public void NullableConstant_Decimal_000E() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => 0.00m == x; + } + """; + var output = "1100011"; + var il = """ + { + // Code size 33 (0x21) + .maxstack 5 + .locals init (decimal? V_0) + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.0 + IL_0004: ldc.i4.2 + IL_0005: newobj "decimal..ctor(int, int, int, bool, byte)" + IL_000a: ldarg.0 + IL_000b: stloc.0 + IL_000c: ldloca.s V_0 + IL_000e: call "decimal decimal?.GetValueOrDefault()" + IL_0013: call "bool decimal.op_Equality(decimal, decimal)" + IL_0018: ldloca.s V_0 + IL_001a: call "bool decimal?.HasValue.get" + IL_001f: and + IL_0020: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Decimal_NE00() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => x != 0.0m; + } + """; + var output = "0011100"; + var il = """ + { + // Code size 39 (0x27) + .maxstack 6 + .locals init (decimal? V_0, + decimal V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_1 + IL_0004: ldc.i4.0 + IL_0005: ldc.i4.0 + IL_0006: ldc.i4.0 + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: call "decimal..ctor(int, int, int, bool, byte)" + IL_000e: ldloca.s V_0 + IL_0010: call "decimal decimal?.GetValueOrDefault()" + IL_0015: ldloc.1 + IL_0016: call "bool decimal.op_Equality(decimal, decimal)" + IL_001b: ldloca.s V_0 + IL_001d: call "bool decimal?.HasValue.get" + IL_0022: and + IL_0023: ldc.i4.0 + IL_0024: ceq + IL_0026: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Decimal_00NE() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => 0.0m != x; + } + """; + var output = "0011100"; + var il = """ + { + // Code size 36 (0x24) + .maxstack 5 + .locals init (decimal? V_0) + IL_0000: ldc.i4.0 + IL_0001: ldc.i4.0 + IL_0002: ldc.i4.0 + IL_0003: ldc.i4.0 + IL_0004: ldc.i4.1 + IL_0005: newobj "decimal..ctor(int, int, int, bool, byte)" + IL_000a: ldarg.0 + IL_000b: stloc.0 + IL_000c: ldloca.s V_0 + IL_000e: call "decimal decimal?.GetValueOrDefault()" + IL_0013: call "bool decimal.op_Equality(decimal, decimal)" + IL_0018: ldloca.s V_0 + IL_001a: call "bool decimal?.HasValue.get" + IL_001f: and + IL_0020: ldc.i4.0 + IL_0021: ceq + IL_0023: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Decimal_GE0() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => x >= 0m; + } + """; + var output = "1111011"; + var il = """ + { + // Code size 32 (0x20) + .maxstack 2 + .locals init (decimal? V_0, + decimal V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_1 + IL_0004: initobj "decimal" + IL_000a: ldloca.s V_0 + IL_000c: call "decimal decimal?.GetValueOrDefault()" + IL_0011: ldloc.1 + IL_0012: call "bool decimal.op_GreaterThanOrEqual(decimal, decimal)" + IL_0017: ldloca.s V_0 + IL_0019: call "bool decimal?.HasValue.get" + IL_001e: and + IL_001f: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Decimal_GE00() + { + var source = """ + C.Run(0m); + C.Run(0.0m); + C.Run(1m); + C.Run(2m); + C.Run(null); + C.Run(default(decimal)); + C.Run(decimal.Zero); + + class C + { + public static void Run(decimal? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(decimal? x) => x >= 0.0m; + } + """; + var output = "1111011"; + var il = """ + { + // Code size 36 (0x24) + .maxstack 6 + .locals init (decimal? V_0, + decimal V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_1 + IL_0004: ldc.i4.0 + IL_0005: ldc.i4.0 + IL_0006: ldc.i4.0 + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: call "decimal..ctor(int, int, int, bool, byte)" + IL_000e: ldloca.s V_0 + IL_0010: call "decimal decimal?.GetValueOrDefault()" + IL_0015: ldloc.1 + IL_0016: call "bool decimal.op_GreaterThanOrEqual(decimal, decimal)" + IL_001b: ldloca.s V_0 + IL_001d: call "bool decimal?.HasValue.get" + IL_0022: and + IL_0023: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Byte_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(byte? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(byte? x) => x == (byte)0; + } + """; + var output = "1000"; + var il = """ + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (int? V_0, + int V_1, + byte? V_2, + int? V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: call "bool byte?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_3 + IL_000d: initobj "int?" + IL_0013: ldloc.3 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_2 + IL_0018: call "byte byte?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.0 + IL_0023: ldc.i4.0 + IL_0024: stloc.1 + IL_0025: ldloca.s V_0 + IL_0027: call "int int?.GetValueOrDefault()" + IL_002c: ldloc.1 + IL_002d: ceq + IL_002f: ldloca.s V_0 + IL_0031: call "bool int?.HasValue.get" + IL_0036: and + IL_0037: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Byte_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(byte? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(byte? x) => x == 1; + } + """; + var output = "0100"; + var il = """ + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (byte? V_0, + int? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call "bool byte?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_1 + IL_000d: initobj "int?" + IL_0013: ldloc.1 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_0 + IL_0018: call "byte byte?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.1 + IL_0023: ldloca.s V_1 + IL_0025: call "int int?.GetValueOrDefault()" + IL_002a: ldc.i4.1 + IL_002b: ceq + IL_002d: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Char_E0() + { + var source = """ + C.Run('\0'); + C.Run(default(char)); + C.Run('A'); + C.Run('\x1'); + C.Run(null); + + class C + { + public static void Run(char? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(char? x) => x == '\0'; + } + """; + var output = "11000"; + var il = """ + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (int? V_0, + int V_1, + char? V_2, + int? V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: call "bool char?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_3 + IL_000d: initobj "int?" + IL_0013: ldloc.3 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_2 + IL_0018: call "char char?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.0 + IL_0023: ldc.i4.0 + IL_0024: stloc.1 + IL_0025: ldloca.s V_0 + IL_0027: call "int int?.GetValueOrDefault()" + IL_002c: ldloc.1 + IL_002d: ceq + IL_002f: ldloca.s V_0 + IL_0031: call "bool int?.HasValue.get" + IL_0036: and + IL_0037: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Char_E1() + { + var source = """ + C.Run('\0'); + C.Run(default(char)); + C.Run('A'); + C.Run('\x1'); + C.Run(null); + + class C + { + public static void Run(char? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(char? x) => x == '\x1'; + } + """; + var output = "00010"; + var il = """ + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (int? V_0, + int V_1, + char? V_2, + int? V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: call "bool char?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_3 + IL_000d: initobj "int?" + IL_0013: ldloc.3 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_2 + IL_0018: call "char char?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.0 + IL_0023: ldc.i4.1 + IL_0024: stloc.1 + IL_0025: ldloca.s V_0 + IL_0027: call "int int?.GetValueOrDefault()" + IL_002c: ldloc.1 + IL_002d: ceq + IL_002f: ldloca.s V_0 + IL_0031: call "bool int?.HasValue.get" + IL_0036: and + IL_0037: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_UInt_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(uint? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(uint? x) => x == 0U; + } + """; + var output = "1000"; + var il = """ + { + // Code size 23 (0x17) + .maxstack 2 + .locals init (uint? V_0, + uint V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: stloc.1 + IL_0004: ldloca.s V_0 + IL_0006: call "uint uint?.GetValueOrDefault()" + IL_000b: ldloc.1 + IL_000c: ceq + IL_000e: ldloca.s V_0 + IL_0010: call "bool uint?.HasValue.get" + IL_0015: and + IL_0016: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_UInt_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(uint? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(uint? x) => x == 1U; + } + """; + var output = "0100"; + var il = """ + { + // Code size 11 (0xb) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: call "uint uint?.GetValueOrDefault()" + IL_0007: ldc.i4.1 + IL_0008: ceq + IL_000a: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Short_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(short? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(short? x) => x == (short)0; + } + """; + var output = "1000"; + var il = """ + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (int? V_0, + int V_1, + short? V_2, + int? V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: call "bool short?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_3 + IL_000d: initobj "int?" + IL_0013: ldloc.3 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_2 + IL_0018: call "short short?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.0 + IL_0023: ldc.i4.0 + IL_0024: stloc.1 + IL_0025: ldloca.s V_0 + IL_0027: call "int int?.GetValueOrDefault()" + IL_002c: ldloc.1 + IL_002d: ceq + IL_002f: ldloca.s V_0 + IL_0031: call "bool int?.HasValue.get" + IL_0036: and + IL_0037: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Short_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(short? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(short? x) => x == 1; + } + """; + var output = "0100"; + var il = """ + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (short? V_0, + int? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call "bool short?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_1 + IL_000d: initobj "int?" + IL_0013: ldloc.1 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_0 + IL_0018: call "short short?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.1 + IL_0023: ldloca.s V_1 + IL_0025: call "int int?.GetValueOrDefault()" + IL_002a: ldc.i4.1 + IL_002b: ceq + IL_002d: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_UShort_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(ushort? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(ushort? x) => x == (ushort)0; + } + """; + var output = "1000"; + var il = """ + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (int? V_0, + int V_1, + ushort? V_2, + int? V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: call "bool ushort?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_3 + IL_000d: initobj "int?" + IL_0013: ldloc.3 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_2 + IL_0018: call "ushort ushort?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.0 + IL_0023: ldc.i4.0 + IL_0024: stloc.1 + IL_0025: ldloca.s V_0 + IL_0027: call "int int?.GetValueOrDefault()" + IL_002c: ldloc.1 + IL_002d: ceq + IL_002f: ldloca.s V_0 + IL_0031: call "bool int?.HasValue.get" + IL_0036: and + IL_0037: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_UShort_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(ushort? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(ushort? x) => x == 1; + } + """; + var output = "0100"; + var il = """ + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (ushort? V_0, + int? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call "bool ushort?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_1 + IL_000d: initobj "int?" + IL_0013: ldloc.1 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_0 + IL_0018: call "ushort ushort?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.1 + IL_0023: ldloca.s V_1 + IL_0025: call "int int?.GetValueOrDefault()" + IL_002a: ldc.i4.1 + IL_002b: ceq + IL_002d: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Long_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(long? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(long? x) => x == 0L; + } + """; + var output = "1000"; + var il = """ + { + // Code size 24 (0x18) + .maxstack 2 + .locals init (long? V_0, + long V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: conv.i8 + IL_0004: stloc.1 + IL_0005: ldloca.s V_0 + IL_0007: call "long long?.GetValueOrDefault()" + IL_000c: ldloc.1 + IL_000d: ceq + IL_000f: ldloca.s V_0 + IL_0011: call "bool long?.HasValue.get" + IL_0016: and + IL_0017: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Long_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(long? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(long? x) => x == 1L; + } + """; + var output = "0100"; + var il = """ + { + // Code size 12 (0xc) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: call "long long?.GetValueOrDefault()" + IL_0007: ldc.i4.1 + IL_0008: conv.i8 + IL_0009: ceq + IL_000b: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_ULong_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(ulong? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(ulong? x) => x == 0UL; + } + """; + var output = "1000"; + var il = """ + { + // Code size 24 (0x18) + .maxstack 2 + .locals init (ulong? V_0, + ulong V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: conv.i8 + IL_0004: stloc.1 + IL_0005: ldloca.s V_0 + IL_0007: call "ulong ulong?.GetValueOrDefault()" + IL_000c: ldloc.1 + IL_000d: ceq + IL_000f: ldloca.s V_0 + IL_0011: call "bool ulong?.HasValue.get" + IL_0016: and + IL_0017: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_ULong_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(ulong? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(ulong? x) => x == 1UL; + } + """; + var output = "0100"; + var il = """ + { + // Code size 12 (0xc) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: call "ulong ulong?.GetValueOrDefault()" + IL_0007: ldc.i4.1 + IL_0008: conv.i8 + IL_0009: ceq + IL_000b: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_NInt_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(nint? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(nint? x) => x == (nint)0; + } + """; + var output = "1000"; + var il = """ + { + // Code size 24 (0x18) + .maxstack 2 + .locals init (nint? V_0, + System.IntPtr V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: conv.i + IL_0004: stloc.1 + IL_0005: ldloca.s V_0 + IL_0007: call "nint nint?.GetValueOrDefault()" + IL_000c: ldloc.1 + IL_000d: ceq + IL_000f: ldloca.s V_0 + IL_0011: call "bool nint?.HasValue.get" + IL_0016: and + IL_0017: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_NInt_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(nint? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(nint? x) => x == (nint)1; + } + """; + var output = "0100"; + var il = """ + { + // Code size 12 (0xc) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: call "nint nint?.GetValueOrDefault()" + IL_0007: ldc.i4.1 + IL_0008: conv.i + IL_0009: ceq + IL_000b: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_NUInt_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(nuint? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(nuint? x) => x == (nuint)0; + } + """; + var output = "1000"; + var il = """ + { + // Code size 24 (0x18) + .maxstack 2 + .locals init (nuint? V_0, + System.UIntPtr V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.0 + IL_0003: conv.i + IL_0004: stloc.1 + IL_0005: ldloca.s V_0 + IL_0007: call "nuint nuint?.GetValueOrDefault()" + IL_000c: ldloc.1 + IL_000d: ceq + IL_000f: ldloca.s V_0 + IL_0011: call "bool nuint?.HasValue.get" + IL_0016: and + IL_0017: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_NUInt_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(nuint? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(nuint? x) => x == (nuint)1; + } + """; + var output = "0100"; + var il = """ + { + // Code size 12 (0xc) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: call "nuint nuint?.GetValueOrDefault()" + IL_0007: ldc.i4.1 + IL_0008: conv.i + IL_0009: ceq + IL_000b: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_SByte_E0() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(sbyte? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(sbyte? x) => x == (sbyte)0; + } + """; + var output = "1000"; + var il = """ + { + // Code size 56 (0x38) + .maxstack 2 + .locals init (int? V_0, + int V_1, + sbyte? V_2, + int? V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: call "bool sbyte?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_3 + IL_000d: initobj "int?" + IL_0013: ldloc.3 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_2 + IL_0018: call "sbyte sbyte?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.0 + IL_0023: ldc.i4.0 + IL_0024: stloc.1 + IL_0025: ldloca.s V_0 + IL_0027: call "int int?.GetValueOrDefault()" + IL_002c: ldloc.1 + IL_002d: ceq + IL_002f: ldloca.s V_0 + IL_0031: call "bool int?.HasValue.get" + IL_0036: and + IL_0037: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_SByte_E1() + { + var source = """ + C.Run(0); + C.Run(1); + C.Run(2); + C.Run(null); + + class C + { + public static void Run(sbyte? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(sbyte? x) => x == 1; + } + """; + var output = "0100"; + var il = """ + { + // Code size 46 (0x2e) + .maxstack 2 + .locals init (sbyte? V_0, + int? V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: call "bool sbyte?.HasValue.get" + IL_0009: brtrue.s IL_0016 + IL_000b: ldloca.s V_1 + IL_000d: initobj "int?" + IL_0013: ldloc.1 + IL_0014: br.s IL_0022 + IL_0016: ldloca.s V_0 + IL_0018: call "sbyte sbyte?.GetValueOrDefault()" + IL_001d: newobj "int?..ctor(int)" + IL_0022: stloc.1 + IL_0023: ldloca.s V_1 + IL_0025: call "int int?.GetValueOrDefault()" + IL_002a: ldc.i4.1 + IL_002b: ceq + IL_002d: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Single_E0() + { + var source = """ + C.Run(0f); + C.Run(0.0f); + C.Run(default(float)); + C.Run(1f); + C.Run(2f); + C.Run(null); + + class C + { + public static void Run(float? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(float? x) => x == 0f; + } + """; + var output = "111000"; + var il = """ + { + // Code size 27 (0x1b) + .maxstack 2 + .locals init (float? V_0, + float V_1) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.r4 0 + IL_0007: stloc.1 + IL_0008: ldloca.s V_0 + IL_000a: call "float float?.GetValueOrDefault()" + IL_000f: ldloc.1 + IL_0010: ceq + IL_0012: ldloca.s V_0 + IL_0014: call "bool float?.HasValue.get" + IL_0019: and + IL_001a: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/52629")] + public void NullableConstant_Single_E1() + { + var source = """ + C.Run(0f); + C.Run(0.0f); + C.Run(default(float)); + C.Run(1f); + C.Run(2f); + C.Run(null); + + class C + { + public static void Run(float? x) + { + System.Console.Write(M(x) ? 1 : 0); + } + static bool M(float? x) => x == 1f; + } + """; + var output = "000100"; + var il = """ + { + // Code size 15 (0xf) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: call "float float?.GetValueOrDefault()" + IL_0007: ldc.r4 1 + IL_000c: ceq + IL_000e: ret + } + """; + var verifier = CompileAndVerify(source, options: TestOptions.ReleaseExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + verifier = CompileAndVerify(source, options: TestOptions.DebugExe, expectedOutput: output); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.M", il); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs index 63e3e41ef313a..41f0fcafaf00d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenStructsAndEnum.cs @@ -2288,7 +2288,7 @@ public static void Eval(object obj1, object obj2) compilation.VerifyIL("NullableTest.EqualEqual", @" { - // Code size 101 (0x65) + // Code size 112 (0x70) .maxstack 2 .locals init (decimal? V_0) IL_0000: ldc.i4.0 @@ -2297,27 +2297,32 @@ .locals init (decimal? V_0) IL_0007: box ""bool"" IL_000c: call ""void Test.Eval(object, object)"" IL_0011: ldsfld ""decimal decimal.One"" - IL_0016: ldsflda ""decimal? NullableTest.NULL"" - IL_001b: call ""decimal decimal?.GetValueOrDefault()"" - IL_0020: call ""bool decimal.op_Equality(decimal, decimal)"" - IL_0025: box ""bool"" - IL_002a: ldc.i4.0 - IL_002b: box ""bool"" - IL_0030: call ""void Test.Eval(object, object)"" - IL_0035: ldsfld ""decimal decimal.Zero"" - IL_003a: ldsfld ""decimal? NullableTest.NULL"" - IL_003f: stloc.0 - IL_0040: ldloca.s V_0 - IL_0042: call ""decimal decimal?.GetValueOrDefault()"" - IL_0047: call ""bool decimal.op_Equality(decimal, decimal)"" - IL_004c: ldloca.s V_0 - IL_004e: call ""bool decimal?.HasValue.get"" - IL_0053: and - IL_0054: box ""bool"" - IL_0059: ldc.i4.0 - IL_005a: box ""bool"" - IL_005f: call ""void Test.Eval(object, object)"" - IL_0064: ret + IL_0016: ldsfld ""decimal? NullableTest.NULL"" + IL_001b: stloc.0 + IL_001c: ldloca.s V_0 + IL_001e: call ""decimal decimal?.GetValueOrDefault()"" + IL_0023: call ""bool decimal.op_Equality(decimal, decimal)"" + IL_0028: ldloca.s V_0 + IL_002a: call ""bool decimal?.HasValue.get"" + IL_002f: and + IL_0030: box ""bool"" + IL_0035: ldc.i4.0 + IL_0036: box ""bool"" + IL_003b: call ""void Test.Eval(object, object)"" + IL_0040: ldsfld ""decimal decimal.Zero"" + IL_0045: ldsfld ""decimal? NullableTest.NULL"" + IL_004a: stloc.0 + IL_004b: ldloca.s V_0 + IL_004d: call ""decimal decimal?.GetValueOrDefault()"" + IL_0052: call ""bool decimal.op_Equality(decimal, decimal)"" + IL_0057: ldloca.s V_0 + IL_0059: call ""bool decimal?.HasValue.get"" + IL_005e: and + IL_005f: box ""bool"" + IL_0064: ldc.i4.0 + IL_0065: box ""bool"" + IL_006a: call ""void Test.Eval(object, object)"" + IL_006f: ret } "); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs index d427589e7c5dd..190e152c175b4 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTests.cs @@ -15740,7 +15740,7 @@ static void Main() } "; - var compilation = CompileAndVerifyWithMscorlib40(source, new[] { SystemCoreRef, CSharpRef }, expectedOutput: "long.long.2"); + var compilation = CompileAndVerifyWithMscorlib40(source, new[] { SystemCoreRef, CSharpRef }, expectedOutput: "long.ex caught"); } [WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")] diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs index 74fa756437854..0bf80048648fe 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs @@ -1942,18 +1942,18 @@ void M(S s1, S s2) }"; var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (6,35): error CS0306: The type 'S' may not be used as a type argument + // (6,35): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // System.Console.Write(("", s1) == (null, s2)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "s1").WithArguments("S").WithLocation(6, 35), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "s1").WithArguments("(T1, T2)", "T2", "S").WithLocation(6, 35), // (6,30): error CS0019: Operator '==' cannot be applied to operands of type 'S' and 'S' // System.Console.Write(("", s1) == (null, s2)); Diagnostic(ErrorCode.ERR_BadBinaryOps, @"("""", s1) == (null, s2)").WithArguments("==", "S", "S").WithLocation(6, 30), - // (6,35): error CS0306: The type 'S' may not be used as a type argument + // (6,35): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // System.Console.Write(("", s1) == (null, s2)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "s1").WithArguments("S").WithLocation(6, 35), - // (6,49): error CS0306: The type 'S' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "s1").WithArguments("(T1, T2)", "T2", "S").WithLocation(6, 35), + // (6,49): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // System.Console.Write(("", s1) == (null, s2)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "s2").WithArguments("S").WithLocation(6, 49) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "s2").WithArguments("(T1, T2)", "T2", "S").WithLocation(6, 49) ); } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/GotoTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/GotoTest.cs index 68a43d7eda5f7..bd68eefaa1e3e 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/GotoTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/GotoTest.cs @@ -550,6 +550,115 @@ .maxstack 2 "); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73068")] + public void GotoInLambda_OutOfScope_Backward() + { + var code = """ + x: + System.Action a = () => + { + using System.IDisposable d = null; + goto x; + }; + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (1,1): warning CS0164: This label has not been referenced + // x: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "x").WithLocation(1, 1), + // (5,5): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("x").WithLocation(5, 5)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73068")] + public void GotoInLambda_OutOfScope_Forward() + { + var code = """ + System.Action a = () => + { + using System.IDisposable d = null; + goto x; + }; + x:; + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (4,5): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("x").WithLocation(4, 5), + // (6,1): warning CS0164: This label has not been referenced + // x:; + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "x").WithLocation(6, 1)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73068")] + public void GotoInLambda_NonExistent() + { + var code = """ + System.Action a = () => + { + using System.IDisposable d = null; + goto x; + }; + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (4,10): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "x").WithArguments("x").WithLocation(4, 10)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73397")] + public void GotoInLocalFunc_OutOfScope_Backward() + { + var code = """ + #pragma warning disable CS8321 // local function unused + x: + void localFunc() + { + using System.IDisposable d = null; + goto x; + } + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (6,5): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("x").WithLocation(6, 5)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73397")] + public void GotoInLocalFunc_OutOfScope_Forward() + { + var code = """ + #pragma warning disable CS8321 // local function unused + void localFunc() + { + using System.IDisposable d = null; + goto x; + } + x:; + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (5,5): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("x").WithLocation(5, 5)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73397")] + public void GotoInLocalFunc_NonExistent() + { + var code = """ + #pragma warning disable CS8321 // local function unused + void localFunc() + { + using System.IDisposable d = null; + goto x; + } + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (5,10): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "x").WithArguments("x").WithLocation(5, 10)); + } + // Definition same label in different lambdas [WorkItem(5991, "DevDiv_Projects/Roslyn")] [Fact] diff --git a/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenSpanBasedStringConcatTests.cs b/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenSpanBasedStringConcatTests.cs index 48efeed6dbc2b..f0d02647d79a9 100644 --- a/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenSpanBasedStringConcatTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/CodeGen/CodeGenSpanBasedStringConcatTests.cs @@ -47,7 +47,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0014: ret } @@ -60,7 +60,7 @@ .locals init (char V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" @@ -104,7 +104,7 @@ .locals init (char V_0) IL_0007: call "char char.ToLowerInvariant(char)" IL_000c: stloc.0 IL_000d: ldloca.s V_0 - IL_000f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0014: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0019: ret } @@ -118,7 +118,7 @@ .locals init (char V_0) IL_0001: call "char char.ToLowerInvariant(char)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0014: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" @@ -179,7 +179,7 @@ .locals init (char V_0) IL_000a: call "char Test.GetCharWithSideEffect()" IL_000f: stloc.0 IL_0010: ldloca.s V_0 - IL_0012: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0012: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0017: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_001c: ret } @@ -192,7 +192,7 @@ .locals init (char V_0) IL_0000: call "char Test.GetCharWithSideEffect()" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: call "string Test.GetStringWithSideEffect()" IL_0012: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0017: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" @@ -240,13 +240,13 @@ .locals init (char V_0, IL_0001: ldfld "char C.c" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "ref char C.GetC()" IL_0014: ldind.u2 IL_0015: stloc.1 IL_0016: ldloca.s V_1 - IL_0018: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0018: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001d: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0022: call "void System.Console.Write(string)" IL_0027: ret @@ -293,7 +293,7 @@ .locals init (char V_0, //c IL_0003: ldloc.0 IL_0004: stloc.1 IL_0005: ldloca.s V_1 - IL_0007: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0007: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000c: ldarg.0 IL_000d: ldloca.s V_0 IL_000f: call "string C.SneakyLocalChange(ref char)" @@ -497,11 +497,11 @@ .locals init (char V_0, IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.1 IL_000a: stloc.1 IL_000b: ldloca.s V_1 - IL_000d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0012: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0017: ret } @@ -943,7 +943,7 @@ .locals init (int V_0, IL_00cd: ldfld "string Test.d__1.<>7__wrap1" IL_00d2: call "System.ReadOnlySpan string.op_Implicit(string)" IL_00d7: ldloca.s V_2 - IL_00d9: newobj "System.ReadOnlySpan..ctor(in char)" + IL_00d9: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_00de: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_00e3: stloc.1 IL_00e4: leave.s IL_00ff @@ -1014,7 +1014,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0014: ret } @@ -1027,7 +1027,7 @@ .locals init (char V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" @@ -1081,7 +1081,7 @@ .locals init (char V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -1100,7 +1100,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -1119,7 +1119,7 @@ .locals init (char V_0) IL_000c: ldarg.1 IL_000d: stloc.0 IL_000e: ldloca.s V_0 - IL_0010: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0010: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0015: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_001a: ret } @@ -1133,13 +1133,13 @@ .locals init (char V_0, IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.1 IL_0010: stloc.1 IL_0011: ldloca.s V_1 - IL_0013: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0013: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0018: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_001d: ret } @@ -1192,7 +1192,7 @@ .locals init (char V_0) IL_0001: call "char char.ToLowerInvariant(char)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0014: ldarg.0 @@ -1212,7 +1212,7 @@ .locals init (char V_0) IL_0007: call "char char.ToLowerInvariant(char)" IL_000c: stloc.0 IL_000d: ldloca.s V_0 - IL_000f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0014: ldarg.0 IL_0015: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001a: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -1232,7 +1232,7 @@ .locals init (char V_0) IL_000d: call "char char.ToLowerInvariant(char)" IL_0012: stloc.0 IL_0013: ldloca.s V_0 - IL_0015: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0015: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001a: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_001f: ret } @@ -1247,14 +1247,14 @@ .locals init (char V_0, IL_0001: call "char char.ToLowerInvariant(char)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0014: ldarg.1 IL_0015: call "char char.ToLowerInvariant(char)" IL_001a: stloc.1 IL_001b: ldloca.s V_1 - IL_001d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0022: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0027: ret } @@ -1297,7 +1297,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -1371,7 +1371,7 @@ .locals init (char V_0) IL_0000: call "char Test.GetCharWithSideEffect()" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: call "string Test.GetStringWithSideEffect()" IL_0012: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0017: call "string Test.GetStringWithSideEffect()" @@ -1390,7 +1390,7 @@ .locals init (char V_0) IL_000a: call "char Test.GetCharWithSideEffect()" IL_000f: stloc.0 IL_0010: ldloca.s V_0 - IL_0012: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0012: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0017: call "string Test.GetStringWithSideEffect()" IL_001c: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0021: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -1409,7 +1409,7 @@ .locals init (char V_0) IL_0014: call "char Test.GetCharWithSideEffect()" IL_0019: stloc.0 IL_001a: ldloca.s V_0 - IL_001c: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001c: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0021: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0026: ret } @@ -1423,13 +1423,13 @@ .locals init (char V_0, IL_0000: call "char Test.GetCharWithSideEffect()" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: call "string Test.GetStringWithSideEffect()" IL_0012: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0017: call "char Test.GetCharWithSideEffect()" IL_001c: stloc.1 IL_001d: ldloca.s V_1 - IL_001f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0024: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0029: ret } @@ -1484,18 +1484,18 @@ .locals init (char V_0, IL_0000: ldc.i4.s 97 IL_0002: stloc.0 IL_0003: ldloca.s V_0 - IL_0005: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0005: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000a: ldarg.0 IL_000b: ldfld "char C.c" IL_0010: stloc.1 IL_0011: ldloca.s V_1 - IL_0013: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0013: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0018: ldarg.0 IL_0019: call "ref char C.GetC()" IL_001e: ldind.u2 IL_001f: stloc.2 IL_0020: ldloca.s V_2 - IL_0022: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0022: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0027: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_002c: call "void System.Console.Write(string)" IL_0031: ret @@ -1553,17 +1553,17 @@ .locals init (char V_0, //c IL_0003: ldc.i4.s 97 IL_0005: stloc.1 IL_0006: ldloca.s V_1 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: ldloc.0 IL_000e: stloc.2 IL_000f: ldloca.s V_2 - IL_0011: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0011: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0016: ldarg.0 IL_0017: ldloca.s V_0 IL_0019: call "char C.SneakyLocalChange(ref char)" IL_001e: stloc.3 IL_001f: ldloca.s V_3 - IL_0021: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0021: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0026: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_002b: ret } @@ -1616,7 +1616,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0014: ret } @@ -1802,15 +1802,15 @@ .locals init (char V_0, IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.1 IL_000a: stloc.1 IL_000b: ldloca.s V_1 - IL_000d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0012: ldarg.2 IL_0013: stloc.2 IL_0014: ldloca.s V_2 - IL_0016: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0016: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0020: ret } @@ -2004,7 +2004,7 @@ .locals init (char V_0) IL_0011: ldarg.2 IL_0012: stloc.0 IL_0013: ldloca.s V_0 - IL_0015: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0015: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001a: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_001f: ret } @@ -2017,7 +2017,7 @@ .locals init (char V_0) IL_0000: ldarg.2 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: ldarg.1 IL_000b: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" @@ -2530,7 +2530,7 @@ .locals init (int V_0, IL_0142: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0147: ldarg.0 IL_0148: ldflda "char Test.d__1.<>7__wrap1" - IL_014d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_014d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0152: ldloc.3 IL_0153: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0158: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -2605,7 +2605,7 @@ .locals init (char V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -2624,7 +2624,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -2643,7 +2643,7 @@ .locals init (char V_0) IL_000c: ldarg.1 IL_000d: stloc.0 IL_000e: ldloca.s V_0 - IL_0010: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0010: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0015: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_001a: ret } @@ -2657,13 +2657,13 @@ .locals init (char V_0, IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.1 IL_0010: stloc.1 IL_0011: ldloca.s V_1 - IL_0013: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0013: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0018: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_001d: ret } @@ -2722,7 +2722,7 @@ .locals init (char V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -2743,7 +2743,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: ldarg.0 @@ -2764,7 +2764,7 @@ .locals init (char V_0) IL_000c: ldarg.1 IL_000d: stloc.0 IL_000e: ldloca.s V_0 - IL_0010: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0010: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0015: ldarg.0 IL_0016: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -2785,7 +2785,7 @@ .locals init (char V_0) IL_0012: ldarg.1 IL_0013: stloc.0 IL_0014: ldloca.s V_0 - IL_0016: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0016: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0020: ret } @@ -2799,13 +2799,13 @@ .locals init (char V_0, IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.1 IL_0010: stloc.1 IL_0011: ldloca.s V_1 - IL_0013: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0013: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0018: ldarg.0 IL_0019: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -2823,13 +2823,13 @@ .locals init (char V_0, IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: ldarg.1 IL_0016: stloc.1 IL_0017: ldloca.s V_1 - IL_0019: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0019: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0023: ret } @@ -2843,7 +2843,7 @@ .locals init (char V_0, IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -2851,7 +2851,7 @@ .locals init (char V_0, IL_0015: ldarg.1 IL_0016: stloc.1 IL_0017: ldloca.s V_1 - IL_0019: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0019: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0023: ret } @@ -2911,7 +2911,7 @@ .locals init (char V_0) IL_0001: call "char char.ToLowerInvariant(char)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0014: ldarg.0 @@ -2933,7 +2933,7 @@ .locals init (char V_0) IL_0007: call "char char.ToLowerInvariant(char)" IL_000c: stloc.0 IL_000d: ldloca.s V_0 - IL_000f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0014: ldarg.0 IL_0015: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001a: ldarg.0 @@ -2955,7 +2955,7 @@ .locals init (char V_0) IL_000d: call "char char.ToLowerInvariant(char)" IL_0012: stloc.0 IL_0013: ldloca.s V_0 - IL_0015: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0015: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001a: ldarg.0 IL_001b: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0020: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -2977,7 +2977,7 @@ .locals init (char V_0) IL_0013: call "char char.ToLowerInvariant(char)" IL_0018: stloc.0 IL_0019: ldloca.s V_0 - IL_001b: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001b: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0020: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0025: ret } @@ -2992,14 +2992,14 @@ .locals init (char V_0, IL_0001: call "char char.ToLowerInvariant(char)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0014: ldarg.1 IL_0015: call "char char.ToLowerInvariant(char)" IL_001a: stloc.1 IL_001b: ldloca.s V_1 - IL_001d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0022: ldarg.0 IL_0023: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0028: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -3018,14 +3018,14 @@ .locals init (char V_0, IL_0007: call "char char.ToLowerInvariant(char)" IL_000c: stloc.0 IL_000d: ldloca.s V_0 - IL_000f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0014: ldarg.0 IL_0015: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001a: ldarg.1 IL_001b: call "char char.ToLowerInvariant(char)" IL_0020: stloc.1 IL_0021: ldloca.s V_1 - IL_0023: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0023: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0028: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_002d: ret } @@ -3040,7 +3040,7 @@ .locals init (char V_0, IL_0001: call "char char.ToLowerInvariant(char)" IL_0006: stloc.0 IL_0007: ldloca.s V_0 - IL_0009: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000e: ldarg.0 IL_000f: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0014: ldarg.0 @@ -3049,7 +3049,7 @@ .locals init (char V_0, IL_001b: call "char char.ToLowerInvariant(char)" IL_0020: stloc.1 IL_0021: ldloca.s V_1 - IL_0023: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0023: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0028: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_002d: ret } @@ -3100,7 +3100,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: ldarg.0 @@ -3186,7 +3186,7 @@ .locals init (char V_0) IL_0000: call "char Test.GetCharWithSideEffect()" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: call "string Test.GetStringWithSideEffect()" IL_0012: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0017: call "string Test.GetStringWithSideEffect()" @@ -3207,7 +3207,7 @@ .locals init (char V_0) IL_000a: call "char Test.GetCharWithSideEffect()" IL_000f: stloc.0 IL_0010: ldloca.s V_0 - IL_0012: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0012: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0017: call "string Test.GetStringWithSideEffect()" IL_001c: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0021: call "string Test.GetStringWithSideEffect()" @@ -3228,7 +3228,7 @@ .locals init (char V_0) IL_0014: call "char Test.GetCharWithSideEffect()" IL_0019: stloc.0 IL_001a: ldloca.s V_0 - IL_001c: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001c: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0021: call "string Test.GetStringWithSideEffect()" IL_0026: call "System.ReadOnlySpan string.op_Implicit(string)" IL_002b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -3249,7 +3249,7 @@ .locals init (char V_0) IL_001e: call "char Test.GetCharWithSideEffect()" IL_0023: stloc.0 IL_0024: ldloca.s V_0 - IL_0026: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0026: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_002b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0030: ret } @@ -3263,13 +3263,13 @@ .locals init (char V_0, IL_0000: call "char Test.GetCharWithSideEffect()" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: call "string Test.GetStringWithSideEffect()" IL_0012: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0017: call "char Test.GetCharWithSideEffect()" IL_001c: stloc.1 IL_001d: ldloca.s V_1 - IL_001f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0024: call "string Test.GetStringWithSideEffect()" IL_0029: call "System.ReadOnlySpan string.op_Implicit(string)" IL_002e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -3287,13 +3287,13 @@ .locals init (char V_0, IL_000a: call "char Test.GetCharWithSideEffect()" IL_000f: stloc.0 IL_0010: ldloca.s V_0 - IL_0012: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0012: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0017: call "string Test.GetStringWithSideEffect()" IL_001c: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0021: call "char Test.GetCharWithSideEffect()" IL_0026: stloc.1 IL_0027: ldloca.s V_1 - IL_0029: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0029: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_002e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0033: ret } @@ -3307,7 +3307,7 @@ .locals init (char V_0, IL_0000: call "char Test.GetCharWithSideEffect()" IL_0005: stloc.0 IL_0006: ldloca.s V_0 - IL_0008: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000d: call "string Test.GetStringWithSideEffect()" IL_0012: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0017: call "string Test.GetStringWithSideEffect()" @@ -3315,7 +3315,7 @@ .locals init (char V_0, IL_0021: call "char Test.GetCharWithSideEffect()" IL_0026: stloc.1 IL_0027: ldloca.s V_1 - IL_0029: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0029: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_002e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0033: ret } @@ -3374,24 +3374,24 @@ .locals init (char V_0, IL_0000: ldc.i4.s 97 IL_0002: stloc.0 IL_0003: ldloca.s V_0 - IL_0005: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0005: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000a: ldarg.0 IL_000b: ldfld "char C.c" IL_0010: stloc.1 IL_0011: ldloca.s V_1 - IL_0013: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0013: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0018: ldarg.0 IL_0019: call "ref char C.GetC()" IL_001e: ldind.u2 IL_001f: stloc.2 IL_0020: ldloca.s V_2 - IL_0022: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0022: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0027: ldarg.0 IL_0028: call "ref char C.GetC2()" IL_002d: ldind.u2 IL_002e: stloc.3 IL_002f: ldloca.s V_3 - IL_0031: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0031: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0036: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_003b: call "void System.Console.Write(string)" IL_0040: ret @@ -3453,7 +3453,7 @@ .locals init (char V_0, //c1 IL_0006: ldloc.0 IL_0007: stloc.2 IL_0008: ldloca.s V_2 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: ldloca.s V_0 IL_0012: call "string C.SneakyLocalChange(ref char)" @@ -3461,7 +3461,7 @@ .locals init (char V_0, //c1 IL_001c: ldloc.1 IL_001d: stloc.3 IL_001e: ldloca.s V_3 - IL_0020: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0020: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0025: ldarg.0 IL_0026: ldloca.s V_1 IL_0028: call "string C.SneakyLocalChange(ref char)" @@ -3525,7 +3525,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -3767,19 +3767,19 @@ .locals init (char V_0, IL_0000: ldarg.0 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.1 IL_000a: stloc.1 IL_000b: ldloca.s V_1 - IL_000d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0012: ldarg.2 IL_0013: stloc.2 IL_0014: ldloca.s V_2 - IL_0016: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0016: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001b: ldarg.3 IL_001c: stloc.3 IL_001d: ldloca.s V_3 - IL_001f: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001f: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0024: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0029: ret } @@ -4045,11 +4045,11 @@ .locals init (char V_0, IL_0011: ldarg.2 IL_0012: stloc.0 IL_0013: ldloca.s V_0 - IL_0015: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0015: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001a: ldarg.2 IL_001b: stloc.1 IL_001c: ldloca.s V_1 - IL_001e: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001e: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0023: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0028: ret } @@ -4063,11 +4063,11 @@ .locals init (char V_0, IL_0000: ldarg.2 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.2 IL_000a: stloc.1 IL_000b: ldloca.s V_1 - IL_000d: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000d: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0012: ldarg.0 IL_0013: ldarg.1 IL_0014: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" @@ -4086,7 +4086,7 @@ .locals init (char V_0, IL_0000: ldarg.2 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: ldarg.1 IL_000b: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" @@ -4095,7 +4095,7 @@ .locals init (char V_0, IL_001a: ldarg.2 IL_001b: stloc.1 IL_001c: ldloca.s V_1 - IL_001e: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001e: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0023: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0028: ret } @@ -4151,7 +4151,7 @@ .locals init (char V_0) IL_0017: ldarg.3 IL_0018: stloc.0 IL_0019: ldloca.s V_0 - IL_001b: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001b: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0020: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0025: ret } @@ -4169,7 +4169,7 @@ .locals init (char V_0) IL_0011: ldarg.3 IL_0012: stloc.0 IL_0013: ldloca.s V_0 - IL_0015: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0015: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001a: ldarg.2 IL_001b: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0020: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -4186,7 +4186,7 @@ .locals init (char V_0) IL_0006: ldarg.3 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: ldarg.1 IL_0011: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" @@ -4204,7 +4204,7 @@ .locals init (char V_0) IL_0000: ldarg.3 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.2 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -4231,7 +4231,7 @@ .locals init (char V_0) IL_0017: ldarg.3 IL_0018: stloc.0 IL_0019: ldloca.s V_0 - IL_001b: newobj "System.ReadOnlySpan..ctor(in char)" + IL_001b: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0020: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0025: ret } @@ -4244,7 +4244,7 @@ .locals init (char V_0) IL_0000: ldarg.3 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: ldarg.1 IL_000b: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" @@ -4415,7 +4415,7 @@ .locals init (char V_0) IL_0012: ldarg.3 IL_0013: stloc.0 IL_0014: ldloca.s V_0 - IL_0016: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0016: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan)" IL_0020: ret } @@ -4428,7 +4428,7 @@ .locals init (char V_0) IL_0000: ldarg.3 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: ldarg.1 IL_000b: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" @@ -5229,10 +5229,10 @@ .locals init (int V_0, IL_01af: call "System.ReadOnlySpan string.op_Implicit(string)" IL_01b4: ldarg.0 IL_01b5: ldflda "char Test.d__1.<>7__wrap1" - IL_01ba: newobj "System.ReadOnlySpan..ctor(in char)" + IL_01ba: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_01bf: ldarg.0 IL_01c0: ldflda "char Test.d__1.<>7__wrap2" - IL_01c5: newobj "System.ReadOnlySpan..ctor(in char)" + IL_01c5: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_01ca: ldloc.s V_4 IL_01cc: call "System.ReadOnlySpan string.op_Implicit(string)" IL_01d1: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -5313,7 +5313,7 @@ .locals init (char V_0) IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -5334,7 +5334,7 @@ .locals init (char V_0) IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: ldarg.0 @@ -5355,7 +5355,7 @@ .locals init (char V_0) IL_000c: ldarg.1 IL_000d: stloc.0 IL_000e: ldloca.s V_0 - IL_0010: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0010: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0015: ldarg.0 IL_0016: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -5376,7 +5376,7 @@ .locals init (char V_0) IL_0012: ldarg.1 IL_0013: stloc.0 IL_0014: ldloca.s V_0 - IL_0016: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0016: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001b: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0020: ret } @@ -5390,13 +5390,13 @@ .locals init (char V_0, IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.1 IL_0010: stloc.1 IL_0011: ldloca.s V_1 - IL_0013: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0013: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0018: ldarg.0 IL_0019: call "System.ReadOnlySpan string.op_Implicit(string)" IL_001e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" @@ -5414,13 +5414,13 @@ .locals init (char V_0, IL_0006: ldarg.1 IL_0007: stloc.0 IL_0008: ldloca.s V_0 - IL_000a: newobj "System.ReadOnlySpan..ctor(in char)" + IL_000a: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_000f: ldarg.0 IL_0010: call "System.ReadOnlySpan string.op_Implicit(string)" IL_0015: ldarg.1 IL_0016: stloc.1 IL_0017: ldloca.s V_1 - IL_0019: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0019: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0023: ret } @@ -5434,7 +5434,7 @@ .locals init (char V_0, IL_0000: ldarg.1 IL_0001: stloc.0 IL_0002: ldloca.s V_0 - IL_0004: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_0009: ldarg.0 IL_000a: call "System.ReadOnlySpan string.op_Implicit(string)" IL_000f: ldarg.0 @@ -5442,7 +5442,7 @@ .locals init (char V_0, IL_0015: ldarg.1 IL_0016: stloc.1 IL_0017: ldloca.s V_1 - IL_0019: newobj "System.ReadOnlySpan..ctor(in char)" + IL_0019: newobj "System.ReadOnlySpan..ctor(ref readonly char)" IL_001e: call "string string.Concat(System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan, System.ReadOnlySpan)" IL_0023: ret } diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs index 028ff1e8ff7d4..d2f3bf455c812 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs @@ -5463,7 +5463,10 @@ static IEnumerable F() var compilation1 = compilation0.WithSource(source1.Tree); var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); + v0.VerifyDiagnostics( + // (17,34): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return 1; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(17, 34)); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var f0 = compilation0.GetMember("C.F"); diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs index 04b2a6d0025ee..41ff3e1fd848c 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/EditAndContinue/EditAndContinueTests.cs @@ -1036,14 +1036,29 @@ static void G() {} Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),// add new row ]); - g.VerifyCustomAttributes( - [ - new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(5, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(6, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)), - ]); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(5, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(6, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)), + ]); + } + else + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(5, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(8, TableIndex.MethodDef), Handle(6, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)), + ]); + } }) .Verify(); } @@ -1422,15 +1437,32 @@ [A7]void H() { } Handle(9, TableIndex.CustomAttribute), ]); - g.VerifyCustomAttributes( - [ - new CustomAttributeRow(Handle(9, TableIndex.MethodDef), Handle(2, TableIndex.MethodDef)), // F [A1] -> [A2] - new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // F [A2] delete - new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)),// G [A3] -> [A4] - new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)),// H [A6] -> [A7] - new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // H [A5] delete - new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)),// G [A3] add with RowId 9 - ]); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // F [A2] delete + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // H [A5] delete + new CustomAttributeRow(Handle(9, TableIndex.MethodDef), Handle(2, TableIndex.MethodDef)), // F [A1] -> [A2] + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)),// G [A3] -> [A4] + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)),// G [A3] add with RowId 9 + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)),// H [A6] -> [A7] + ]); + } + else + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(9, TableIndex.MethodDef), Handle(2, TableIndex.MethodDef)), // F [A1] -> [A2] + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // F [A2] delete + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)),// G [A3] -> [A4] + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)),// H [A6] -> [A7] + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // H [A5] delete + new CustomAttributeRow(Handle(10, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)),// G [A3] add with RowId 9 + ]); + + } }) .AddGeneration( source: common + """ @@ -1472,15 +1504,32 @@ void G() { } Handle(11, TableIndex.CustomAttribute), ]); - g.VerifyCustomAttributes( - [ - new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // G [A4] delete - new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(5, TableIndex.MethodDef)), // H [A5] - new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(6, TableIndex.MethodDef)), // H [A6] - new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // G [A3] delete - new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)), // H [A7] add with RowId 10 - new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(8, TableIndex.MethodDef)), // H [A8] add with RowId 11 - ]); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // G [A4] delete + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // G [A3] delete + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(5, TableIndex.MethodDef)), // H [A5] + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(6, TableIndex.MethodDef)), // H [A6] + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)), // H [A7] add with RowId 10 + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(8, TableIndex.MethodDef)), // H [A8] add with RowId 11 + ]); + } + else + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // G [A4] delete + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(5, TableIndex.MethodDef)), // H [A5] + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(6, TableIndex.MethodDef)), // H [A6] + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // G [A3] delete + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(7, TableIndex.MethodDef)), // H [A7] add with RowId 10 + new CustomAttributeRow(Handle(11, TableIndex.MethodDef), Handle(8, TableIndex.MethodDef)), // H [A8] add with RowId 11 + ]); + + } }) .AddGeneration( source: common + """ @@ -1648,11 +1697,23 @@ [A4] void G() { } Handle(5, TableIndex.CustomAttribute), ]); - g.VerifyCustomAttributes( - [ - new CustomAttributeRow(Handle(6, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)), // F: [A1] -> [A3] - new CustomAttributeRow(Handle(5, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)), // G: [A2] -> [A4] - ]); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(5, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)), // G: [A2] -> [A4] + new CustomAttributeRow(Handle(6, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)), // F: [A1] -> [A3] + ]); + } + else + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(6, TableIndex.MethodDef), Handle(4, TableIndex.MethodDef)), // F: [A1] -> [A3] + new CustomAttributeRow(Handle(5, TableIndex.MethodDef), Handle(3, TableIndex.MethodDef)), // G: [A2] -> [A4] + ]); + } }) .Verify(); } @@ -3024,15 +3085,23 @@ class C g.VerifyTypeDefNames("E", "C", "D"); g.VerifyMethodDefNames(); - g.VerifyCustomAttributes( - [ - new CustomAttributeRow(Handle(14, TableIndex.TypeDef), Handle(1, TableIndex.MethodDef)), // E - new CustomAttributeRow(Handle(15, TableIndex.TypeDef), Handle(3, TableIndex.MethodDef)), // C - new CustomAttributeRow(Handle(16, TableIndex.TypeDef), Handle(6, TableIndex.MethodDef)), // D - new CustomAttributeRow(Handle(2, TableIndex.Field), Handle(2, TableIndex.MethodDef)), // E.A - new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(4, TableIndex.MethodDef)), // _x - new CustomAttributeRow(Handle(1, TableIndex.Property), Handle(5, TableIndex.MethodDef)) // X - ]); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(1, TableIndex.Property), Handle(5, TableIndex.MethodDef)), // X + new CustomAttributeRow(Handle(2, TableIndex.Field), Handle(2, TableIndex.MethodDef)), // E.A + new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(4, TableIndex.MethodDef)), // _x + new CustomAttributeRow(Handle(14, TableIndex.TypeDef), Handle(1, TableIndex.MethodDef)), // E + new CustomAttributeRow(Handle(15, TableIndex.TypeDef), Handle(3, TableIndex.MethodDef)), // C + new CustomAttributeRow(Handle(16, TableIndex.TypeDef), Handle(6, TableIndex.MethodDef)), // D + ]); + } + else + { + + } g.VerifyEncLogDefinitions( [ @@ -3105,15 +3174,31 @@ class C g.VerifyTypeDefNames("E", "C", "D"); g.VerifyMethodDefNames(); - g.VerifyCustomAttributes( - [ - new CustomAttributeRow(Handle(14, TableIndex.TypeDef), Handle(7, TableIndex.MethodDef)), // E - new CustomAttributeRow(Handle(15, TableIndex.TypeDef), Handle(9, TableIndex.MethodDef)), // C - new CustomAttributeRow(Handle(16, TableIndex.TypeDef), Handle(12, TableIndex.MethodDef)),// D - new CustomAttributeRow(Handle(2, TableIndex.Field), Handle(8, TableIndex.MethodDef)), // E.A - new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(10, TableIndex.MethodDef)), // _x - new CustomAttributeRow(Handle(1, TableIndex.Property), Handle(11, TableIndex.MethodDef)) // X - ]); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(1, TableIndex.Property), Handle(11, TableIndex.MethodDef)),// X + new CustomAttributeRow(Handle(2, TableIndex.Field), Handle(8, TableIndex.MethodDef)), // E.A + new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(10, TableIndex.MethodDef)), // _x + new CustomAttributeRow(Handle(14, TableIndex.TypeDef), Handle(7, TableIndex.MethodDef)), // E + new CustomAttributeRow(Handle(15, TableIndex.TypeDef), Handle(9, TableIndex.MethodDef)), // C + new CustomAttributeRow(Handle(16, TableIndex.TypeDef), Handle(12, TableIndex.MethodDef)),// D + ]); + } + else + { + g.VerifyCustomAttributes( + [ + new CustomAttributeRow(Handle(14, TableIndex.TypeDef), Handle(7, TableIndex.MethodDef)), // E + new CustomAttributeRow(Handle(15, TableIndex.TypeDef), Handle(9, TableIndex.MethodDef)), // C + new CustomAttributeRow(Handle(16, TableIndex.TypeDef), Handle(12, TableIndex.MethodDef)),// D + new CustomAttributeRow(Handle(2, TableIndex.Field), Handle(8, TableIndex.MethodDef)), // E.A + new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(10, TableIndex.MethodDef)), // _x + new CustomAttributeRow(Handle(1, TableIndex.Property), Handle(11, TableIndex.MethodDef)),// X + ]); + } g.VerifyEncLogDefinitions(new[] { @@ -6964,16 +7049,33 @@ [B] static void M2<[A]T>() { } Handle(6, TableIndex.MethodSemantics), Handle(2, TableIndex.GenericParam)); - CheckAttributes(reader1, - new CustomAttributeRow(Handle(1, TableIndex.GenericParam), Handle(1, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(1, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(11, TableIndex.MemberRef)), - new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(12, TableIndex.MemberRef)), - new CustomAttributeRow(Handle(12, TableIndex.MethodDef), Handle(2, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(14, TableIndex.MethodDef), Handle(11, TableIndex.MemberRef)), - new CustomAttributeRow(Handle(15, TableIndex.MethodDef), Handle(11, TableIndex.MemberRef)), - new CustomAttributeRow(Handle(2, TableIndex.Event), Handle(1, TableIndex.MethodDef)), - new CustomAttributeRow(Handle(2, TableIndex.Property), Handle(2, TableIndex.MethodDef))); + // https://github.com/dotnet/roslyn/issues/73513 + if (RuntimeUtilities.IsCoreClr9OrHigherRuntime) + { + CheckAttributes(reader1, + new CustomAttributeRow(Handle(1, TableIndex.GenericParam), Handle(1, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(2, TableIndex.Property), Handle(2, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(2, TableIndex.Event), Handle(1, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(1, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(11, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(12, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(12, TableIndex.MethodDef), Handle(2, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(14, TableIndex.MethodDef), Handle(11, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(15, TableIndex.MethodDef), Handle(11, TableIndex.MemberRef))); + } + else + { + CheckAttributes(reader1, + new CustomAttributeRow(Handle(1, TableIndex.GenericParam), Handle(1, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(3, TableIndex.Field), Handle(1, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(11, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(4, TableIndex.Field), Handle(12, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(12, TableIndex.MethodDef), Handle(2, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(14, TableIndex.MethodDef), Handle(11, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(15, TableIndex.MethodDef), Handle(11, TableIndex.MemberRef)), + new CustomAttributeRow(Handle(2, TableIndex.Event), Handle(1, TableIndex.MethodDef)), + new CustomAttributeRow(Handle(2, TableIndex.Property), Handle(2, TableIndex.MethodDef))); + } } /// diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/LocalStateTracing/LocalStateTracingTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/LocalStateTracing/LocalStateTracingTests.cs index 4315771543ce5..899fc155bff31 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/LocalStateTracing/LocalStateTracingTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/LocalStateTracing/LocalStateTracingTests.cs @@ -162,7 +162,7 @@ private static string MemoryToString(void* address, int size) private static string WithHelpers(string source) => source + s_helpers; - private static readonly TargetFramework s_targetFramework = TargetFramework.Net70; + private const TargetFramework s_targetFramework = TargetFramework.Net70; private static readonly Verification s_verification = Verification.Fails with { @@ -180,13 +180,13 @@ private static string WithHelpers(string source) """ }; - private CompilationVerifier CompileAndVerify(string source, string? ilVerifyMessage = null, string? expectedOutput = null) + private CompilationVerifier CompileAndVerify(string source, string? ilVerifyMessage = null, string? expectedOutput = null, TargetFramework targetFramework = s_targetFramework) => CompileAndVerify( source, options: (expectedOutput != null) ? TestOptions.UnsafeDebugExe : TestOptions.UnsafeDebugDll, emitOptions: s_emitOptions, verify: s_verification with { ILVerifyMessage = ilVerifyMessage + Environment.NewLine + s_verification.ILVerifyMessage }, - targetFramework: s_targetFramework, + targetFramework: targetFramework, expectedOutput: expectedOutput); // Only used to diagnose test verification failures (rename CompileAndVerify to CompileAndVerifyFails and rerun). @@ -1682,6 +1682,82 @@ .locals init (Microsoft.CodeAnalysis.Runtime.LocalStoreTracker V_0, }"); } + [Fact] + public void RefStructTypeParameter() + { + var source = WithHelpers(""" +S.F(new S()); + +ref struct S +{ + ref int X; + + public static void F(T p) + where T : struct, allows ref struct + { + int a = 1; + var x = p = default(T); + } +} +"""); + var verifier = CompileAndVerify( + source, + targetFramework: TargetFramework.Net90, + expectedOutput: @" +
$: Entered +
$: P'args'[0] = System.String[] +F: Entered +F: L1 = 1 +F: Returned +
$: Returned +"); + + // writes to x and p are not logged since we can't invoke ToString() + verifier.VerifyMethodBody("S.F(T)", @" +{ + // Code size 46 (0x2e) + .maxstack 3 + .locals init (Microsoft.CodeAnalysis.Runtime.LocalStoreTracker V_0, + int V_1, //a + T V_2) //x + // sequence point: + IL_0000: ldtoken ""void S.F(T)"" + IL_0005: call ""Microsoft.CodeAnalysis.Runtime.LocalStoreTracker Microsoft.CodeAnalysis.Runtime.LocalStoreTracker.LogMethodEntry(int)"" + IL_000a: stloc.0 + .try + { + // sequence point: { + IL_000b: nop + // sequence point: int a = 1; + IL_000c: ldloca.s V_0 + IL_000e: ldc.i4.1 + IL_000f: dup + IL_0010: stloc.1 + IL_0011: ldc.i4.1 + IL_0012: call ""void Microsoft.CodeAnalysis.Runtime.LocalStoreTracker.LogLocalStore(uint, int)"" + IL_0017: nop + // sequence point: var x = p = default(T); + IL_0018: ldarga.s V_0 + IL_001a: initobj ""T"" + IL_0020: ldarg.0 + IL_0021: stloc.2 + // sequence point: } + IL_0022: leave.s IL_002d + } + finally + { + // sequence point: + IL_0024: ldloca.s V_0 + IL_0026: call ""void Microsoft.CodeAnalysis.Runtime.LocalStoreTracker.LogReturn()"" + IL_002b: nop + IL_002c: endfinally + } + // sequence point: } + IL_002d: ret +} +"); + } + [Fact] public void UnmanagedRefStruct() { @@ -5520,7 +5596,7 @@ static void Main() Main: Entered Main: L'a' = 1 Main: L'b' = 2 -Main: L4 = System.Linq.Enumerable+SelectArrayIterator`2[System.Int32,System.Int32] +Main: L4 = System.Linq.Enumerable+ArraySelectIterator`2[System.Int32,System.Int32] Main: Entered lambda '
b__0'
b__0: P'item'[0] = 10
b__0: Returned diff --git a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs index 4760ca1c2c254..458de9f14813a 100644 --- a/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Emit/NumericIntPtrTests.cs @@ -1359,20 +1359,44 @@ static IEnumerable F() yield return sizeof(System.UIntPtr); } }"; - var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70); - comp.VerifyDiagnostics( - // (6,22): error CS1629: Unsafe code may not appear in iterators + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + var expectedDiagnostics = new[] + { + // (6,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // yield return sizeof(nint); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nint)").WithLocation(6, 22), - // (7,22): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nint)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 22), + // (7,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // yield return sizeof(nuint); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nuint)").WithLocation(7, 22), - // (8,22): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nuint)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 22), + // (8,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // yield return sizeof(System.IntPtr); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(System.IntPtr)").WithLocation(8, 22), - // (9,22): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(System.IntPtr)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 22), + // (9,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // yield return sizeof(System.UIntPtr); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(System.UIntPtr)").WithLocation(9, 22)); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(System.UIntPtr)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 22) + }; + + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics); + + expectedDiagnostics = new[] + { + // (6,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 22), + // (7,22): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nuint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nuint)").WithArguments("nuint").WithLocation(7, 22), + // (8,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(System.IntPtr); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.IntPtr)").WithArguments("nint").WithLocation(8, 22), + // (9,22): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(System.UIntPtr); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(System.UIntPtr)").WithArguments("nuint").WithLocation(9, 22) + }; + + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics); } [Fact] diff --git a/src/Compilers/CSharp/Test/Emit2/Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests.csproj b/src/Compilers/CSharp/Test/Emit2/Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests.csproj index 3276fae69d6c0..a5058e4b017cf 100644 --- a/src/Compilers/CSharp/Test/Emit2/Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests.csproj +++ b/src/Compilers/CSharp/Test/Emit2/Microsoft.CodeAnalysis.CSharp.Emit2.UnitTests.csproj @@ -4,7 +4,7 @@ Library Microsoft.CodeAnalysis.CSharp.UnitTests - $(NetRoslyn);net472 + $(NetRoslynNext);net472 true @@ -27,6 +27,7 @@ + diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs index 87f26b8e0675b..2ed198808f074 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/CollectionExpressionTests.cs @@ -9097,18 +9097,66 @@ static void Main() verifier.VerifyIL("Program.F", """ { - // Code size 21 (0x15) - .maxstack 3 - .locals init (System.Collections.Generic.List V_0) - IL_0000: ldarg.0 - IL_0001: stloc.0 - IL_0002: ldloc.0 - IL_0003: callvirt "int System.Collections.Generic.List.Count.get" - IL_0008: newobj "System.Collections.Generic.List..ctor(int)" - IL_000d: dup - IL_000e: ldloc.0 - IL_000f: callvirt "void System.Collections.Generic.List.AddRange(System.Collections.Generic.IEnumerable)" - IL_0014: ret + // Code size 141 (0x8d) + .maxstack 9 + .locals init (System.Collections.Generic.List V_0, + System.Collections.Generic.List.Enumerator V_1, + object V_2) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: stloc.0 + IL_0006: ldarg.0 + IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_000c: stloc.1 + .try + { + IL_000d: br.s IL_0072 + IL_000f: ldloca.s V_1 + IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_0016: stloc.2 + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_001c: brtrue.s IL_005c + IL_001e: ldc.i4 0x100 + IL_0023: ldstr "Add" + IL_0028: ldnull + IL_0029: ldtoken "Program" + IL_002e: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0033: ldc.i4.2 + IL_0034: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0039: dup + IL_003a: ldc.i4.0 + IL_003b: ldc.i4.1 + IL_003c: ldnull + IL_003d: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0042: stelem.ref + IL_0043: dup + IL_0044: ldc.i4.1 + IL_0045: ldc.i4.0 + IL_0046: ldnull + IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_004c: stelem.ref + IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_006b: ldloc.0 + IL_006c: ldloc.2 + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_0072: ldloca.s V_1 + IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0079: brtrue.s IL_000f + IL_007b: leave.s IL_008b + } + finally + { + IL_007d: ldloca.s V_1 + IL_007f: constrained. "System.Collections.Generic.List.Enumerator" + IL_0085: callvirt "void System.IDisposable.Dispose()" + IL_008a: endfinally + } + IL_008b: ldloc.0 + IL_008c: ret } """); } @@ -9118,55 +9166,66 @@ .locals init (System.Collections.Generic.List V_0) verifier.VerifyIL("Program.F", """ { - // Code size 126 (0x7e) - .maxstack 4 + // Code size 141 (0x8d) + .maxstack 9 .locals init (System.Collections.Generic.List V_0, System.Collections.Generic.List.Enumerator V_1, object V_2) - IL_0000: ldarg.0 - IL_0001: dup - IL_0002: callvirt "int System.Collections.Generic.List.Count.get" - IL_0007: newobj "System.Collections.Generic.List..ctor(int)" - IL_000c: stloc.0 - IL_000d: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" - IL_0012: stloc.1 + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: stloc.0 + IL_0006: ldarg.0 + IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_000c: stloc.1 .try { - IL_0013: br.s IL_0063 - IL_0015: ldloca.s V_1 - IL_0017: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" - IL_001c: stloc.2 - IL_001d: ldloc.0 - IL_001e: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0023: brtrue.s IL_0049 - IL_0025: ldc.i4.0 - IL_0026: ldtoken "int" - IL_002b: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0030: ldtoken "Program" - IL_0035: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_003a: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_003f: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0044: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0049: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_004e: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_0053: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0058: ldloc.2 - IL_0059: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_005e: callvirt "void System.Collections.Generic.List.Add(int)" - IL_0063: ldloca.s V_1 - IL_0065: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" - IL_006a: brtrue.s IL_0015 - IL_006c: leave.s IL_007c + IL_000d: br.s IL_0072 + IL_000f: ldloca.s V_1 + IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_0016: stloc.2 + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_001c: brtrue.s IL_005c + IL_001e: ldc.i4 0x100 + IL_0023: ldstr "Add" + IL_0028: ldnull + IL_0029: ldtoken "Program" + IL_002e: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0033: ldc.i4.2 + IL_0034: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0039: dup + IL_003a: ldc.i4.0 + IL_003b: ldc.i4.1 + IL_003c: ldnull + IL_003d: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0042: stelem.ref + IL_0043: dup + IL_0044: ldc.i4.1 + IL_0045: ldc.i4.0 + IL_0046: ldnull + IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_004c: stelem.ref + IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_006b: ldloc.0 + IL_006c: ldloc.2 + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_0072: ldloca.s V_1 + IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0079: brtrue.s IL_000f + IL_007b: leave.s IL_008b } finally { - IL_006e: ldloca.s V_1 - IL_0070: constrained. "System.Collections.Generic.List.Enumerator" - IL_0076: callvirt "void System.IDisposable.Dispose()" - IL_007b: endfinally + IL_007d: ldloca.s V_1 + IL_007f: constrained. "System.Collections.Generic.List.Enumerator" + IL_0085: callvirt "void System.IDisposable.Dispose()" + IL_008a: endfinally } - IL_007c: ldloc.0 - IL_007d: ret + IL_008b: ldloc.0 + IL_008c: ret } """); } @@ -13908,7 +13967,7 @@ static void M2() comp, symbolValidator: module => { - AssertEx.Equal(new[] { "<>y__InlineArray1", "<>y__InlineArray3" }, getInlineArrayTypeNames(module)); + AssertEx.Equal(new[] { "<>y__InlineArray3" }, getInlineArrayTypeNames(module)); }, verify: Verification.Skipped); @@ -17994,6 +18053,8 @@ public class MyCollectionBuilder var comp = CreateCompilation(sourceA, targetFramework: TargetFramework.Net80); var refA = AsReference(comp, useCompilationReference); + // https://github.com/dotnet/roslyn/issues/73085 + // Test hits an assertion failure when collection-expr with a single element is used here string sourceB = """ #pragma warning disable 219 class Program @@ -18001,7 +18062,7 @@ class Program static void Main() { MyCollection x = []; - MyCollection y = ["2"]; + MyCollection y = ["2", "3"]; MyCollection z = new(); } } @@ -18010,14 +18071,17 @@ static void Main() comp.MakeTypeMissing(SpecialType.System_Int32); comp.VerifyEmitDiagnostics( // (7,34): error CS0518: Predefined type 'System.Int32' is not defined or imported - // MyCollection y = ["2"]; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2""]").WithArguments("System.Int32").WithLocation(7, 34), + // MyCollection y = ["2", "3"]; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2"", ""3""]").WithArguments("System.Int32").WithLocation(7, 34), + // (7,34): error CS0518: Predefined type 'System.Int32' is not defined or imported + // MyCollection y = ["2", "3"]; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2"", ""3""]").WithArguments("System.Int32").WithLocation(7, 34), // (7,34): error CS0518: Predefined type 'System.Int32' is not defined or imported - // MyCollection y = ["2"]; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2""]").WithArguments("System.Int32").WithLocation(7, 34), + // MyCollection y = ["2", "3"]; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2"", ""3""]").WithArguments("System.Int32").WithLocation(7, 34), // (7,34): error CS0518: Predefined type 'System.Int32' is not defined or imported - // MyCollection y = ["2"]; - Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2""]").WithArguments("System.Int32").WithLocation(7, 34)); + // MyCollection y = ["2", "3"]; + Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, @"[""2"", ""3""]").WithArguments("System.Int32").WithLocation(7, 34)); } [Fact] @@ -19772,118 +19836,132 @@ static void Main() verifier.VerifyIL("Program.F1", """ { - // Code size 72 (0x48) - .maxstack 4 - .locals init (int V_0, - System.Collections.Generic.List V_1, - System.Span V_2, - int V_3, - System.Span V_4) - IL_0000: ldarg.0 - IL_0001: dup - IL_0002: callvirt "int System.Collections.Generic.List.Count.get" - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: newobj "System.Collections.Generic.List..ctor(int)" - IL_000e: stloc.1 - IL_000f: ldloc.1 - IL_0010: ldloc.0 - IL_0011: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" - IL_0016: ldloc.1 - IL_0017: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_001c: stloc.2 - IL_001d: ldc.i4.0 - IL_001e: stloc.3 - IL_001f: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_0024: stloc.s V_4 - IL_0026: ldloca.s V_4 - IL_0028: ldloca.s V_2 - IL_002a: ldloc.3 - IL_002b: ldloca.s V_4 - IL_002d: call "int System.Span.Length.get" - IL_0032: call "System.Span System.Span.Slice(int, int)" - IL_0037: call "void System.Span.CopyTo(System.Span)" - IL_003c: ldloc.3 - IL_003d: ldloca.s V_4 - IL_003f: call "int System.Span.Length.get" - IL_0044: add - IL_0045: stloc.3 - IL_0046: ldloc.1 - IL_0047: ret - } + // Code size 141 (0x8d) + .maxstack 9 + .locals init (System.Collections.Generic.List V_0, + System.Collections.Generic.List.Enumerator V_1, + object V_2) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: stloc.0 + IL_0006: ldarg.0 + IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_000c: stloc.1 + .try + { + IL_000d: br.s IL_0072 + IL_000f: ldloca.s V_1 + IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_0016: stloc.2 + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_001c: brtrue.s IL_005c + IL_001e: ldc.i4 0x100 + IL_0023: ldstr "Add" + IL_0028: ldnull + IL_0029: ldtoken "Program" + IL_002e: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0033: ldc.i4.2 + IL_0034: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0039: dup + IL_003a: ldc.i4.0 + IL_003b: ldc.i4.1 + IL_003c: ldnull + IL_003d: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0042: stelem.ref + IL_0043: dup + IL_0044: ldc.i4.1 + IL_0045: ldc.i4.0 + IL_0046: ldnull + IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_004c: stelem.ref + IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_006b: ldloc.0 + IL_006c: ldloc.2 + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_0072: ldloca.s V_1 + IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0079: brtrue.s IL_000f + IL_007b: leave.s IL_008b + } + finally + { + IL_007d: ldloca.s V_1 + IL_007f: constrained. "System.Collections.Generic.List.Enumerator" + IL_0085: callvirt "void System.IDisposable.Dispose()" + IL_008a: endfinally + } + IL_008b: ldloc.0 + IL_008c: ret + } """); verifier.VerifyIL("Program.F2", """ { - // Code size 154 (0x9a) - .maxstack 4 - .locals init (int V_0, - System.Collections.Generic.List V_1, - System.Span V_2, - int V_3, - System.Collections.Generic.List.Enumerator V_4, - object V_5) - IL_0000: ldarg.0 - IL_0001: dup - IL_0002: callvirt "int System.Collections.Generic.List.Count.get" - IL_0007: stloc.0 - IL_0008: ldloc.0 - IL_0009: newobj "System.Collections.Generic.List..ctor(int)" - IL_000e: stloc.1 - IL_000f: ldloc.1 - IL_0010: ldloc.0 - IL_0011: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" - IL_0016: ldloc.1 - IL_0017: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_001c: stloc.2 - IL_001d: ldc.i4.0 - IL_001e: stloc.3 - IL_001f: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" - IL_0024: stloc.s V_4 + // Code size 141 (0x8d) + .maxstack 9 + .locals init (System.Collections.Generic.List V_0, + System.Collections.Generic.List.Enumerator V_1, + object V_2) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: stloc.0 + IL_0006: ldarg.0 + IL_0007: callvirt "System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()" + IL_000c: stloc.1 .try { - IL_0026: br.s IL_007f - IL_0028: ldloca.s V_4 - IL_002a: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" - IL_002f: stloc.s V_5 - IL_0031: ldloca.s V_2 - IL_0033: ldloc.3 - IL_0034: call "ref int System.Span.this[int].get" - IL_0039: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_003e: brtrue.s IL_0064 - IL_0040: ldc.i4.0 - IL_0041: ldtoken "int" - IL_0046: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_004b: ldtoken "Program" - IL_0050: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0055: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_005a: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_005f: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_0064: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_0069: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_006e: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_0073: ldloc.s V_5 - IL_0075: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_007a: stind.i4 - IL_007b: ldloc.3 - IL_007c: ldc.i4.1 - IL_007d: add - IL_007e: stloc.3 - IL_007f: ldloca.s V_4 - IL_0081: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" - IL_0086: brtrue.s IL_0028 - IL_0088: leave.s IL_0098 + IL_000d: br.s IL_0072 + IL_000f: ldloca.s V_1 + IL_0011: call "dynamic System.Collections.Generic.List.Enumerator.Current.get" + IL_0016: stloc.2 + IL_0017: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_001c: brtrue.s IL_005c + IL_001e: ldc.i4 0x100 + IL_0023: ldstr "Add" + IL_0028: ldnull + IL_0029: ldtoken "Program" + IL_002e: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0033: ldc.i4.2 + IL_0034: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0039: dup + IL_003a: ldc.i4.0 + IL_003b: ldc.i4.1 + IL_003c: ldnull + IL_003d: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0042: stelem.ref + IL_0043: dup + IL_0044: ldc.i4.1 + IL_0045: ldc.i4.0 + IL_0046: ldnull + IL_0047: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_004c: stelem.ref + IL_004d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0052: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0057: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_005c: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0061: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0066: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_006b: ldloc.0 + IL_006c: ldloc.2 + IL_006d: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_0072: ldloca.s V_1 + IL_0074: call "bool System.Collections.Generic.List.Enumerator.MoveNext()" + IL_0079: brtrue.s IL_000f + IL_007b: leave.s IL_008b } finally { - IL_008a: ldloca.s V_4 - IL_008c: constrained. "System.Collections.Generic.List.Enumerator" - IL_0092: callvirt "void System.IDisposable.Dispose()" - IL_0097: endfinally + IL_007d: ldloca.s V_1 + IL_007f: constrained. "System.Collections.Generic.List.Enumerator" + IL_0085: callvirt "void System.IDisposable.Dispose()" + IL_008a: endfinally } - IL_0098: ldloc.1 - IL_0099: ret - } + IL_008b: ldloc.0 + IL_008c: ret + } """); } @@ -20132,79 +20210,85 @@ static void Main() verifier.VerifyIL("Program.F1", """ { - // Code size 39 (0x27) - .maxstack 3 - .locals init (int V_0, - System.Span V_1, - int V_2) - IL_0000: ldc.i4.1 - IL_0001: stloc.0 - IL_0002: ldloc.0 - IL_0003: newobj "System.Collections.Generic.List..ctor(int)" - IL_0008: dup - IL_0009: ldloc.0 - IL_000a: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" - IL_000f: dup - IL_0010: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_0015: stloc.1 - IL_0016: ldc.i4.0 - IL_0017: stloc.2 - IL_0018: ldloca.s V_1 - IL_001a: ldloc.2 - IL_001b: call "ref object System.Span.this[int].get" - IL_0020: ldarg.0 - IL_0021: stind.ref - IL_0022: ldloc.2 - IL_0023: ldc.i4.1 - IL_0024: add - IL_0025: stloc.2 - IL_0026: ret + // Code size 99 (0x63) + .maxstack 9 + .locals init (System.Collections.Generic.List V_0) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: stloc.0 + IL_0006: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_000b: brtrue.s IL_004b + IL_000d: ldc.i4 0x100 + IL_0012: ldstr "Add" + IL_0017: ldnull + IL_0018: ldtoken "Program" + IL_001d: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0022: ldc.i4.2 + IL_0023: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0028: dup + IL_0029: ldc.i4.0 + IL_002a: ldc.i4.1 + IL_002b: ldnull + IL_002c: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0031: stelem.ref + IL_0032: dup + IL_0033: ldc.i4.1 + IL_0034: ldc.i4.0 + IL_0035: ldnull + IL_0036: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_003b: stelem.ref + IL_003c: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0041: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0046: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_0050: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__0.<>p__0" + IL_005a: ldloc.0 + IL_005b: ldarg.0 + IL_005c: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_0061: ldloc.0 + IL_0062: ret } """); verifier.VerifyIL("Program.F2", """ { - // Code size 102 (0x66) - .maxstack 5 - .locals init (int V_0, - System.Span V_1, - int V_2) - IL_0000: ldc.i4.1 - IL_0001: stloc.0 - IL_0002: ldloc.0 - IL_0003: newobj "System.Collections.Generic.List..ctor(int)" - IL_0008: dup - IL_0009: ldloc.0 - IL_000a: call "void System.Runtime.InteropServices.CollectionsMarshal.SetCount(System.Collections.Generic.List, int)" - IL_000f: dup - IL_0010: call "System.Span System.Runtime.InteropServices.CollectionsMarshal.AsSpan(System.Collections.Generic.List)" - IL_0015: stloc.1 - IL_0016: ldc.i4.0 - IL_0017: stloc.2 - IL_0018: ldloca.s V_1 - IL_001a: ldloc.2 - IL_001b: call "ref int System.Span.this[int].get" - IL_0020: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_0025: brtrue.s IL_004b - IL_0027: ldc.i4.0 - IL_0028: ldtoken "int" - IL_002d: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0032: ldtoken "Program" - IL_0037: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_003c: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_0041: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0046: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_0050: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__1.<>p__0" - IL_005a: ldarg.0 - IL_005b: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_0060: stind.i4 - IL_0061: ldloc.2 - IL_0062: ldc.i4.1 - IL_0063: add - IL_0064: stloc.2 - IL_0065: ret + // Code size 99 (0x63) + .maxstack 9 + .locals init (System.Collections.Generic.List V_0) + IL_0000: newobj "System.Collections.Generic.List..ctor()" + IL_0005: stloc.0 + IL_0006: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_000b: brtrue.s IL_004b + IL_000d: ldc.i4 0x100 + IL_0012: ldstr "Add" + IL_0017: ldnull + IL_0018: ldtoken "Program" + IL_001d: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_0022: ldc.i4.2 + IL_0023: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0028: dup + IL_0029: ldc.i4.0 + IL_002a: ldc.i4.1 + IL_002b: ldnull + IL_002c: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0031: stelem.ref + IL_0032: dup + IL_0033: ldc.i4.1 + IL_0034: ldc.i4.0 + IL_0035: ldnull + IL_0036: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_003b: stelem.ref + IL_003c: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_0041: call "System.Runtime.CompilerServices.CallSite, dynamic>> System.Runtime.CompilerServices.CallSite, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0046: stsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_004b: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_0050: ldfld "System.Action, dynamic> System.Runtime.CompilerServices.CallSite, dynamic>>.Target" + IL_0055: ldsfld "System.Runtime.CompilerServices.CallSite, dynamic>> Program.<>o__1.<>p__0" + IL_005a: ldloc.0 + IL_005b: ldarg.0 + IL_005c: callvirt "void System.Action, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Collections.Generic.List, dynamic)" + IL_0061: ldloc.0 + IL_0062: ret } """); } @@ -20473,10 +20557,7 @@ public void RefStruct_04() CreateCompilation(source).VerifyDiagnostics( // (5,7): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. // S s = [d]; - Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "[d]").WithArguments("S").WithLocation(5, 7), - // (7,16): error CS8343: 'S': ref structs cannot implement interfaces - // ref struct S : IEnumerable - Diagnostic(ErrorCode.ERR_RefStructInterfaceImpl, "IEnumerable").WithArguments("S").WithLocation(7, 16) + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "[d]").WithArguments("S").WithLocation(5, 7) ); } @@ -20832,6 +20913,397 @@ static void Report(MyCollection c) Diagnostic(ErrorCode.ERR_CollectionExpressionEscape, "[x, y, z]").WithArguments("MyCollection").WithLocation(12, 60)); } + [Fact] + public void Span_SingleElement() + { + var source = """ + using System; + + class Program + { + static void Main() => M(1); + + static void M(int x) + { + Span y = [x]; + x++; + Console.Write(y[0]); + Console.Write(x); + } + } + """; + + var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net80, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("12")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (System.Span V_0, //y + int V_1) + IL_0000: ldarg.0 + IL_0001: stloc.1 + IL_0002: ldloca.s V_1 + IL_0004: newobj "System.Span..ctor(ref int)" + IL_0009: stloc.0 + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: add + IL_000d: starg.s V_0 + IL_000f: ldloca.s V_0 + IL_0011: ldc.i4.0 + IL_0012: call "ref int System.Span.this[int].get" + IL_0017: ldind.i4 + IL_0018: call "void System.Console.Write(int)" + IL_001d: ldarg.0 + IL_001e: call "void System.Console.Write(int)" + IL_0023: ret + } + """); + + verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("12")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 43 (0x2b) + .maxstack 5 + .locals init (System.Span V_0) //y + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: newarr "int" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldarg.0 + IL_000b: stelem.i4 + IL_000c: call "System.Span..ctor(int[])" + IL_0011: ldarg.0 + IL_0012: ldc.i4.1 + IL_0013: add + IL_0014: starg.s V_0 + IL_0016: ldloca.s V_0 + IL_0018: ldc.i4.0 + IL_0019: call "ref int System.Span.this[int].get" + IL_001e: ldind.i4 + IL_001f: call "void System.Console.Write(int)" + IL_0024: ldarg.0 + IL_0025: call "void System.Console.Write(int)" + IL_002a: ret + } + """); + } + + [Fact] + public void Span_SingleElement_TempsAreNotReused() + { + var source = """ + using System; + + class Program + { + static void Main() => M(1); + + static void M(int x) + { + { + Span y = [x]; + Console.Write(y[0]); + y[0]++; + } + { + Span y = [x]; + Console.Write(y[0]); + } + } + } + """; + + var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("11")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 62 (0x3e) + .maxstack 3 + .locals init (int V_0, + int V_1, + System.Span V_2, //y + System.Span V_3) //y + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: newobj "System.Span..ctor(ref int)" + IL_0009: stloc.2 + IL_000a: ldloca.s V_2 + IL_000c: ldc.i4.0 + IL_000d: call "ref int System.Span.this[int].get" + IL_0012: ldind.i4 + IL_0013: call "void System.Console.Write(int)" + IL_0018: ldloca.s V_2 + IL_001a: ldc.i4.0 + IL_001b: call "ref int System.Span.this[int].get" + IL_0020: dup + IL_0021: ldind.i4 + IL_0022: ldc.i4.1 + IL_0023: add + IL_0024: stind.i4 + IL_0025: ldarg.0 + IL_0026: stloc.1 + IL_0027: ldloca.s V_1 + IL_0029: newobj "System.Span..ctor(ref int)" + IL_002e: stloc.3 + IL_002f: ldloca.s V_3 + IL_0031: ldc.i4.0 + IL_0032: call "ref int System.Span.this[int].get" + IL_0037: ldind.i4 + IL_0038: call "void System.Console.Write(int)" + IL_003d: ret + } + """); + + verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("11")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 76 (0x4c) + .maxstack 5 + .locals init (System.Span V_0, //y + System.Span V_1) //y + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: newarr "int" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldarg.0 + IL_000b: stelem.i4 + IL_000c: call "System.Span..ctor(int[])" + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.0 + IL_0014: call "ref int System.Span.this[int].get" + IL_0019: ldind.i4 + IL_001a: call "void System.Console.Write(int)" + IL_001f: ldloca.s V_0 + IL_0021: ldc.i4.0 + IL_0022: call "ref int System.Span.this[int].get" + IL_0027: dup + IL_0028: ldind.i4 + IL_0029: ldc.i4.1 + IL_002a: add + IL_002b: stind.i4 + IL_002c: ldloca.s V_1 + IL_002e: ldc.i4.1 + IL_002f: newarr "int" + IL_0034: dup + IL_0035: ldc.i4.0 + IL_0036: ldarg.0 + IL_0037: stelem.i4 + IL_0038: call "System.Span..ctor(int[])" + IL_003d: ldloca.s V_1 + IL_003f: ldc.i4.0 + IL_0040: call "ref int System.Span.this[int].get" + IL_0045: ldind.i4 + IL_0046: call "void System.Console.Write(int)" + IL_004b: ret + } + """); + } + + [Fact] + public void Span_SingleElement_TempsAreNotReused_SameBlock() + { + var source = """ + using System; + + class Program + { + static void Main() => M(1); + + static void M(int x) + { + Span y = [x]; + Console.Write(y[0]); + y[0]++; + + Span z = [x]; + Console.Write(z[0]); + } + } + """; + + var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("11")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 62 (0x3e) + .maxstack 3 + .locals init (System.Span V_0, //y + System.Span V_1, //z + int V_2, + int V_3) + IL_0000: ldarg.0 + IL_0001: stloc.2 + IL_0002: ldloca.s V_2 + IL_0004: newobj "System.Span..ctor(ref int)" + IL_0009: stloc.0 + IL_000a: ldloca.s V_0 + IL_000c: ldc.i4.0 + IL_000d: call "ref int System.Span.this[int].get" + IL_0012: ldind.i4 + IL_0013: call "void System.Console.Write(int)" + IL_0018: ldloca.s V_0 + IL_001a: ldc.i4.0 + IL_001b: call "ref int System.Span.this[int].get" + IL_0020: dup + IL_0021: ldind.i4 + IL_0022: ldc.i4.1 + IL_0023: add + IL_0024: stind.i4 + IL_0025: ldarg.0 + IL_0026: stloc.3 + IL_0027: ldloca.s V_3 + IL_0029: newobj "System.Span..ctor(ref int)" + IL_002e: stloc.1 + IL_002f: ldloca.s V_1 + IL_0031: ldc.i4.0 + IL_0032: call "ref int System.Span.this[int].get" + IL_0037: ldind.i4 + IL_0038: call "void System.Console.Write(int)" + IL_003d: ret + } + """); + + verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("11")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 76 (0x4c) + .maxstack 5 + .locals init (System.Span V_0, //y + System.Span V_1) //z + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: newarr "int" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldarg.0 + IL_000b: stelem.i4 + IL_000c: call "System.Span..ctor(int[])" + IL_0011: ldloca.s V_0 + IL_0013: ldc.i4.0 + IL_0014: call "ref int System.Span.this[int].get" + IL_0019: ldind.i4 + IL_001a: call "void System.Console.Write(int)" + IL_001f: ldloca.s V_0 + IL_0021: ldc.i4.0 + IL_0022: call "ref int System.Span.this[int].get" + IL_0027: dup + IL_0028: ldind.i4 + IL_0029: ldc.i4.1 + IL_002a: add + IL_002b: stind.i4 + IL_002c: ldloca.s V_1 + IL_002e: ldc.i4.1 + IL_002f: newarr "int" + IL_0034: dup + IL_0035: ldc.i4.0 + IL_0036: ldarg.0 + IL_0037: stelem.i4 + IL_0038: call "System.Span..ctor(int[])" + IL_003d: ldloca.s V_1 + IL_003f: ldc.i4.0 + IL_0040: call "ref int System.Span.this[int].get" + IL_0045: ldind.i4 + IL_0046: call "void System.Console.Write(int)" + IL_004b: ret + } + """); + } + + [Fact] + public void ReadOnlySpan_SingleElement() + { + var source = """ + using System; + + class Program + { + static void Main() => M(1); + + static void M(int x) + { + ReadOnlySpan y = [x]; + x++; + Console.Write(y[0]); + Console.Write(x); + } + } + """; + + var verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net80, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("12")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 36 (0x24) + .maxstack 2 + .locals init (System.ReadOnlySpan V_0, //y + int V_1) + IL_0000: ldarg.0 + IL_0001: stloc.1 + IL_0002: ldloca.s V_1 + IL_0004: newobj "System.ReadOnlySpan..ctor(ref readonly int)" + IL_0009: stloc.0 + IL_000a: ldarg.0 + IL_000b: ldc.i4.1 + IL_000c: add + IL_000d: starg.s V_0 + IL_000f: ldloca.s V_0 + IL_0011: ldc.i4.0 + IL_0012: call "ref readonly int System.ReadOnlySpan.this[int].get" + IL_0017: ldind.i4 + IL_0018: call "void System.Console.Write(int)" + IL_001d: ldarg.0 + IL_001e: call "void System.Console.Write(int)" + IL_0023: ret + } + """); + + verifier = CompileAndVerify(source, targetFramework: TargetFramework.Net70, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("12")); + verifier.VerifyDiagnostics(); + + verifier.VerifyIL("Program.M", """ + { + // Code size 43 (0x2b) + .maxstack 5 + .locals init (System.ReadOnlySpan V_0) //y + IL_0000: ldloca.s V_0 + IL_0002: ldc.i4.1 + IL_0003: newarr "int" + IL_0008: dup + IL_0009: ldc.i4.0 + IL_000a: ldarg.0 + IL_000b: stelem.i4 + IL_000c: call "System.ReadOnlySpan..ctor(int[])" + IL_0011: ldarg.0 + IL_0012: ldc.i4.1 + IL_0013: add + IL_0014: starg.s V_0 + IL_0016: ldloca.s V_0 + IL_0018: ldc.i4.0 + IL_0019: call "ref readonly int System.ReadOnlySpan.this[int].get" + IL_001e: ldind.i4 + IL_001f: call "void System.Console.Write(int)" + IL_0024: ldarg.0 + IL_0025: call "void System.Console.Write(int)" + IL_002a: ret + } + """); + } + [CombinatorialData] [Theory] public void SpanArgument_01([CombinatorialValues(TargetFramework.Net70, TargetFramework.Net80)] TargetFramework targetFramework) @@ -20857,81 +21329,48 @@ static void Main() new[] { source, s_collectionExtensionsWithSpan }, targetFramework: targetFramework, verify: Verification.Skipped, - symbolValidator: module => - { - if (targetFramework == TargetFramework.Net80) - { - var synthesizedType = module.GlobalNamespace.GetTypeMember("<>y__InlineArray1"); - Assert.Equal("<>y__InlineArray1", synthesizedType.ToTestDisplayString()); - Assert.Equal("<>y__InlineArray1`1", synthesizedType.MetadataName); - } - }, expectedOutput: IncludeExpectedOutput("[1], [2], [3], [4], ")); if (targetFramework == TargetFramework.Net80) { verifier.VerifyIL("Program.Main", """ { - // Code size 161 (0xa1) + // Code size 87 (0x57) .maxstack 2 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3, + .locals init (object V_0, + int? V_1, + int? V_2, + object V_3, System.Span V_4, System.ReadOnlySpan V_5) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_0 - IL_0019: ldc.i4.1 - IL_001a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_001f: call "void Program.F1(System.Span)" - IL_0024: ldloca.s V_1 - IL_0026: initobj "<>y__InlineArray1" - IL_002c: ldloca.s V_1 - IL_002e: ldc.i4.0 - IL_002f: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_0034: ldc.i4.2 - IL_0035: newobj "int?..ctor(int)" - IL_003a: stobj "int?" - IL_003f: ldloca.s V_1 - IL_0041: ldc.i4.1 - IL_0042: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_0047: call "void Program.F2(System.ReadOnlySpan)" - IL_004c: ldloca.s V_2 - IL_004e: initobj "<>y__InlineArray1" - IL_0054: ldloca.s V_2 - IL_0056: ldc.i4.0 - IL_0057: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_005c: ldc.i4.3 - IL_005d: newobj "int?..ctor(int)" - IL_0062: stobj "int?" - IL_0067: ldloca.s V_2 - IL_0069: ldc.i4.1 - IL_006a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_006f: stloc.s V_4 - IL_0071: ldloca.s V_4 - IL_0073: call "void Program.F3(in System.Span)" - IL_0078: ldloca.s V_3 - IL_007a: initobj "<>y__InlineArray1" - IL_0080: ldloca.s V_3 - IL_0082: ldc.i4.0 - IL_0083: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0088: ldc.i4.4 - IL_0089: box "int" - IL_008e: stind.ref - IL_008f: ldloca.s V_3 - IL_0091: ldc.i4.1 - IL_0092: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0097: stloc.s V_5 - IL_0099: ldloca.s V_5 - IL_009b: call "void Program.F4(in System.ReadOnlySpan)" - IL_00a0: ret + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: newobj "System.Span..ctor(ref object)" + IL_000e: call "void Program.F1(System.Span)" + IL_0013: ldloca.s V_1 + IL_0015: ldc.i4.2 + IL_0016: call "int?..ctor(int)" + IL_001b: ldloca.s V_1 + IL_001d: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0022: call "void Program.F2(System.ReadOnlySpan)" + IL_0027: ldloca.s V_2 + IL_0029: ldc.i4.3 + IL_002a: call "int?..ctor(int)" + IL_002f: ldloca.s V_2 + IL_0031: newobj "System.Span..ctor(ref int?)" + IL_0036: stloc.s V_4 + IL_0038: ldloca.s V_4 + IL_003a: call "void Program.F3(in System.Span)" + IL_003f: ldc.i4.4 + IL_0040: box "int" + IL_0045: stloc.3 + IL_0046: ldloca.s V_3 + IL_0048: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_004d: stloc.s V_5 + IL_004f: ldloca.s V_5 + IL_0051: call "void Program.F4(in System.ReadOnlySpan)" + IL_0056: ret } """); } @@ -21019,65 +21458,41 @@ static void Main() expectedOutput: IncludeExpectedOutput("[1], [2], [3], [4], ")); verifier.VerifyIL("Program.Main", """ { - // Code size 149 (0x95) - .maxstack 2 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_0 - IL_0019: ldc.i4.1 - IL_001a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_001f: call "S Program.ReturnsStruct(System.Span)" - IL_0024: pop - IL_0025: ldloca.s V_1 - IL_0027: initobj "<>y__InlineArray1" - IL_002d: ldloca.s V_1 - IL_002f: ldc.i4.0 - IL_0030: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0035: ldc.i4.2 - IL_0036: box "int" - IL_003b: stind.ref - IL_003c: ldloca.s V_1 - IL_003e: ldc.i4.1 - IL_003f: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0044: call "R Program.ReturnsRefStruct(System.Span)" - IL_0049: pop - IL_004a: ldloca.s V_2 - IL_004c: initobj "<>y__InlineArray1" - IL_0052: ldloca.s V_2 - IL_0054: ldc.i4.0 - IL_0055: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_005a: ldc.i4.3 - IL_005b: box "int" - IL_0060: stind.ref - IL_0061: ldloca.s V_2 - IL_0063: ldc.i4.1 - IL_0064: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0069: call "ref int Program.ReturnsRef(System.Span)" - IL_006e: pop - IL_006f: ldloca.s V_3 - IL_0071: initobj "<>y__InlineArray1" - IL_0077: ldloca.s V_3 - IL_0079: ldc.i4.0 - IL_007a: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_007f: ldc.i4.4 - IL_0080: box "int" - IL_0085: stind.ref - IL_0086: ldloca.s V_3 - IL_0088: ldc.i4.1 - IL_0089: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_008e: call "ref readonly int Program.ReturnsRefReadOnly(System.Span)" - IL_0093: pop - IL_0094: ret + // Code size 81 (0x51) + .maxstack 1 + .locals init (object V_0, + object V_1, + object V_2, + object V_3) + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: newobj "System.Span..ctor(ref object)" + IL_000e: call "S Program.ReturnsStruct(System.Span)" + IL_0013: pop + IL_0014: ldc.i4.2 + IL_0015: box "int" + IL_001a: stloc.1 + IL_001b: ldloca.s V_1 + IL_001d: newobj "System.Span..ctor(ref object)" + IL_0022: call "R Program.ReturnsRefStruct(System.Span)" + IL_0027: pop + IL_0028: ldc.i4.3 + IL_0029: box "int" + IL_002e: stloc.2 + IL_002f: ldloca.s V_2 + IL_0031: newobj "System.Span..ctor(ref object)" + IL_0036: call "ref int Program.ReturnsRef(System.Span)" + IL_003b: pop + IL_003c: ldc.i4.4 + IL_003d: box "int" + IL_0042: stloc.3 + IL_0043: ldloca.s V_3 + IL_0045: newobj "System.Span..ctor(ref object)" + IL_004a: call "ref readonly int Program.ReturnsRefReadOnly(System.Span)" + IL_004f: pop + IL_0050: ret } """); } @@ -21107,54 +21522,36 @@ static void Main() new[] { source, s_collectionExtensionsWithSpan }, targetFramework: TargetFramework.Net80, verify: Verification.Skipped, - expectedOutput: IncludeExpectedOutput("[2], [3], [4], ")); - verifier.VerifyIL("Program.Main", """ - { - // Code size 112 (0x70) - .maxstack 2 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.2 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_0 - IL_0019: ldc.i4.1 - IL_001a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_001f: call "R Program.ReturnsRefStruct(scoped System.Span)" - IL_0024: pop - IL_0025: ldloca.s V_1 - IL_0027: initobj "<>y__InlineArray1" - IL_002d: ldloca.s V_1 - IL_002f: ldc.i4.0 - IL_0030: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0035: ldc.i4.3 - IL_0036: box "int" - IL_003b: stind.ref - IL_003c: ldloca.s V_1 - IL_003e: ldc.i4.1 - IL_003f: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0044: call "ref int Program.ReturnsRef(scoped System.Span)" - IL_0049: pop - IL_004a: ldloca.s V_2 - IL_004c: initobj "<>y__InlineArray1" - IL_0052: ldloca.s V_2 - IL_0054: ldc.i4.0 - IL_0055: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_005a: ldc.i4.4 - IL_005b: box "int" - IL_0060: stind.ref - IL_0061: ldloca.s V_2 - IL_0063: ldc.i4.1 - IL_0064: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0069: call "ref readonly int Program.ReturnsRefReadOnly(scoped System.Span)" - IL_006e: pop - IL_006f: ret + expectedOutput: IncludeExpectedOutput("[2], [3], [4], ")); + verifier.VerifyIL("Program.Main", """ + { + // Code size 61 (0x3d) + .maxstack 1 + .locals init (object V_0, + object V_1, + object V_2) + IL_0000: ldc.i4.2 + IL_0001: box "int" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: newobj "System.Span..ctor(ref object)" + IL_000e: call "R Program.ReturnsRefStruct(scoped System.Span)" + IL_0013: pop + IL_0014: ldc.i4.3 + IL_0015: box "int" + IL_001a: stloc.1 + IL_001b: ldloca.s V_1 + IL_001d: newobj "System.Span..ctor(ref object)" + IL_0022: call "ref int Program.ReturnsRef(scoped System.Span)" + IL_0027: pop + IL_0028: ldc.i4.4 + IL_0029: box "int" + IL_002e: stloc.2 + IL_002f: ldloca.s V_2 + IL_0031: newobj "System.Span..ctor(ref object)" + IL_0036: call "ref readonly int Program.ReturnsRefReadOnly(scoped System.Span)" + IL_003b: pop + IL_003c: ret } """); } @@ -21239,105 +21636,69 @@ static void Main() expectedOutput: IncludeExpectedOutput("[1], [2], [3], [4], [5], [6], ")); verifier.VerifyIL("Program.Main", """ { - // Code size 280 (0x118) + // Code size 160 (0xa0) .maxstack 3 .locals init (S V_0, //s R1 V_1, //r1 R2 V_2, //r2 - <>y__InlineArray1 V_3, - <>y__InlineArray1 V_4, - <>y__InlineArray1 V_5, - <>y__InlineArray1 V_6, - <>y__InlineArray1 V_7, - <>y__InlineArray1 V_8) + int? V_3, + int? V_4, + int? V_5, + int? V_6, + int? V_7, + int? V_8) IL_0000: ldloca.s V_0 IL_0002: initobj "S" IL_0008: ldloca.s V_0 IL_000a: ldloca.s V_3 - IL_000c: initobj "<>y__InlineArray1" + IL_000c: ldc.i4.1 + IL_000d: call "int?..ctor(int)" IL_0012: ldloca.s V_3 - IL_0014: ldc.i4.0 - IL_0015: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_001a: ldc.i4.1 - IL_001b: newobj "int?..ctor(int)" - IL_0020: stobj "int?" - IL_0025: ldloca.s V_3 - IL_0027: ldc.i4.1 - IL_0028: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_002d: call "void S.M(System.ReadOnlySpan)" - IL_0032: ldloca.s V_0 - IL_0034: ldloca.s V_4 - IL_0036: initobj "<>y__InlineArray1" - IL_003c: ldloca.s V_4 - IL_003e: ldc.i4.0 - IL_003f: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_0044: ldc.i4.2 - IL_0045: newobj "int?..ctor(int)" - IL_004a: stobj "int?" - IL_004f: ldloca.s V_4 - IL_0051: ldc.i4.1 - IL_0052: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_0057: ldnull - IL_0058: call "void S.this[System.ReadOnlySpan].set" - IL_005d: ldloca.s V_1 - IL_005f: initobj "R1" - IL_0065: ldloca.s V_1 - IL_0067: ldloca.s V_5 - IL_0069: initobj "<>y__InlineArray1" - IL_006f: ldloca.s V_5 - IL_0071: ldc.i4.0 - IL_0072: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_0077: ldc.i4.3 - IL_0078: newobj "int?..ctor(int)" - IL_007d: stobj "int?" - IL_0082: ldloca.s V_5 - IL_0084: ldc.i4.1 - IL_0085: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_008a: call "void R1.M(System.ReadOnlySpan)" - IL_008f: ldloca.s V_1 - IL_0091: ldloca.s V_6 - IL_0093: initobj "<>y__InlineArray1" - IL_0099: ldloca.s V_6 - IL_009b: ldc.i4.0 - IL_009c: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_00a1: ldc.i4.4 - IL_00a2: newobj "int?..ctor(int)" - IL_00a7: stobj "int?" - IL_00ac: ldloca.s V_6 - IL_00ae: ldc.i4.1 - IL_00af: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_00b4: ldnull - IL_00b5: call "void R1.this[System.ReadOnlySpan].set" - IL_00ba: ldloca.s V_2 - IL_00bc: initobj "R2" - IL_00c2: ldloca.s V_2 - IL_00c4: ldloca.s V_7 - IL_00c6: initobj "<>y__InlineArray1" - IL_00cc: ldloca.s V_7 - IL_00ce: ldc.i4.0 - IL_00cf: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_00d4: ldc.i4.5 - IL_00d5: newobj "int?..ctor(int)" - IL_00da: stobj "int?" - IL_00df: ldloca.s V_7 - IL_00e1: ldc.i4.1 - IL_00e2: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_00e7: call "void R2.M(scoped System.ReadOnlySpan)" - IL_00ec: ldloca.s V_2 - IL_00ee: ldloca.s V_8 - IL_00f0: initobj "<>y__InlineArray1" - IL_00f6: ldloca.s V_8 - IL_00f8: ldc.i4.0 - IL_00f9: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_00fe: ldc.i4.6 - IL_00ff: newobj "int?..ctor(int)" - IL_0104: stobj "int?" - IL_0109: ldloca.s V_8 - IL_010b: ldc.i4.1 - IL_010c: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_0111: ldnull - IL_0112: call "void R2.this[scoped System.ReadOnlySpan].set" - IL_0117: ret + IL_0014: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0019: call "void S.M(System.ReadOnlySpan)" + IL_001e: ldloca.s V_0 + IL_0020: ldloca.s V_4 + IL_0022: ldc.i4.2 + IL_0023: call "int?..ctor(int)" + IL_0028: ldloca.s V_4 + IL_002a: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_002f: ldnull + IL_0030: call "void S.this[System.ReadOnlySpan].set" + IL_0035: ldloca.s V_1 + IL_0037: initobj "R1" + IL_003d: ldloca.s V_1 + IL_003f: ldloca.s V_5 + IL_0041: ldc.i4.3 + IL_0042: call "int?..ctor(int)" + IL_0047: ldloca.s V_5 + IL_0049: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_004e: call "void R1.M(System.ReadOnlySpan)" + IL_0053: ldloca.s V_1 + IL_0055: ldloca.s V_6 + IL_0057: ldc.i4.4 + IL_0058: call "int?..ctor(int)" + IL_005d: ldloca.s V_6 + IL_005f: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0064: ldnull + IL_0065: call "void R1.this[System.ReadOnlySpan].set" + IL_006a: ldloca.s V_2 + IL_006c: initobj "R2" + IL_0072: ldloca.s V_2 + IL_0074: ldloca.s V_7 + IL_0076: ldc.i4.5 + IL_0077: call "int?..ctor(int)" + IL_007c: ldloca.s V_7 + IL_007e: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0083: call "void R2.M(scoped System.ReadOnlySpan)" + IL_0088: ldloca.s V_2 + IL_008a: ldloca.s V_8 + IL_008c: ldc.i4.6 + IL_008d: call "int?..ctor(int)" + IL_0092: ldloca.s V_8 + IL_0094: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0099: ldnull + IL_009a: call "void R2.this[scoped System.ReadOnlySpan].set" + IL_009f: ret } """); } @@ -21377,73 +21738,49 @@ static void Main() expectedOutput: IncludeExpectedOutput("[3], [4], [5], [6], ")); verifier.VerifyIL("Program.Main", """ { - // Code size 187 (0xbb) + // Code size 107 (0x6b) .maxstack 3 .locals init (R1 V_0, //r1 R2 V_1, //r2 - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3, - <>y__InlineArray1 V_4, - <>y__InlineArray1 V_5) + int? V_2, + int? V_3, + int? V_4, + int? V_5) IL_0000: ldloca.s V_0 IL_0002: initobj "R1" IL_0008: ldloca.s V_0 IL_000a: ldloca.s V_2 - IL_000c: initobj "<>y__InlineArray1" + IL_000c: ldc.i4.3 + IL_000d: call "int?..ctor(int)" IL_0012: ldloca.s V_2 - IL_0014: ldc.i4.0 - IL_0015: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_001a: ldc.i4.3 - IL_001b: newobj "int?..ctor(int)" - IL_0020: stobj "int?" - IL_0025: ldloca.s V_2 - IL_0027: ldc.i4.1 - IL_0028: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_002d: call "void R1.M(System.ReadOnlySpan)" - IL_0032: ldloca.s V_0 - IL_0034: ldloca.s V_3 - IL_0036: initobj "<>y__InlineArray1" - IL_003c: ldloca.s V_3 - IL_003e: ldc.i4.0 - IL_003f: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_0044: ldc.i4.4 - IL_0045: newobj "int?..ctor(int)" - IL_004a: stobj "int?" - IL_004f: ldloca.s V_3 - IL_0051: ldc.i4.1 - IL_0052: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_0057: call "object R1.this[System.ReadOnlySpan].get" - IL_005c: pop - IL_005d: ldloca.s V_1 - IL_005f: initobj "R2" - IL_0065: ldloca.s V_1 - IL_0067: ldloca.s V_4 - IL_0069: initobj "<>y__InlineArray1" - IL_006f: ldloca.s V_4 - IL_0071: ldc.i4.0 - IL_0072: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_0077: ldc.i4.5 - IL_0078: newobj "int?..ctor(int)" - IL_007d: stobj "int?" - IL_0082: ldloca.s V_4 - IL_0084: ldc.i4.1 - IL_0085: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_008a: call "readonly void R2.M(System.ReadOnlySpan)" - IL_008f: ldloca.s V_1 - IL_0091: ldloca.s V_5 - IL_0093: initobj "<>y__InlineArray1" - IL_0099: ldloca.s V_5 - IL_009b: ldc.i4.0 - IL_009c: call "ref int? .InlineArrayElementRef<<>y__InlineArray1, int?>(ref <>y__InlineArray1, int)" - IL_00a1: ldc.i4.6 - IL_00a2: newobj "int?..ctor(int)" - IL_00a7: stobj "int?" - IL_00ac: ldloca.s V_5 - IL_00ae: ldc.i4.1 - IL_00af: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int?>(in <>y__InlineArray1, int)" - IL_00b4: call "readonly object R2.this[System.ReadOnlySpan].get" - IL_00b9: pop - IL_00ba: ret + IL_0014: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0019: call "void R1.M(System.ReadOnlySpan)" + IL_001e: ldloca.s V_0 + IL_0020: ldloca.s V_3 + IL_0022: ldc.i4.4 + IL_0023: call "int?..ctor(int)" + IL_0028: ldloca.s V_3 + IL_002a: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_002f: call "object R1.this[System.ReadOnlySpan].get" + IL_0034: pop + IL_0035: ldloca.s V_1 + IL_0037: initobj "R2" + IL_003d: ldloca.s V_1 + IL_003f: ldloca.s V_4 + IL_0041: ldc.i4.5 + IL_0042: call "int?..ctor(int)" + IL_0047: ldloca.s V_4 + IL_0049: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_004e: call "readonly void R2.M(System.ReadOnlySpan)" + IL_0053: ldloca.s V_1 + IL_0055: ldloca.s V_5 + IL_0057: ldc.i4.6 + IL_0058: call "int?..ctor(int)" + IL_005d: ldloca.s V_5 + IL_005f: newobj "System.ReadOnlySpan..ctor(ref readonly int?)" + IL_0064: call "readonly object R2.this[System.ReadOnlySpan].get" + IL_0069: pop + IL_006a: ret } """); } @@ -21471,52 +21808,34 @@ static void Main() expectedOutput: IncludeExpectedOutput("[1], [3], [2], [4], ")); verifier.VerifyIL("Program.Main", """ { - // Code size 113 (0x71) - .maxstack 3 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref int .InlineArrayElementRef<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_0010: ldloca.s V_1 - IL_0012: initobj "<>y__InlineArray1" - IL_0018: ldloca.s V_1 - IL_001a: ldc.i4.0 - IL_001b: call "ref int .InlineArrayElementRef<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_0020: ldc.i4.1 - IL_0021: stind.i4 - IL_0022: ldloca.s V_1 - IL_0024: ldc.i4.1 - IL_0025: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_002a: call "int Program.F1(System.Span)" - IL_002f: ldc.i4.2 - IL_0030: add - IL_0031: stind.i4 - IL_0032: ldloca.s V_0 - IL_0034: ldc.i4.1 - IL_0035: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_003a: call "int Program.F1(System.Span)" - IL_003f: pop - IL_0040: ldloca.s V_2 - IL_0042: initobj "<>y__InlineArray1" - IL_0048: ldloca.s V_2 - IL_004a: ldc.i4.0 - IL_004b: call "ref int .InlineArrayElementRef<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_0050: ldtoken ".__StaticArrayInitTypeSize=4_Align=4 .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE4" - IL_0055: call "System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)" - IL_005a: call "int Program.F2(System.ReadOnlySpan)" - IL_005f: ldc.i4.2 - IL_0060: add - IL_0061: stind.i4 - IL_0062: ldloca.s V_2 - IL_0064: ldc.i4.1 - IL_0065: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, int>(in <>y__InlineArray1, int)" - IL_006a: call "int Program.F2(System.ReadOnlySpan)" - IL_006f: pop - IL_0070: ret + // Code size 62 (0x3e) + .maxstack 2 + .locals init (int V_0, + int V_1, + int V_2) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: newobj "System.Span..ctor(ref int)" + IL_0009: call "int Program.F1(System.Span)" + IL_000e: ldc.i4.2 + IL_000f: add + IL_0010: stloc.1 + IL_0011: ldloca.s V_1 + IL_0013: newobj "System.Span..ctor(ref int)" + IL_0018: call "int Program.F1(System.Span)" + IL_001d: pop + IL_001e: ldtoken ".__StaticArrayInitTypeSize=4_Align=4 .26B25D457597A7B0463F9620F666DD10AA2C4373A505967C7C8D70922A2D6ECE4" + IL_0023: call "System.ReadOnlySpan System.Runtime.CompilerServices.RuntimeHelpers.CreateSpan(System.RuntimeFieldHandle)" + IL_0028: call "int Program.F2(System.ReadOnlySpan)" + IL_002d: ldc.i4.2 + IL_002e: add + IL_002f: stloc.2 + IL_0030: ldloca.s V_2 + IL_0032: newobj "System.ReadOnlySpan..ctor(ref readonly int)" + IL_0037: call "int Program.F2(System.ReadOnlySpan)" + IL_003c: pop + IL_003d: ret } """); } @@ -21554,67 +21873,43 @@ static ReadOnlySpan F2(scoped ReadOnlySpan x, ReadOnlySpan y) expectedOutput: IncludeExpectedOutput("[2], [1], [4], [3], ")); verifier.VerifyIL("Program.Main", """ { - // Code size 145 (0x91) + // Code size 77 (0x4d) .maxstack 2 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3, + .locals init (object V_0, + object V_1, + object V_2, + object V_3, System.Span V_4, System.ReadOnlySpan V_5) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: newobj "System.Span..ctor(ref object)" + IL_000e: stloc.s V_4 + IL_0010: ldc.i4.2 IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_0 - IL_0019: ldc.i4.1 - IL_001a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_001f: stloc.s V_4 - IL_0021: ldloca.s V_1 - IL_0023: initobj "<>y__InlineArray1" - IL_0029: ldloca.s V_1 - IL_002b: ldc.i4.0 - IL_002c: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0031: ldc.i4.2 - IL_0032: box "int" - IL_0037: stind.ref - IL_0038: ldloca.s V_1 - IL_003a: ldc.i4.1 - IL_003b: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0040: ldloc.s V_4 - IL_0042: call "System.Span Program.F1(System.Span, scoped System.Span)" - IL_0047: pop - IL_0048: ldloca.s V_2 - IL_004a: initobj "<>y__InlineArray1" - IL_0050: ldloca.s V_2 - IL_0052: ldc.i4.0 - IL_0053: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0058: ldc.i4.3 - IL_0059: box "int" - IL_005e: stind.ref - IL_005f: ldloca.s V_2 - IL_0061: ldc.i4.1 - IL_0062: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0067: stloc.s V_5 - IL_0069: ldloca.s V_3 - IL_006b: initobj "<>y__InlineArray1" - IL_0071: ldloca.s V_3 - IL_0073: ldc.i4.0 - IL_0074: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0079: ldc.i4.4 - IL_007a: box "int" - IL_007f: stind.ref - IL_0080: ldloca.s V_3 - IL_0082: ldc.i4.1 - IL_0083: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0088: ldloc.s V_5 - IL_008a: call "System.ReadOnlySpan Program.F2(scoped System.ReadOnlySpan, System.ReadOnlySpan)" - IL_008f: pop - IL_0090: ret + IL_0016: stloc.1 + IL_0017: ldloca.s V_1 + IL_0019: newobj "System.Span..ctor(ref object)" + IL_001e: ldloc.s V_4 + IL_0020: call "System.Span Program.F1(System.Span, scoped System.Span)" + IL_0025: pop + IL_0026: ldc.i4.3 + IL_0027: box "int" + IL_002c: stloc.2 + IL_002d: ldloca.s V_2 + IL_002f: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0034: stloc.s V_5 + IL_0036: ldc.i4.4 + IL_0037: box "int" + IL_003c: stloc.3 + IL_003d: ldloca.s V_3 + IL_003f: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0044: ldloc.s V_5 + IL_0046: call "System.ReadOnlySpan Program.F2(scoped System.ReadOnlySpan, System.ReadOnlySpan)" + IL_004b: pop + IL_004c: ret } """); } @@ -21868,48 +22163,36 @@ static object[] F2() expectedOutput: IncludeExpectedOutput("[1], [2], ")); verifier.VerifyIL("Program.F1", """ { - // Code size 40 (0x28) - .maxstack 2 - .locals init (System.Span V_0, //s1 - <>y__InlineArray1 V_1) - IL_0000: ldloca.s V_1 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_1 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_1 - IL_0019: ldc.i4.1 - IL_001a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_001f: stloc.0 - IL_0020: ldloca.s V_0 - IL_0022: call "object[] System.Span.ToArray()" - IL_0027: ret + // Code size 23 (0x17) + .maxstack 1 + .locals init (System.Span V_0, //s1 + object V_1) + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.1 + IL_0007: ldloca.s V_1 + IL_0009: newobj "System.Span..ctor(ref object)" + IL_000e: stloc.0 + IL_000f: ldloca.s V_0 + IL_0011: call "object[] System.Span.ToArray()" + IL_0016: ret } """); verifier.VerifyIL("Program.F2", """ { - // Code size 40 (0x28) - .maxstack 2 - .locals init (System.ReadOnlySpan V_0, //s2 - <>y__InlineArray1 V_1) - IL_0000: ldloca.s V_1 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_1 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.2 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_1 - IL_0019: ldc.i4.1 - IL_001a: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_001f: stloc.0 - IL_0020: ldloca.s V_0 - IL_0022: call "object[] System.ReadOnlySpan.ToArray()" - IL_0027: ret + // Code size 23 (0x17) + .maxstack 1 + .locals init (System.ReadOnlySpan V_0, //s2 + object V_1) + IL_0000: ldc.i4.2 + IL_0001: box "int" + IL_0006: stloc.1 + IL_0007: ldloca.s V_1 + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_000e: stloc.0 + IL_000f: ldloca.s V_0 + IL_0011: call "object[] System.ReadOnlySpan.ToArray()" + IL_0016: ret } """); } @@ -21942,41 +22225,29 @@ static void Main() { verifier.VerifyIL("Program.Main", """ { - // Code size 79 (0x4f) - .maxstack 2 + // Code size 45 (0x2d) + .maxstack 1 .locals init (System.Span V_0, //x System.ReadOnlySpan V_1, //y - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3) - IL_0000: ldloca.s V_2 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_2 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_2 - IL_0019: ldc.i4.1 - IL_001a: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_001f: stloc.0 - IL_0020: ldloca.s V_3 - IL_0022: initobj "<>y__InlineArray1" - IL_0028: ldloca.s V_3 - IL_002a: ldc.i4.0 - IL_002b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0030: ldc.i4.2 - IL_0031: box "int" - IL_0036: stind.ref - IL_0037: ldloca.s V_3 - IL_0039: ldc.i4.1 - IL_003a: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_003f: stloc.1 - IL_0040: ldloca.s V_0 - IL_0042: call "void CollectionExtensions.Report(in System.Span)" - IL_0047: ldloca.s V_1 - IL_0049: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_004e: ret + object V_2, + object V_3) + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.2 + IL_0007: ldloca.s V_2 + IL_0009: newobj "System.Span..ctor(ref object)" + IL_000e: stloc.0 + IL_000f: ldc.i4.2 + IL_0010: box "int" + IL_0015: stloc.3 + IL_0016: ldloca.s V_3 + IL_0018: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_001d: stloc.1 + IL_001e: ldloca.s V_0 + IL_0020: call "void CollectionExtensions.Report(in System.Span)" + IL_0025: ldloca.s V_1 + IL_0027: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_002c: ret } """); } @@ -22070,49 +22341,37 @@ static void Main() expectedOutput: IncludeExpectedOutput("[1], [2], ")); verifier.VerifyIL("Program.Main", """ { - // Code size 117 (0x75) - .maxstack 3 + // Code size 83 (0x53) + .maxstack 2 .locals init (R V_0, //x R V_1, //y - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3) + object V_2, + object V_3) IL_0000: ldloca.s V_0 IL_0002: initobj "R" IL_0008: ldloca.s V_1 IL_000a: initobj "R" IL_0010: ldloca.s V_0 - IL_0012: ldloca.s V_2 - IL_0014: initobj "<>y__InlineArray1" - IL_001a: ldloca.s V_2 - IL_001c: ldc.i4.0 - IL_001d: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0022: ldc.i4.1 - IL_0023: box "int" - IL_0028: stind.ref - IL_0029: ldloca.s V_2 - IL_002b: ldc.i4.1 - IL_002c: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0031: stfld "System.ReadOnlySpan R.F" - IL_0036: ldloca.s V_1 - IL_0038: ldloca.s V_3 - IL_003a: initobj "<>y__InlineArray1" - IL_0040: ldloca.s V_3 - IL_0042: ldc.i4.0 - IL_0043: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0048: ldc.i4.2 - IL_0049: box "int" - IL_004e: stind.ref - IL_004f: ldloca.s V_3 - IL_0051: ldc.i4.1 - IL_0052: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0057: stfld "System.ReadOnlySpan R.F" - IL_005c: ldloca.s V_0 - IL_005e: ldflda "System.ReadOnlySpan R.F" - IL_0063: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_0068: ldloca.s V_1 - IL_006a: ldflda "System.ReadOnlySpan R.F" - IL_006f: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_0074: ret + IL_0012: ldc.i4.1 + IL_0013: box "int" + IL_0018: stloc.2 + IL_0019: ldloca.s V_2 + IL_001b: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0020: stfld "System.ReadOnlySpan R.F" + IL_0025: ldloca.s V_1 + IL_0027: ldc.i4.2 + IL_0028: box "int" + IL_002d: stloc.3 + IL_002e: ldloca.s V_3 + IL_0030: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0035: stfld "System.ReadOnlySpan R.F" + IL_003a: ldloca.s V_0 + IL_003c: ldflda "System.ReadOnlySpan R.F" + IL_0041: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_0046: ldloca.s V_1 + IL_0048: ldflda "System.ReadOnlySpan R.F" + IL_004d: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_0052: ret } """); } @@ -22372,64 +22631,40 @@ static void F(bool b) { verifier.VerifyIL("Program.F", """ { - // Code size 134 (0x86) - .maxstack 2 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_0 - IL_0019: ldc.i4.1 - IL_001a: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_001f: pop - IL_0020: ldarg.0 - IL_0021: brfalse.s IL_0045 - IL_0023: ldloca.s V_1 - IL_0025: initobj "<>y__InlineArray1" - IL_002b: ldloca.s V_1 - IL_002d: ldc.i4.0 - IL_002e: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0033: ldc.i4.2 - IL_0034: box "int" - IL_0039: stind.ref - IL_003a: ldloca.s V_1 - IL_003c: ldc.i4.1 - IL_003d: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0042: pop - IL_0043: br.s IL_0065 - IL_0045: ldloca.s V_2 - IL_0047: initobj "<>y__InlineArray1" - IL_004d: ldloca.s V_2 - IL_004f: ldc.i4.0 - IL_0050: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0055: ldc.i4.3 - IL_0056: box "int" - IL_005b: stind.ref - IL_005c: ldloca.s V_2 - IL_005e: ldc.i4.1 - IL_005f: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0064: pop - IL_0065: ldloca.s V_3 - IL_0067: initobj "<>y__InlineArray1" - IL_006d: ldloca.s V_3 - IL_006f: ldc.i4.0 - IL_0070: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0075: ldc.i4.4 - IL_0076: box "int" - IL_007b: stind.ref - IL_007c: ldloca.s V_3 - IL_007e: ldc.i4.1 - IL_007f: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0084: pop - IL_0085: ret + // Code size 66 (0x42) + .maxstack 1 + .locals init (object V_0, + object V_1, + object V_2, + object V_3) + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_000e: pop + IL_000f: ldarg.0 + IL_0010: brfalse.s IL_0023 + IL_0012: ldc.i4.2 + IL_0013: box "int" + IL_0018: stloc.1 + IL_0019: ldloca.s V_1 + IL_001b: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0020: pop + IL_0021: br.s IL_0032 + IL_0023: ldc.i4.3 + IL_0024: box "int" + IL_0029: stloc.2 + IL_002a: ldloca.s V_2 + IL_002c: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0031: pop + IL_0032: ldc.i4.4 + IL_0033: box "int" + IL_0038: stloc.3 + IL_0039: ldloca.s V_3 + IL_003b: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0040: pop + IL_0041: ret } """); } @@ -22687,25 +22922,19 @@ void A2() expectedOutput: IncludeExpectedOutput("[1], [2], [3], [4], [1], ")); verifier.VerifyIL("Program.<>c__DisplayClass1_0.g__A2|1()", """ { - // Code size 44 (0x2c) - .maxstack 2 + // Code size 23 (0x17) + .maxstack 1 .locals init (System.Span V_0, //s3 - <>y__InlineArray1 V_1) - IL_0000: ldloca.s V_1 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_1 - IL_000a: ldc.i4.0 - IL_000b: call "ref T .InlineArrayElementRef<<>y__InlineArray1, T>(ref <>y__InlineArray1, int)" - IL_0010: ldarg.0 - IL_0011: ldfld "T Program.<>c__DisplayClass1_0.z" - IL_0016: stobj "T" - IL_001b: ldloca.s V_1 - IL_001d: ldc.i4.1 - IL_001e: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, T>(ref <>y__InlineArray1, int)" - IL_0023: stloc.0 - IL_0024: ldloca.s V_0 - IL_0026: call "void CollectionExtensions.Report(in System.Span)" - IL_002b: ret + T V_1) + IL_0000: ldarg.0 + IL_0001: ldfld "T Program.<>c__DisplayClass1_0.z" + IL_0006: stloc.1 + IL_0007: ldloca.s V_1 + IL_0009: newobj "System.Span..ctor(ref T)" + IL_000e: stloc.0 + IL_000f: ldloca.s V_0 + IL_0011: call "void CollectionExtensions.Report(in System.Span)" + IL_0016: ret } """); } @@ -22747,10 +22976,10 @@ static void Main() expectedOutput: IncludeExpectedOutput("[b], [a], ")); verifier.VerifyIL("C.<>c.<.ctor>b__1_0(T, T)", """ { - // Code size 76 (0x4c) + // Code size 55 (0x37) .maxstack 2 .locals init (System.ReadOnlySpan V_0, //r1 - <>y__InlineArray1 V_1) + T V_1) IL_0000: ldsfld "System.Action C.<>c.<>9__1_1" IL_0005: dup IL_0006: brtrue.s IL_001f @@ -22762,20 +22991,14 @@ .locals init (System.ReadOnlySpan V_0, //r1 IL_001a: stsfld "System.Action C.<>c.<>9__1_1" IL_001f: ldarg.2 IL_0020: callvirt "void System.Action.Invoke(T)" - IL_0025: ldloca.s V_1 - IL_0027: initobj "<>y__InlineArray1" - IL_002d: ldloca.s V_1 - IL_002f: ldc.i4.0 - IL_0030: call "ref T .InlineArrayElementRef<<>y__InlineArray1, T>(ref <>y__InlineArray1, int)" - IL_0035: ldarg.1 - IL_0036: stobj "T" - IL_003b: ldloca.s V_1 - IL_003d: ldc.i4.1 - IL_003e: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, T>(in <>y__InlineArray1, int)" - IL_0043: stloc.0 - IL_0044: ldloca.s V_0 - IL_0046: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_004b: ret + IL_0025: ldarg.1 + IL_0026: stloc.1 + IL_0027: ldloca.s V_1 + IL_0029: newobj "System.ReadOnlySpan..ctor(ref readonly T)" + IL_002e: stloc.0 + IL_002f: ldloca.s V_0 + IL_0031: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_0036: ret } """); } @@ -22804,60 +23027,48 @@ static void Main() var verifier = CompileAndVerify( new[] { source, s_collectionExtensionsWithSpan }, targetFramework: TargetFramework.Net80, - verify: Verification.Fails, + verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("[1], [2], Disposed, ")); verifier.VerifyIL("Program.Main", """ { - // Code size 97 (0x61) - .maxstack 2 + // Code size 64 (0x40) + .maxstack 1 .locals init (System.ReadOnlySpan V_0, //x Disposable V_1, //d System.ReadOnlySpan V_2, //y - <>y__InlineArray1 V_3, - <>y__InlineArray1 V_4) - IL_0000: ldloca.s V_3 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_3 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: box "int" - IL_0016: stind.ref - IL_0017: ldloca.s V_3 - IL_0019: ldc.i4.1 - IL_001a: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_001f: stloc.0 - IL_0020: newobj "Disposable..ctor()" - IL_0025: stloc.1 + object V_3, + object V_4) + IL_0000: ldc.i4.1 + IL_0001: box "int" + IL_0006: stloc.3 + IL_0007: ldloca.s V_3 + IL_0009: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_000e: stloc.0 + IL_000f: newobj "Disposable..ctor()" + IL_0014: stloc.1 .try { - IL_0026: ldloca.s V_4 - IL_0028: initobj "<>y__InlineArray1" - IL_002e: ldloca.s V_4 - IL_0030: ldc.i4.0 - IL_0031: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0036: ldc.i4.2 - IL_0037: box "int" - IL_003c: stind.ref - IL_003d: ldloca.s V_4 - IL_003f: ldc.i4.1 - IL_0040: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_0045: stloc.2 - IL_0046: ldloca.s V_0 - IL_0048: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_004d: ldloca.s V_2 - IL_004f: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" - IL_0054: leave.s IL_0060 + IL_0015: ldc.i4.2 + IL_0016: box "int" + IL_001b: stloc.s V_4 + IL_001d: ldloca.s V_4 + IL_001f: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_0024: stloc.2 + IL_0025: ldloca.s V_0 + IL_0027: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_002c: ldloca.s V_2 + IL_002e: call "void CollectionExtensions.Report(in System.ReadOnlySpan)" + IL_0033: leave.s IL_003f } finally { - IL_0056: ldloc.1 - IL_0057: brfalse.s IL_005f - IL_0059: ldloc.1 - IL_005a: callvirt "void System.IDisposable.Dispose()" - IL_005f: endfinally + IL_0035: ldloc.1 + IL_0036: brfalse.s IL_003e + IL_0038: ldloc.1 + IL_0039: callvirt "void System.IDisposable.Dispose()" + IL_003e: endfinally } - IL_0060: ret + IL_003f: ret } """); } @@ -23247,59 +23458,35 @@ static void Report(ReadOnlySpan s) """)); verifier.VerifyIL("Program.Main", """ { - // Code size 135 (0x87) - .maxstack 2 - .locals init (<>y__InlineArray1 V_0, - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2, - <>y__InlineArray1 V_3) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref object .InlineArrayElementRef<<>y__InlineArray1, object>(ref <>y__InlineArray1, int)" - IL_0010: ldstr "1" - IL_0015: stind.ref - IL_0016: ldloca.s V_0 - IL_0018: ldc.i4.1 - IL_0019: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, object>(in <>y__InlineArray1, int)" - IL_001e: call "void Program.Report(System.ReadOnlySpan)" - IL_0023: ldloca.s V_1 - IL_0025: initobj "<>y__InlineArray1" - IL_002b: ldloca.s V_1 - IL_002d: ldc.i4.0 - IL_002e: call "ref string .InlineArrayElementRef<<>y__InlineArray1, string>(ref <>y__InlineArray1, int)" - IL_0033: ldstr "2" - IL_0038: stind.ref - IL_0039: ldloca.s V_1 - IL_003b: ldc.i4.1 - IL_003c: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, string>(in <>y__InlineArray1, int)" - IL_0041: call "void Program.Report(System.ReadOnlySpan)" - IL_0046: ldloca.s V_2 - IL_0048: initobj "<>y__InlineArray1" - IL_004e: ldloca.s V_2 - IL_0050: ldc.i4.0 - IL_0051: call "ref nint .InlineArrayElementRef<<>y__InlineArray1, nint>(ref <>y__InlineArray1, int)" - IL_0056: ldc.i4.3 - IL_0057: conv.i - IL_0058: stind.i - IL_0059: ldloca.s V_2 - IL_005b: ldc.i4.1 - IL_005c: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, nint>(in <>y__InlineArray1, int)" - IL_0061: call "void Program.Report(System.ReadOnlySpan)" - IL_0066: ldloca.s V_3 - IL_0068: initobj "<>y__InlineArray1" - IL_006e: ldloca.s V_3 - IL_0070: ldc.i4.0 - IL_0071: call "ref nuint .InlineArrayElementRef<<>y__InlineArray1, nuint>(ref <>y__InlineArray1, int)" - IL_0076: ldc.i4.4 - IL_0077: conv.i - IL_0078: stind.i - IL_0079: ldloca.s V_3 - IL_007b: ldc.i4.1 - IL_007c: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, nuint>(in <>y__InlineArray1, int)" - IL_0081: call "void Program.Report(System.ReadOnlySpan)" - IL_0086: ret + // Code size 67 (0x43) + .maxstack 1 + .locals init (object V_0, + string V_1, + nint V_2, + nuint V_3) + IL_0000: ldstr "1" + IL_0005: stloc.0 + IL_0006: ldloca.s V_0 + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly object)" + IL_000d: call "void Program.Report(System.ReadOnlySpan)" + IL_0012: ldstr "2" + IL_0017: stloc.1 + IL_0018: ldloca.s V_1 + IL_001a: newobj "System.ReadOnlySpan..ctor(ref readonly string)" + IL_001f: call "void Program.Report(System.ReadOnlySpan)" + IL_0024: ldc.i4.3 + IL_0025: conv.i + IL_0026: stloc.2 + IL_0027: ldloca.s V_2 + IL_0029: newobj "System.ReadOnlySpan..ctor(ref readonly nint)" + IL_002e: call "void Program.Report(System.ReadOnlySpan)" + IL_0033: ldc.i4.4 + IL_0034: conv.i + IL_0035: stloc.3 + IL_0036: ldloca.s V_3 + IL_0038: newobj "System.ReadOnlySpan..ctor(ref readonly nuint)" + IL_003d: call "void Program.Report(System.ReadOnlySpan)" + IL_0042: ret } """); } @@ -25847,7 +26034,7 @@ static void Main() } """; CreateCompilation(source).VerifyEmitDiagnostics( - // (7,17): error CS9503: There is no target type for the collection expression. + // (7,17): error CS9176: There is no target type for the collection expression. // var v = []->Count; Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[]").WithLocation(7, 17)); } @@ -25910,7 +26097,7 @@ static void Main(List list) } """; CreateCompilationWithIndexAndRangeAndSpan(source).VerifyEmitDiagnostics( - // (7,9): error CS9500: Cannot initialize type 'Index' with a collection expression because the type is not constructible. + // (7,9): error CS9174: Cannot initialize type 'Index' with a collection expression because the type is not constructible. // []..; Diagnostic(ErrorCode.ERR_CollectionExpressionTargetTypeNotConstructible, "[]").WithArguments("System.Index").WithLocation(7, 9), // (7,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement @@ -25933,7 +26120,7 @@ static void Main(List list) } """; CreateCompilation(source).VerifyEmitDiagnostics( - // (7,9): error CS9503: There is no target type for the collection expression. + // (7,9): error CS9176: There is no target type for the collection expression. // [] switch Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[]").WithLocation(7, 9), // (7,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement @@ -25956,7 +26143,7 @@ static void Main(List list) } """; CreateCompilation(source).VerifyEmitDiagnostics( - // (7,9): error CS9503: There is no target type for the collection expression. + // (7,9): error CS9176: There is no target type for the collection expression. // [] with { Count = 1, }; Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[]").WithLocation(7, 9), // (7,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement @@ -25979,7 +26166,7 @@ static void Main(List list) } """; CreateCompilation(source).VerifyEmitDiagnostics( - // (7,9): error CS9503: There is no target type for the collection expression. + // (7,9): error CS9176: There is no target type for the collection expression. // [] is object; Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[]").WithLocation(7, 9), // (7,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement @@ -26002,7 +26189,7 @@ static void Main(List list) } """; CreateCompilation(source).VerifyEmitDiagnostics( - // (7,9): error CS9503: There is no target type for the collection expression. + // (7,9): error CS9176: There is no target type for the collection expression. // [] as List; Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[]").WithLocation(7, 9), // (7,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement @@ -28596,29 +28783,23 @@ .maxstack 4 verifier.VerifyDiagnostics(); verifier.VerifyIL("Program.M", """ { - // Code size 44 (0x2c) + // Code size 27 (0x1b) .maxstack 4 - .locals init (<>y__InlineArray1 V_0) - IL_0000: ldloca.s V_0 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_0 - IL_000a: ldc.i4.0 - IL_000b: call "ref int .InlineArrayElementRef<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_0010: ldc.i4.1 - IL_0011: stind.i4 - IL_0012: ldloca.s V_0 - IL_0014: ldc.i4.1 - IL_0015: call "System.Span .InlineArrayAsSpan<<>y__InlineArray1, int>(ref <>y__InlineArray1, int)" - IL_001a: pop - IL_001b: ldc.i4.1 - IL_001c: newarr "int" - IL_0021: dup - IL_0022: ldc.i4.0 - IL_0023: ldc.i4.1 - IL_0024: stelem.i4 - IL_0025: call "System.Span System.Span.op_Implicit(int[])" - IL_002a: pop - IL_002b: ret + .locals init (int V_0) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: newobj "System.Span..ctor(ref int)" + IL_0009: pop + IL_000a: ldc.i4.1 + IL_000b: newarr "int" + IL_0010: dup + IL_0011: ldc.i4.0 + IL_0012: ldc.i4.1 + IL_0013: stelem.i4 + IL_0014: call "System.Span System.Span.op_Implicit(int[])" + IL_0019: pop + IL_001a: ret } """); } @@ -28647,9 +28828,6 @@ class Program """; var comp = CreateCompilation(source); comp.VerifyEmitDiagnostics( - // (2,16): error CS8343: 'S': ref structs cannot implement interfaces - // ref struct S : IEnumerable - Diagnostic(ErrorCode.ERR_RefStructInterfaceImpl, "IEnumerable").WithArguments("S").WithLocation(2, 16), // (4,28): error CS0611: Array elements cannot be of type 'S' // public void Add(params S[] x) => throw null; Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "S").WithArguments("S").WithLocation(4, 28), @@ -28678,9 +28856,6 @@ class Program """; var comp = CreateCompilation(source); comp.VerifyEmitDiagnostics( - // (3,19): error CS8343: 'S': ref structs cannot implement interfaces - // ref struct S : IEnumerable - Diagnostic(ErrorCode.ERR_RefStructInterfaceImpl, "IEnumerable").WithArguments("S").WithLocation(3, 19), // (11,26): error CS9203: A collection expression of type 'S' cannot be used in this context because it may be exposed outside of the current scope. // static S F() => [1, 2, 3]; Diagnostic(ErrorCode.ERR_CollectionExpressionEscape, "[1, 2, 3]").WithArguments("S").WithLocation(11, 26)); @@ -31497,92 +31672,80 @@ class D : C { } verifier.VerifyDiagnostics(); verifier.VerifyIL("C.Main", """ { - // Code size 185 (0xb9) + // Code size 151 (0x97) .maxstack 3 .locals init (System.ReadOnlySpan V_0, //li1 - <>y__InlineArray1 V_1, - <>y__InlineArray1 V_2, + D V_1, + D V_2, System.ReadOnlySpan V_3, System.ReadOnlySpan V_4, int V_5, C[] V_6, System.ReadOnlySpan.Enumerator V_7, D V_8) - IL_0000: ldloca.s V_1 - IL_0002: initobj "<>y__InlineArray1" - IL_0008: ldloca.s V_1 - IL_000a: ldc.i4.0 - IL_000b: call "ref D .InlineArrayElementRef<<>y__InlineArray1, D>(ref <>y__InlineArray1, int)" - IL_0010: newobj "D..ctor()" - IL_0015: stind.ref - IL_0016: ldloca.s V_1 - IL_0018: ldc.i4.1 - IL_0019: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, D>(in <>y__InlineArray1, int)" - IL_001e: stloc.0 - IL_001f: ldloca.s V_2 - IL_0021: initobj "<>y__InlineArray1" - IL_0027: ldloca.s V_2 - IL_0029: ldc.i4.0 - IL_002a: call "ref D .InlineArrayElementRef<<>y__InlineArray1, D>(ref <>y__InlineArray1, int)" - IL_002f: newobj "D..ctor()" - IL_0034: stind.ref - IL_0035: ldloca.s V_2 - IL_0037: ldc.i4.1 - IL_0038: call "System.ReadOnlySpan .InlineArrayAsReadOnlySpan<<>y__InlineArray1, D>(in <>y__InlineArray1, int)" - IL_003d: ldloc.0 - IL_003e: stloc.3 - IL_003f: stloc.s V_4 - IL_0041: ldc.i4.0 - IL_0042: stloc.s V_5 - IL_0044: ldloca.s V_3 - IL_0046: call "int System.ReadOnlySpan.Length.get" - IL_004b: ldloca.s V_4 - IL_004d: call "int System.ReadOnlySpan.Length.get" - IL_0052: add - IL_0053: newarr "C" - IL_0058: stloc.s V_6 - IL_005a: ldloca.s V_3 - IL_005c: call "System.ReadOnlySpan.Enumerator System.ReadOnlySpan.GetEnumerator()" - IL_0061: stloc.s V_7 - IL_0063: br.s IL_007c - IL_0065: ldloca.s V_7 - IL_0067: call "ref readonly D System.ReadOnlySpan.Enumerator.Current.get" - IL_006c: ldind.ref - IL_006d: stloc.s V_8 - IL_006f: ldloc.s V_6 - IL_0071: ldloc.s V_5 - IL_0073: ldloc.s V_8 - IL_0075: stelem.ref - IL_0076: ldloc.s V_5 - IL_0078: ldc.i4.1 - IL_0079: add - IL_007a: stloc.s V_5 - IL_007c: ldloca.s V_7 - IL_007e: call "bool System.ReadOnlySpan.Enumerator.MoveNext()" - IL_0083: brtrue.s IL_0065 - IL_0085: ldloca.s V_4 - IL_0087: call "System.ReadOnlySpan.Enumerator System.ReadOnlySpan.GetEnumerator()" - IL_008c: stloc.s V_7 - IL_008e: br.s IL_00a7 - IL_0090: ldloca.s V_7 - IL_0092: call "ref readonly D System.ReadOnlySpan.Enumerator.Current.get" - IL_0097: ldind.ref - IL_0098: stloc.s V_8 - IL_009a: ldloc.s V_6 - IL_009c: ldloc.s V_5 - IL_009e: ldloc.s V_8 - IL_00a0: stelem.ref - IL_00a1: ldloc.s V_5 - IL_00a3: ldc.i4.1 - IL_00a4: add - IL_00a5: stloc.s V_5 - IL_00a7: ldloca.s V_7 - IL_00a9: call "bool System.ReadOnlySpan.Enumerator.MoveNext()" - IL_00ae: brtrue.s IL_0090 - IL_00b0: ldloc.s V_6 - IL_00b2: ldc.i4.0 - IL_00b3: call "void CollectionExtensions.Report(object, bool)" - IL_00b8: ret + IL_0000: newobj "D..ctor()" + IL_0005: stloc.1 + IL_0006: ldloca.s V_1 + IL_0008: newobj "System.ReadOnlySpan..ctor(ref readonly D)" + IL_000d: stloc.0 + IL_000e: newobj "D..ctor()" + IL_0013: stloc.2 + IL_0014: ldloca.s V_2 + IL_0016: newobj "System.ReadOnlySpan..ctor(ref readonly D)" + IL_001b: ldloc.0 + IL_001c: stloc.3 + IL_001d: stloc.s V_4 + IL_001f: ldc.i4.0 + IL_0020: stloc.s V_5 + IL_0022: ldloca.s V_3 + IL_0024: call "int System.ReadOnlySpan.Length.get" + IL_0029: ldloca.s V_4 + IL_002b: call "int System.ReadOnlySpan.Length.get" + IL_0030: add + IL_0031: newarr "C" + IL_0036: stloc.s V_6 + IL_0038: ldloca.s V_3 + IL_003a: call "System.ReadOnlySpan.Enumerator System.ReadOnlySpan.GetEnumerator()" + IL_003f: stloc.s V_7 + IL_0041: br.s IL_005a + IL_0043: ldloca.s V_7 + IL_0045: call "ref readonly D System.ReadOnlySpan.Enumerator.Current.get" + IL_004a: ldind.ref + IL_004b: stloc.s V_8 + IL_004d: ldloc.s V_6 + IL_004f: ldloc.s V_5 + IL_0051: ldloc.s V_8 + IL_0053: stelem.ref + IL_0054: ldloc.s V_5 + IL_0056: ldc.i4.1 + IL_0057: add + IL_0058: stloc.s V_5 + IL_005a: ldloca.s V_7 + IL_005c: call "bool System.ReadOnlySpan.Enumerator.MoveNext()" + IL_0061: brtrue.s IL_0043 + IL_0063: ldloca.s V_4 + IL_0065: call "System.ReadOnlySpan.Enumerator System.ReadOnlySpan.GetEnumerator()" + IL_006a: stloc.s V_7 + IL_006c: br.s IL_0085 + IL_006e: ldloca.s V_7 + IL_0070: call "ref readonly D System.ReadOnlySpan.Enumerator.Current.get" + IL_0075: ldind.ref + IL_0076: stloc.s V_8 + IL_0078: ldloc.s V_6 + IL_007a: ldloc.s V_5 + IL_007c: ldloc.s V_8 + IL_007e: stelem.ref + IL_007f: ldloc.s V_5 + IL_0081: ldc.i4.1 + IL_0082: add + IL_0083: stloc.s V_5 + IL_0085: ldloca.s V_7 + IL_0087: call "bool System.ReadOnlySpan.Enumerator.MoveNext()" + IL_008c: brtrue.s IL_006e + IL_008e: ldloc.s V_6 + IL_0090: ldc.i4.0 + IL_0091: call "void CollectionExtensions.Report(object, bool)" + IL_0096: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs index 1963a7532e9f2..69af3dd321590 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/InlineArrayTests.cs @@ -4691,9 +4691,12 @@ static async Task FromResult(T r) "; var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); comp.VerifyEmitDiagnostics( - // (24,22): error CS4007: 'await' cannot be used in an expression containing the type 'System.ReadOnlySpan>' - // [Get01()][await FromResult(Get02(x))]; - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await FromResult(Get02(x))").WithArguments("System.ReadOnlySpan>").WithLocation(24, 22) + // (20,12): error CS4007: Instance of type 'System.ReadOnlySpan>' cannot be preserved across 'await' or 'yield' boundary. + // => MemoryMarshal.CreateReadOnlySpan( + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"MemoryMarshal.CreateReadOnlySpan( + ref Unsafe.As>, Buffer10>( + ref Unsafe.AsRef(in GetC(x).F)), + 10)").WithArguments("System.ReadOnlySpan>").WithLocation(20, 12) ); } @@ -4743,9 +4746,12 @@ static async Task FromResult(T r) "; var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); comp.VerifyEmitDiagnostics( - // (24,13): error CS4007: 'await' cannot be used in an expression containing the type 'System.ReadOnlySpan' - // [await FromResult(Get02(x))]; - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await FromResult(Get02(x))").WithArguments("System.ReadOnlySpan").WithLocation(24, 13) + // (20,12): error CS4007: Instance of type 'System.ReadOnlySpan' cannot be preserved across 'await' or 'yield' boundary. + // => MemoryMarshal.CreateReadOnlySpan( + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"MemoryMarshal.CreateReadOnlySpan( + ref Unsafe.As, int>( + ref Unsafe.AsRef(in GetC(x).F[Get01()])), + 10)").WithArguments("System.ReadOnlySpan").WithLocation(20, 12) ); } @@ -8958,9 +8964,6 @@ public ref struct Buffer10 "; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); comp.VerifyDiagnostics( - // (7,16): error CS0306: The type 'Buffer10' may not be used as a type argument - // return M3(x)[0]; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(x)[0]").WithArguments("Buffer10").WithLocation(7, 16), // (7,16): error CS0306: The type 'Span' may not be used as a type argument // return M3(x)[0]; Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(x)[0]").WithArguments("System.Span").WithLocation(7, 16), @@ -8970,24 +8973,15 @@ public ref struct Buffer10 // (7,19): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope // return M3(x)[0]; Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(7, 19), - // (13,17): error CS0306: The type 'Buffer10' may not be used as a type argument - // var y = M3(x)[0]; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(x)[0]").WithArguments("Buffer10").WithLocation(13, 17), // (13,17): error CS0306: The type 'Span' may not be used as a type argument // var y = M3(x)[0]; Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(x)[0]").WithArguments("System.Span").WithLocation(13, 17), // (14,16): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope // return y; Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(14, 16), - // (24,16): error CS0306: The type 'Buffer10' may not be used as a type argument - // return M3(xx)[0]; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(xx)[0]").WithArguments("Buffer10").WithLocation(24, 16), // (24,16): error CS0306: The type 'Span' may not be used as a type argument // return M3(xx)[0]; Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(xx)[0]").WithArguments("System.Span").WithLocation(24, 16), - // (29,18): error CS0306: The type 'Buffer10' may not be used as a type argument - // var yy = M3(xx)[0]; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(xx)[0]").WithArguments("Buffer10").WithLocation(29, 18), // (29,18): error CS0306: The type 'Span' may not be used as a type argument // var yy = M3(xx)[0]; Diagnostic(ErrorCode.ERR_BadTypeArgument, "M3(xx)[0]").WithArguments("System.Span").WithLocation(29, 18), @@ -14555,10 +14549,10 @@ static void M3(in C x) // Code size 18 (0x12) .maxstack 2 IL_0000: ldarg.0 - IL_0001: call ""ref TBuffer System.Runtime.CompilerServices.Unsafe.AsRef(scoped in TBuffer)"" + IL_0001: call ""ref TBuffer System.Runtime.CompilerServices.Unsafe.AsRef(scoped ref readonly TBuffer)"" IL_0006: call ""ref TElement System.Runtime.CompilerServices.Unsafe.As(ref TBuffer)"" IL_000b: ldarg.1 - IL_000c: call ""System.ReadOnlySpan System.Runtime.InteropServices.MemoryMarshal.CreateReadOnlySpan(scoped ref TElement, int)"" + IL_000c: call ""System.ReadOnlySpan System.Runtime.InteropServices.MemoryMarshal.CreateReadOnlySpan(scoped ref readonly TElement, int)"" IL_0011: ret } "); @@ -14652,7 +14646,7 @@ static void M3(in C x) // Code size 18 (0x12) .maxstack 2 IL_0000: ldarg.0 - IL_0001: call ""ref TBuffer System.Runtime.CompilerServices.Unsafe.AsRef(scoped in TBuffer)"" + IL_0001: call ""ref TBuffer System.Runtime.CompilerServices.Unsafe.AsRef(scoped ref readonly TBuffer)"" IL_0006: call ""ref TElement System.Runtime.CompilerServices.Unsafe.As(ref TBuffer)"" IL_000b: ldarg.1 IL_000c: call ""ref TElement System.Runtime.CompilerServices.Unsafe.Add(ref TElement, int)"" @@ -14743,7 +14737,7 @@ static void M3(in C x) // Code size 12 (0xc) .maxstack 1 IL_0000: ldarg.0 - IL_0001: call ""ref TBuffer System.Runtime.CompilerServices.Unsafe.AsRef(scoped in TBuffer)"" + IL_0001: call ""ref TBuffer System.Runtime.CompilerServices.Unsafe.AsRef(scoped ref readonly TBuffer)"" IL_0006: call ""ref TElement System.Runtime.CompilerServices.Unsafe.As(ref TBuffer)"" IL_000b: ret } @@ -16388,15 +16382,15 @@ static int M6(System.Span? x, Buffer10 y) // (9,27): error CS1503: Argument 1: cannot convert from 'Buffer10?' to 'System.ReadOnlySpan?' // static int M2() => M4(M3(), default); Diagnostic(ErrorCode.ERR_BadArgType, "M3()").WithArguments("1", "Buffer10?", "System.ReadOnlySpan?").WithLocation(9, 27), - // (13,45): error CS0306: The type 'ReadOnlySpan' may not be used as a type argument + // (13,45): error CS9244: The type 'ReadOnlySpan' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // static int M4(System.ReadOnlySpan? x, Buffer10 y) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "x").WithArguments("System.ReadOnlySpan").WithLocation(13, 45), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "x").WithArguments("System.Nullable", "T", "System.ReadOnlySpan").WithLocation(13, 45), // (18,27): error CS1503: Argument 1: cannot convert from 'Buffer10?' to 'System.Span?' // static int M5() => M6(M3(), default); Diagnostic(ErrorCode.ERR_BadArgType, "M3()").WithArguments("1", "Buffer10?", "System.Span?").WithLocation(18, 27), - // (20,37): error CS0306: The type 'Span' may not be used as a type argument + // (20,37): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // static int M6(System.Span? x, Buffer10 y) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "x").WithArguments("System.Span").WithLocation(20, 37) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "x").WithArguments("System.Nullable", "T", "System.Span").WithLocation(20, 37) ); } @@ -16475,15 +16469,15 @@ static int M6(System.Span? x, Buffer10 y) // (9,27): error CS1503: Argument 1: cannot convert from 'Buffer10' to 'System.ReadOnlySpan?' // static int M2() => M4(M3(), default); Diagnostic(ErrorCode.ERR_BadArgType, "M3()").WithArguments("1", "Buffer10", "System.ReadOnlySpan?").WithLocation(9, 27), - // (13,45): error CS0306: The type 'ReadOnlySpan' may not be used as a type argument + // (13,45): error CS9244: The type 'ReadOnlySpan' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // static int M4(System.ReadOnlySpan? x, Buffer10 y) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "x").WithArguments("System.ReadOnlySpan").WithLocation(13, 45), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "x").WithArguments("System.Nullable", "T", "System.ReadOnlySpan").WithLocation(13, 45), // (18,27): error CS1503: Argument 1: cannot convert from 'Buffer10' to 'System.Span?' // static int M5() => M6(M3(), default); Diagnostic(ErrorCode.ERR_BadArgType, "M3()").WithArguments("1", "Buffer10", "System.Span?").WithLocation(18, 27), - // (20,37): error CS0306: The type 'Span' may not be used as a type argument + // (20,37): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // static int M6(System.Span? x, Buffer10 y) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "x").WithArguments("System.Span").WithLocation(20, 37) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "x").WithArguments("System.Nullable", "T", "System.Span").WithLocation(20, 37) ); } @@ -18487,7 +18481,7 @@ .locals init (Buffer4& V_0, IL_0019: dup IL_001a: ldind.i4 IL_001b: call ""void System.Console.Write(int)"" - IL_0020: call ""ref int System.Runtime.CompilerServices.Unsafe.AsRef(scoped in int)"" + IL_0020: call ""ref int System.Runtime.CompilerServices.Unsafe.AsRef(scoped ref readonly int)"" IL_0025: dup IL_0026: ldind.i4 IL_0027: ldc.i4.m1 @@ -18714,7 +18708,7 @@ .locals init (Buffer4& V_0, IL_0019: dup IL_001a: ldind.i4 IL_001b: call ""void System.Console.Write(int)"" - IL_0020: call ""ref int System.Runtime.CompilerServices.Unsafe.AsRef(scoped in int)"" + IL_0020: call ""ref int System.Runtime.CompilerServices.Unsafe.AsRef(scoped ref readonly int)"" IL_0025: dup IL_0026: ldind.i4 IL_0027: ldc.i4.m1 @@ -19161,18 +19155,12 @@ public ref struct Buffer10 "; var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); comp.VerifyDiagnostics( - // (7,27): error CS0306: The type 'Buffer10' may not be used as a type argument - // foreach (var y in GetBuffer(x)) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "GetBuffer(x)").WithArguments("Buffer10").WithLocation(7, 27), // (7,27): error CS0306: The type 'Span' may not be used as a type argument // foreach (var y in GetBuffer(x)) Diagnostic(ErrorCode.ERR_BadTypeArgument, "GetBuffer(x)").WithArguments("System.Span").WithLocation(7, 27), // (9,20): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope // return y; Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(9, 20), - // (17,28): error CS0306: The type 'Buffer10' may not be used as a type argument - // foreach (var yy in GetBuffer(xx)) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "GetBuffer(xx)").WithArguments("Buffer10").WithLocation(17, 28), // (17,28): error CS0306: The type 'Span' may not be used as a type argument // foreach (var yy in GetBuffer(xx)) Diagnostic(ErrorCode.ERR_BadTypeArgument, "GetBuffer(xx)").WithArguments("System.Span").WithLocation(17, 28), @@ -20154,30 +20142,45 @@ .locals init (int V_0, CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); } - [Fact] + [ConditionalFact(typeof(CoreClrOnly))] public void Foreach_InAsync_03() { var src = @" class Program { - static async void Test() + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() { + s_buffer[1] = 3; + foreach (ref int y in GetBuffer()) { + y *= y; + System.Console.Write(y); } await System.Threading.Tasks.Task.Yield(); + + System.Console.Write(s_buffer[1]); } - static ref Buffer4 GetBuffer() => throw null; + static ref Buffer4 GetBuffer() => ref s_buffer; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); - comp.VerifyDiagnostics( - // (6,26): error CS8177: Async methods cannot have by-reference locals +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // foreach (ref int y in GetBuffer()) - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y").WithLocation(6, 26) - ); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26)); + + var expectedOutput = "09009"; + + CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); } [Fact] @@ -20598,30 +20601,48 @@ .locals init (int V_0, CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); } - [Fact] + [ConditionalFact(typeof(CoreClrOnly))] public void Foreach_InAsync_07() { var src = @" class Program { - static async void Test() + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() { + s_buffer[1] = 3; + + int i = 0; foreach (ref readonly int y in GetBuffer()) { + System.Console.Write(y); + s_buffer[i++]++; + System.Console.Write(y); + System.Console.Write(' '); } await System.Threading.Tasks.Task.Yield(); + + System.Console.Write(s_buffer[1]); } - static ref readonly Buffer4 GetBuffer() => throw null; + static ref readonly Buffer4 GetBuffer() => ref s_buffer; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); - comp.VerifyDiagnostics( - // (6,35): error CS8177: Async methods cannot have by-reference locals +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (11,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // foreach (ref readonly int y in GetBuffer()) - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y").WithLocation(6, 35) - ); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 35)); + + var expectedOutput = "01 34 01 01 4"; + + CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput).VerifyDiagnostics(); } [Fact] @@ -20798,132 +20819,209 @@ .locals init (int V_0, } [ConditionalFact(typeof(CoreClrOnly))] - public void Foreach_InIterator_01() + public void Foreach_InAsync_10() { var src = @" class Program { - static private Buffer4 F = default; - private static int index = 0; + static Buffer4 s_buffer; - static void Main() + static async System.Threading.Tasks.Task Main() { - foreach (var a in Test()) - {} + s_buffer[1] = 3; + + ref Buffer4 buffer = ref GetBuffer(); + foreach (ref int y in buffer) + { + y *= y; + System.Console.Write(y); + } + + await System.Threading.Tasks.Task.Yield(); + + System.Console.Write(s_buffer[1]); } - static System.Collections.Generic.IEnumerable Test() + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref Buffer4 buffer = ref GetBuffer(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "buffer").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26), + // (11,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in buffer) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 26)); + + var expectedOutput = "09009"; + + CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void Foreach_InAsync_11() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() { - yield return -1; + s_buffer[1] = 3; - foreach (var y in GetBuffer()) + foreach (ref int y in GetBuffer()) { - Increment(); - System.Console.Write(' '); + await System.Threading.Tasks.Task.Yield(); + y *= y; System.Console.Write(y); } - yield return -2; - } + await System.Threading.Tasks.Task.Yield(); - static ref Buffer4 GetBuffer() - { - System.Console.Write(-1); - return ref F; + System.Console.Write(s_buffer[1]); } - static void Increment() + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26)); + + var expectedDiagnostics = new[] + { + // (13,13): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // y *= y; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(13, 13), + // (13,18): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // y *= y; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(13, 18), + // (14,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(14, 34) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InAsync_12() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() { - index++; + s_buffer[1] = 3; - if (index < 4) + foreach (ref int y in GetBuffer()) { - F[index] = index; + y *= y; + System.Console.Write(y); + await System.Threading.Tasks.Task.Yield(); } + + await System.Threading.Tasks.Task.Yield(); + + System.Console.Write(s_buffer[1]); } + + static ref Buffer4 GetBuffer() => ref s_buffer; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); - var verifier = CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); +" + Buffer4Definition; - verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext", -@" + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26)); + + var expectedDiagnostics = new[] + { + // (10,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, @"foreach (ref int y in GetBuffer()) + { + y *= y; + System.Console.Write(y); + await System.Threading.Tasks.Task.Yield(); + }").WithArguments("Program.GetBuffer()").WithLocation(10, 9) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InAsync_13() + { + var src = @" +class Program { - // Code size 126 (0x7e) - .maxstack 2 - .locals init (int V_0, - Buffer4& V_1, - int V_2) - IL_0000: ldarg.0 - IL_0001: ldfld ""int Program.d__3.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001b, - IL_0032, - IL_0075) - IL_0019: ldc.i4.0 - IL_001a: ret - IL_001b: ldarg.0 - IL_001c: ldc.i4.m1 - IL_001d: stfld ""int Program.d__3.<>1__state"" - IL_0022: ldarg.0 - IL_0023: ldc.i4.m1 - IL_0024: stfld ""int Program.d__3.<>2__current"" - IL_0029: ldarg.0 - IL_002a: ldc.i4.1 - IL_002b: stfld ""int Program.d__3.<>1__state"" - IL_0030: ldc.i4.1 - IL_0031: ret - IL_0032: ldarg.0 - IL_0033: ldc.i4.m1 - IL_0034: stfld ""int Program.d__3.<>1__state"" - IL_0039: call ""ref Buffer4 Program.GetBuffer()"" - IL_003e: stloc.1 - IL_003f: ldc.i4.0 - IL_0040: stloc.2 - IL_0041: br.s IL_0060 - IL_0043: ldloc.1 - IL_0044: ldloc.2 - IL_0045: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)"" - IL_004a: ldind.i4 - IL_004b: call ""void Program.Increment()"" - IL_0050: ldc.i4.s 32 - IL_0052: call ""void System.Console.Write(char)"" - IL_0057: call ""void System.Console.Write(int)"" - IL_005c: ldloc.2 - IL_005d: ldc.i4.1 - IL_005e: add - IL_005f: stloc.2 - IL_0060: ldloc.2 - IL_0061: ldc.i4.4 - IL_0062: blt.s IL_0043 - IL_0064: ldarg.0 - IL_0065: ldc.i4.s -2 - IL_0067: stfld ""int Program.d__3.<>2__current"" - IL_006c: ldarg.0 - IL_006d: ldc.i4.2 - IL_006e: stfld ""int Program.d__3.<>1__state"" - IL_0073: ldc.i4.1 - IL_0074: ret - IL_0075: ldarg.0 - IL_0076: ldc.i4.m1 - IL_0077: stfld ""int Program.d__3.<>1__state"" - IL_007c: ldc.i4.0 - IL_007d: ret + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() + { + s_buffer[1] = 3; + + ref Buffer4 buffer = ref GetBuffer(); + foreach (ref int y in buffer) + { + y *= y; + System.Console.Write(y); + await System.Threading.Tasks.Task.Yield(); + } + + await System.Threading.Tasks.Task.Yield(); + + System.Console.Write(s_buffer[1]); + } + + static ref Buffer4 GetBuffer() => ref s_buffer; } -"); - comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (10,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref Buffer4 buffer = ref GetBuffer(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "buffer").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 26), + // (11,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in buffer) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 26)); + + var expectedDiagnostics = new[] + { + // (11,31): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (ref int y in buffer) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "buffer").WithLocation(11, 31) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); } - [ConditionalFact(typeof(CoreClrOnly))] - public void Foreach_InIterator_02() + [Fact] + public void Foreach_InAsync_14() { var src = @" +using System.Threading.Tasks; + class C { - public Buffer4 F = default; + public readonly Buffer4 F = default; } class Program @@ -20933,19 +21031,20 @@ class Program static void Main() { - foreach (var a in Test(c)) - {} + Test(c).Wait(); } - static System.Collections.Generic.IEnumerable Test(C x) + static async Task Test(C x) { - foreach (var y in x.F) + ref readonly Buffer4 f = ref x.F; + foreach (var y in f) { Increment(); System.Console.Write(' '); System.Console.Write(y); - yield return -1; + await Task.Yield(); + await Task.Delay(2); } } @@ -20955,146 +21054,266 @@ static void Increment() if (index < 4) { - c.F[index] = index; + System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index; } } } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); - var verifier = CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); +" + Buffer4Definition; - verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext", -@" + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (21,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly Buffer4 f = ref x.F; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "f").WithArguments("ref and unsafe in async and iterator methods").WithLocation(21, 35)); + + var expectedDiagnostics = new[] + { + // (22,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var y in f) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(22, 27) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InAsync_15() + { + var src = @" +class Program { - // Code size 151 (0x97) - .maxstack 3 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int Program.d__3.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0070 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld ""int Program.d__3.<>1__state"" - IL_0017: ldarg.0 - IL_0018: ldarg.0 - IL_0019: ldfld ""C Program.d__3.x"" - IL_001e: stfld ""C Program.d__3.<>7__wrap2"" - IL_0023: ldarg.0 - IL_0024: ldfld ""C Program.d__3.<>7__wrap2"" - IL_0029: ldfld ""Buffer4 C.F"" - IL_002e: pop - IL_002f: ldarg.0 - IL_0030: ldc.i4.0 - IL_0031: stfld ""int Program.d__3.<>7__wrap1"" - IL_0036: br.s IL_0085 - IL_0038: ldarg.0 - IL_0039: ldfld ""C Program.d__3.<>7__wrap2"" - IL_003e: ldflda ""Buffer4 C.F"" - IL_0043: ldarg.0 - IL_0044: ldfld ""int Program.d__3.<>7__wrap1"" - IL_0049: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)"" - IL_004e: ldind.i4 - IL_004f: call ""void Program.Increment()"" - IL_0054: ldc.i4.s 32 - IL_0056: call ""void System.Console.Write(char)"" - IL_005b: call ""void System.Console.Write(int)"" - IL_0060: ldarg.0 - IL_0061: ldc.i4.m1 - IL_0062: stfld ""int Program.d__3.<>2__current"" - IL_0067: ldarg.0 - IL_0068: ldc.i4.1 - IL_0069: stfld ""int Program.d__3.<>1__state"" - IL_006e: ldc.i4.1 - IL_006f: ret - IL_0070: ldarg.0 - IL_0071: ldc.i4.m1 - IL_0072: stfld ""int Program.d__3.<>1__state"" - IL_0077: ldarg.0 - IL_0078: ldarg.0 - IL_0079: ldfld ""int Program.d__3.<>7__wrap1"" - IL_007e: ldc.i4.1 - IL_007f: add - IL_0080: stfld ""int Program.d__3.<>7__wrap1"" - IL_0085: ldarg.0 - IL_0086: ldfld ""int Program.d__3.<>7__wrap1"" - IL_008b: ldc.i4.4 - IL_008c: blt.s IL_0038 - IL_008e: ldarg.0 - IL_008f: ldnull - IL_0090: stfld ""C Program.d__3.<>7__wrap2"" - IL_0095: ldc.i4.0 - IL_0096: ret + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() + { + foreach (ref readonly int y in GetBuffer()) + { + System.Console.Write(y); + await System.Threading.Tasks.Task.Yield(); + } + + await System.Threading.Tasks.Task.Yield(); + } + + static ref readonly Buffer4 GetBuffer() => ref s_buffer; } -"); - comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (8,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 35)); + + var expectedDiagnostics = new[] + { + // (8,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, @"foreach (ref readonly int y in GetBuffer()) + { + System.Console.Write(y); + await System.Threading.Tasks.Task.Yield(); + }").WithArguments("Program.GetBuffer()").WithLocation(8, 9) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); } [Fact] - public void Foreach_InIterator_03() + public void Foreach_InAsync_16() { var src = @" class Program { - static System.Collections.Generic.IEnumerable Test() + static Buffer4 s_buffer; + + static async System.Threading.Tasks.Task Main() { - foreach (ref int y in GetBuffer()) + foreach (ref readonly int y in GetBuffer()) { + await System.Threading.Tasks.Task.Yield(); + System.Console.Write(y); } - yield return -1; + await System.Threading.Tasks.Task.Yield(); } - static ref Buffer4 GetBuffer() => throw null; + static ref readonly Buffer4 GetBuffer() => ref s_buffer; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); - comp.VerifyDiagnostics( - // (6,26): error CS8176: Iterators cannot have by-reference locals - // foreach (ref int y in GetBuffer()) - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "y").WithLocation(6, 26) - ); +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (8,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 35)); + + var expectedDiagnostics = new[] + { + // (11,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(11, 34) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InAsync_17() + { + var src = @" +using System.Threading.Tasks; + +class C +{ + public readonly Buffer4 F = default; +} + +class Program +{ + private static C c = new C(); + private static int index = 0; + + static void Main() + { + Test(c).Wait(); + } + + static async Task Test(C x) + { + foreach (ref readonly int y in x.F) + { + Increment(); + System.Console.Write(' '); + System.Console.Write(y); + + await Task.Yield(); + await Task.Delay(2); + } + } + + static void Increment() + { + index++; + + if (index < 4) + { + System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index; + } + } +} +" + Buffer4Definition; + var expectedOutput = " 0 1 2 3"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyDiagnostics(); + comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyDiagnostics(); } [Fact] - public void Foreach_InIterator_04() + public void Foreach_InAsync_18() { var src = @" +using System.Threading.Tasks; + +class C +{ + public readonly Buffer4 F = default; +} + class Program { - static System.Collections.Generic.IEnumerable Test() + static async Task Test(C x) { - foreach (int y in GetBuffer()) + foreach (ref readonly int y in x.F) { - yield return -1; + await Task.Yield(); + System.Console.Write(y); } } +} +" + Buffer4Definition; - static ref Buffer4 GetBuffer() => throw null; + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (13,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in x.F) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 35)); + + var expectedDiagnostics = new[] + { + // (16,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(16, 34) + }; + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InAsync_19() + { + var src = @" +using System.Threading.Tasks; + +class C +{ + public readonly Buffer4 F = default; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); - comp.VerifyEmitDiagnostics( - // (6,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. - // foreach (int y in GetBuffer()) - Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, - @"foreach (int y in GetBuffer()) +class Program +{ + static async Task Test(C x) + { + ref readonly Buffer4 f = ref x.F; + + foreach (var i in f) System.Console.Write(i); + + foreach (var y in f) { - yield return -1; - }").WithArguments("Program.GetBuffer()").WithLocation(6, 9) - ); + System.Console.Write(y); + await Task.Yield(); + } + + foreach (var j in f) System.Console.Write(j); + + foreach (var z in f) + { + System.Console.Write(z); + await Task.Yield(); + } + } +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (13,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly Buffer4 f = ref x.F; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "f").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 35)); + + var expectedDiagnostics = new[] + { + // (17,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var y in f) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(17, 27), + // (23,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var j in f) System.Console.Write(j); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(23, 27), + // (25,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var z in f) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(25, 27) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); } [ConditionalFact(typeof(CoreClrOnly))] - public void Foreach_InIterator_05() + public void Foreach_InIterator_01() { var src = @" class Program @@ -21122,7 +21341,7 @@ static System.Collections.Generic.IEnumerable Test() yield return -2; } - static ref readonly Buffer4 GetBuffer() + static ref Buffer4 GetBuffer() { System.Console.Write(-1); return ref F; @@ -21174,14 +21393,14 @@ .locals init (int V_0, IL_0032: ldarg.0 IL_0033: ldc.i4.m1 IL_0034: stfld ""int Program.d__3.<>1__state"" - IL_0039: call ""ref readonly Buffer4 Program.GetBuffer()"" + IL_0039: call ""ref Buffer4 Program.GetBuffer()"" IL_003e: stloc.1 IL_003f: ldc.i4.0 IL_0040: stloc.2 IL_0041: br.s IL_0060 IL_0043: ldloc.1 IL_0044: ldloc.2 - IL_0045: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)"" + IL_0045: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)"" IL_004a: ldind.i4 IL_004b: call ""void Program.Increment()"" IL_0050: ldc.i4.s 32 @@ -21208,13 +21427,1009 @@ .locals init (int V_0, IL_007c: ldc.i4.0 IL_007d: ret } -"); - comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); +"); + comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_02() + { + var src = @" +class C +{ + public Buffer4 F = default; +} + +class Program +{ + private static C c = new C(); + private static int index = 0; + + static void Main() + { + foreach (var a in Test(c)) + {} + } + + static System.Collections.Generic.IEnumerable Test(C x) + { + foreach (var y in x.F) + { + Increment(); + System.Console.Write(' '); + System.Console.Write(y); + + yield return -1; + } + } + + static void Increment() + { + index++; + + if (index < 4) + { + c.F[index] = index; + } + } +} +"; + var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + + verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext", +@" +{ + // Code size 151 (0x97) + .maxstack 3 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld ""int Program.d__3.<>1__state"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0070 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld ""int Program.d__3.<>1__state"" + IL_0017: ldarg.0 + IL_0018: ldarg.0 + IL_0019: ldfld ""C Program.d__3.x"" + IL_001e: stfld ""C Program.d__3.<>7__wrap2"" + IL_0023: ldarg.0 + IL_0024: ldfld ""C Program.d__3.<>7__wrap2"" + IL_0029: ldfld ""Buffer4 C.F"" + IL_002e: pop + IL_002f: ldarg.0 + IL_0030: ldc.i4.0 + IL_0031: stfld ""int Program.d__3.<>7__wrap1"" + IL_0036: br.s IL_0085 + IL_0038: ldarg.0 + IL_0039: ldfld ""C Program.d__3.<>7__wrap2"" + IL_003e: ldflda ""Buffer4 C.F"" + IL_0043: ldarg.0 + IL_0044: ldfld ""int Program.d__3.<>7__wrap1"" + IL_0049: call ""ref int .InlineArrayElementRef, int>(ref Buffer4, int)"" + IL_004e: ldind.i4 + IL_004f: call ""void Program.Increment()"" + IL_0054: ldc.i4.s 32 + IL_0056: call ""void System.Console.Write(char)"" + IL_005b: call ""void System.Console.Write(int)"" + IL_0060: ldarg.0 + IL_0061: ldc.i4.m1 + IL_0062: stfld ""int Program.d__3.<>2__current"" + IL_0067: ldarg.0 + IL_0068: ldc.i4.1 + IL_0069: stfld ""int Program.d__3.<>1__state"" + IL_006e: ldc.i4.1 + IL_006f: ret + IL_0070: ldarg.0 + IL_0071: ldc.i4.m1 + IL_0072: stfld ""int Program.d__3.<>1__state"" + IL_0077: ldarg.0 + IL_0078: ldarg.0 + IL_0079: ldfld ""int Program.d__3.<>7__wrap1"" + IL_007e: ldc.i4.1 + IL_007f: add + IL_0080: stfld ""int Program.d__3.<>7__wrap1"" + IL_0085: ldarg.0 + IL_0086: ldfld ""int Program.d__3.<>7__wrap1"" + IL_008b: ldc.i4.4 + IL_008c: blt.s IL_0038 + IL_008e: ldarg.0 + IL_008f: ldnull + IL_0090: stfld ""C Program.d__3.<>7__wrap2"" + IL_0095: ldc.i4.0 + IL_0096: ret +} +"); + comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_03() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static void Main() + { + s_buffer[2] = 3; + + foreach (int x in Test()) + { + System.Console.Write(x); + } + } + + static System.Collections.Generic.IEnumerable Test() + { + foreach (ref int y in GetBuffer()) + { + y *= y; + System.Console.Write(y); + } + + yield return -1; + + System.Console.Write(s_buffer[2]); + } + + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (18,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(18, 26)); + + var expectedOutput = "0090-19"; + + CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void Foreach_InIterator_04() + { + var src = @" +class Program +{ + static System.Collections.Generic.IEnumerable Test() + { + foreach (int y in GetBuffer()) + { + yield return -1; + } + } + + static ref Buffer4 GetBuffer() => throw null; +} +"; + var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); + + comp.VerifyEmitDiagnostics( + // (6,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. + // foreach (int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, + @"foreach (int y in GetBuffer()) + { + yield return -1; + }").WithArguments("Program.GetBuffer()").WithLocation(6, 9) + ); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_05() + { + var src = @" +class Program +{ + static private Buffer4 F = default; + private static int index = 0; + + static void Main() + { + foreach (var a in Test()) + {} + } + + static System.Collections.Generic.IEnumerable Test() + { + yield return -1; + + foreach (var y in GetBuffer()) + { + Increment(); + System.Console.Write(' '); + System.Console.Write(y); + } + + yield return -2; + } + + static ref readonly Buffer4 GetBuffer() + { + System.Console.Write(-1); + return ref F; + } + + static void Increment() + { + index++; + + if (index < 4) + { + F[index] = index; + } + } +} +"; + var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + + verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext", +@" +{ + // Code size 126 (0x7e) + .maxstack 2 + .locals init (int V_0, + Buffer4& V_1, + int V_2) + IL_0000: ldarg.0 + IL_0001: ldfld ""int Program.d__3.<>1__state"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: switch ( + IL_001b, + IL_0032, + IL_0075) + IL_0019: ldc.i4.0 + IL_001a: ret + IL_001b: ldarg.0 + IL_001c: ldc.i4.m1 + IL_001d: stfld ""int Program.d__3.<>1__state"" + IL_0022: ldarg.0 + IL_0023: ldc.i4.m1 + IL_0024: stfld ""int Program.d__3.<>2__current"" + IL_0029: ldarg.0 + IL_002a: ldc.i4.1 + IL_002b: stfld ""int Program.d__3.<>1__state"" + IL_0030: ldc.i4.1 + IL_0031: ret + IL_0032: ldarg.0 + IL_0033: ldc.i4.m1 + IL_0034: stfld ""int Program.d__3.<>1__state"" + IL_0039: call ""ref readonly Buffer4 Program.GetBuffer()"" + IL_003e: stloc.1 + IL_003f: ldc.i4.0 + IL_0040: stloc.2 + IL_0041: br.s IL_0060 + IL_0043: ldloc.1 + IL_0044: ldloc.2 + IL_0045: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)"" + IL_004a: ldind.i4 + IL_004b: call ""void Program.Increment()"" + IL_0050: ldc.i4.s 32 + IL_0052: call ""void System.Console.Write(char)"" + IL_0057: call ""void System.Console.Write(int)"" + IL_005c: ldloc.2 + IL_005d: ldc.i4.1 + IL_005e: add + IL_005f: stloc.2 + IL_0060: ldloc.2 + IL_0061: ldc.i4.4 + IL_0062: blt.s IL_0043 + IL_0064: ldarg.0 + IL_0065: ldc.i4.s -2 + IL_0067: stfld ""int Program.d__3.<>2__current"" + IL_006c: ldarg.0 + IL_006d: ldc.i4.2 + IL_006e: stfld ""int Program.d__3.<>1__state"" + IL_0073: ldc.i4.1 + IL_0074: ret + IL_0075: ldarg.0 + IL_0076: ldc.i4.m1 + IL_0077: stfld ""int Program.d__3.<>1__state"" + IL_007c: ldc.i4.0 + IL_007d: ret +} +"); + comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "-1 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_06() + { + var src = @" +class C +{ + public readonly Buffer4 F = default; +} + +class Program +{ + private static C c = new C(); + private static int index = 0; + + static void Main() + { + foreach (var a in Test(c)) + {} + } + + static System.Collections.Generic.IEnumerable Test(C x) + { + foreach (var y in x.F) + { + Increment(); + System.Console.Write(' '); + System.Console.Write(y); + + yield return -1; + } + } + + static void Increment() + { + index++; + + if (index < 4) + { + System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index; + } + } +} +"; + var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + + verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext", +@" +{ + // Code size 151 (0x97) + .maxstack 3 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld ""int Program.d__3.<>1__state"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0070 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld ""int Program.d__3.<>1__state"" + IL_0017: ldarg.0 + IL_0018: ldarg.0 + IL_0019: ldfld ""C Program.d__3.x"" + IL_001e: stfld ""C Program.d__3.<>7__wrap2"" + IL_0023: ldarg.0 + IL_0024: ldfld ""C Program.d__3.<>7__wrap2"" + IL_0029: ldfld ""Buffer4 C.F"" + IL_002e: pop + IL_002f: ldarg.0 + IL_0030: ldc.i4.0 + IL_0031: stfld ""int Program.d__3.<>7__wrap1"" + IL_0036: br.s IL_0085 + IL_0038: ldarg.0 + IL_0039: ldfld ""C Program.d__3.<>7__wrap2"" + IL_003e: ldflda ""Buffer4 C.F"" + IL_0043: ldarg.0 + IL_0044: ldfld ""int Program.d__3.<>7__wrap1"" + IL_0049: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)"" + IL_004e: ldind.i4 + IL_004f: call ""void Program.Increment()"" + IL_0054: ldc.i4.s 32 + IL_0056: call ""void System.Console.Write(char)"" + IL_005b: call ""void System.Console.Write(int)"" + IL_0060: ldarg.0 + IL_0061: ldc.i4.m1 + IL_0062: stfld ""int Program.d__3.<>2__current"" + IL_0067: ldarg.0 + IL_0068: ldc.i4.1 + IL_0069: stfld ""int Program.d__3.<>1__state"" + IL_006e: ldc.i4.1 + IL_006f: ret + IL_0070: ldarg.0 + IL_0071: ldc.i4.m1 + IL_0072: stfld ""int Program.d__3.<>1__state"" + IL_0077: ldarg.0 + IL_0078: ldarg.0 + IL_0079: ldfld ""int Program.d__3.<>7__wrap1"" + IL_007e: ldc.i4.1 + IL_007f: add + IL_0080: stfld ""int Program.d__3.<>7__wrap1"" + IL_0085: ldarg.0 + IL_0086: ldfld ""int Program.d__3.<>7__wrap1"" + IL_008b: ldc.i4.4 + IL_008c: blt.s IL_0038 + IL_008e: ldarg.0 + IL_008f: ldnull + IL_0090: stfld ""C Program.d__3.<>7__wrap2"" + IL_0095: ldc.i4.0 + IL_0096: ret +} +"); + comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_07() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static void Main() + { + s_buffer[2] = 3; + + foreach (int x in Test()) + { + System.Console.Write(x); + } + } + + static System.Collections.Generic.IEnumerable Test() + { + int i = 0; + foreach (ref readonly int y in GetBuffer()) + { + System.Console.Write(y); + s_buffer[i++]++; + System.Console.Write(y); + System.Console.Write(' '); + } + + yield return -1; + + System.Console.Write(s_buffer[2]); + } + + static ref readonly Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (19,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(19, 35)); + + var expectedOutput = "01 01 34 01 -14"; + + CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void Foreach_InIterator_08() + { + var src = @" +class Program +{ + static System.Collections.Generic.IEnumerable Test() + { + foreach (int y in GetBuffer()) + { + yield return -1; + } + } + + static ref readonly Buffer4 GetBuffer() => throw null; +} +"; + var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); + + comp.VerifyEmitDiagnostics( + // (6,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. + // foreach (int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, + @"foreach (int y in GetBuffer()) + { + yield return -1; + }").WithArguments("Program.GetBuffer()").WithLocation(6, 9) + ); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_09() + { + var src = @" +class Program +{ + static void Main() + { + foreach (var a in Test()) + {} + } + + static System.Collections.Generic.IEnumerable Test() + { + foreach (var y in GetBuffer()) + { + System.Console.Write(' '); + System.Console.Write(y); + yield return -1; + } + } + + static Buffer4 GetBuffer() + { + Buffer4 x = default; + x[0] = 111; + x[1] = 112; + x[2] = 113; + x[3] = 114; + + System.Console.Write(-1); + return x; + } +} +"; + var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: "-1 111 112 113 114").VerifyDiagnostics(); + + verifier.VerifyIL("Program.d__1.System.Collections.IEnumerator.MoveNext", +@" +{ + // Code size 121 (0x79) + .maxstack 3 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld ""int Program.d__1.<>1__state"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0010 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq.s IL_0059 + IL_000e: ldc.i4.0 + IL_000f: ret + IL_0010: ldarg.0 + IL_0011: ldc.i4.m1 + IL_0012: stfld ""int Program.d__1.<>1__state"" + IL_0017: ldarg.0 + IL_0018: call ""Buffer4 Program.GetBuffer()"" + IL_001d: stfld ""Buffer4 Program.d__1.<>7__wrap1"" + IL_0022: ldarg.0 + IL_0023: ldc.i4.0 + IL_0024: stfld ""int Program.d__1.<>7__wrap2"" + IL_0029: br.s IL_006e + IL_002b: ldarg.0 + IL_002c: ldflda ""Buffer4 Program.d__1.<>7__wrap1"" + IL_0031: ldarg.0 + IL_0032: ldfld ""int Program.d__1.<>7__wrap2"" + IL_0037: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)"" + IL_003c: ldind.i4 + IL_003d: ldc.i4.s 32 + IL_003f: call ""void System.Console.Write(char)"" + IL_0044: call ""void System.Console.Write(int)"" + IL_0049: ldarg.0 + IL_004a: ldc.i4.m1 + IL_004b: stfld ""int Program.d__1.<>2__current"" + IL_0050: ldarg.0 + IL_0051: ldc.i4.1 + IL_0052: stfld ""int Program.d__1.<>1__state"" + IL_0057: ldc.i4.1 + IL_0058: ret + IL_0059: ldarg.0 + IL_005a: ldc.i4.m1 + IL_005b: stfld ""int Program.d__1.<>1__state"" + IL_0060: ldarg.0 + IL_0061: ldarg.0 + IL_0062: ldfld ""int Program.d__1.<>7__wrap2"" + IL_0067: ldc.i4.1 + IL_0068: add + IL_0069: stfld ""int Program.d__1.<>7__wrap2"" + IL_006e: ldarg.0 + IL_006f: ldfld ""int Program.d__1.<>7__wrap2"" + IL_0074: ldc.i4.4 + IL_0075: blt.s IL_002b + IL_0077: ldc.i4.0 + IL_0078: ret +} +"); + comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "-1 111 112 113 114").VerifyDiagnostics(); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void Foreach_InIterator_10() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static void Main() + { + s_buffer[2] = 3; + + foreach (int x in Test()) + { + System.Console.Write(x); + } + } + + static System.Collections.Generic.IEnumerable Test() + { + ref Buffer4 buffer = ref GetBuffer(); + foreach (ref int y in buffer) + { + y *= y; + System.Console.Write(y); + } + + yield return -1; + + System.Console.Write(s_buffer[2]); + } + + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (18,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref Buffer4 buffer = ref GetBuffer(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "buffer").WithArguments("ref and unsafe in async and iterator methods").WithLocation(18, 26), + // (19,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in buffer) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(19, 26)); + + var expectedOutput = "0090-19"; + + CompileAndVerify(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void Foreach_InIterator_11() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static void Main() + { + s_buffer[2] = 3; + + foreach (int x in Test()) + { + System.Console.Write(x); + } + } + + static System.Collections.Generic.IEnumerable Test() + { + foreach (ref int y in GetBuffer()) + { + yield return 1; + y *= y; + System.Console.Write(y); + } + + yield return -1; + + System.Console.Write(s_buffer[2]); + } + + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (18,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(18, 26)); + + var expectedDiagnostics = new[] + { + // (21,13): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // y *= y; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(21, 13), + // (21,18): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // y *= y; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(21, 18), + // (22,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(22, 34) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InIterator_12() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static void Main() + { + s_buffer[2] = 3; + + foreach (int x in Test()) + { + System.Console.Write(x); + } + } + + static System.Collections.Generic.IEnumerable Test() + { + foreach (ref int y in GetBuffer()) + { + y *= y; + System.Console.Write(y); + yield return 1; + } + + yield return -1; + + System.Console.Write(s_buffer[2]); + } + + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (18,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(18, 26)); + + var expectedDiagnostics = new[] + { + // (18,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. + // foreach (ref int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, @"foreach (ref int y in GetBuffer()) + { + y *= y; + System.Console.Write(y); + yield return 1; + }").WithArguments("Program.GetBuffer()").WithLocation(18, 9) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InIterator_13() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static void Main() + { + s_buffer[2] = 3; + + foreach (int x in Test()) + { + System.Console.Write(x); + } + } + + static System.Collections.Generic.IEnumerable Test() + { + ref Buffer4 buffer = ref GetBuffer(); + foreach (ref int y in buffer) + { + y *= y; + System.Console.Write(y); + yield return 1; + } + + yield return -1; + + System.Console.Write(s_buffer[2]); + } + + static ref Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (18,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref Buffer4 buffer = ref GetBuffer(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "buffer").WithArguments("ref and unsafe in async and iterator methods").WithLocation(18, 26), + // (19,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref int y in buffer) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(19, 26)); + + var expectedDiagnostics = new[] + { + // (19,31): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (ref int y in buffer) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "buffer").WithLocation(19, 31) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InIterator_14() + { + var src = @" +class C +{ + public readonly Buffer4 F = default; +} + +class Program +{ + private static C c = new C(); + private static int index = 0; + + static void Main() + { + foreach (var a in Test(c)) + {} + } + + static System.Collections.Generic.IEnumerable Test(C x) + { + ref readonly Buffer4 f = ref x.F; + foreach (var y in f) + { + Increment(); + System.Console.Write(' '); + System.Console.Write(y); + + yield return -1; + } + } + + static void Increment() + { + index++; + + if (index < 4) + { + System.Runtime.CompilerServices.Unsafe.AsRef(in c.F)[index] = index; + } + } +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (20,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly Buffer4 f = ref x.F; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "f").WithArguments("ref and unsafe in async and iterator methods").WithLocation(20, 35)); + + var expectedDiagnostics = new[] + { + // (21,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var y in f) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(21, 27) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InIterator_15() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static System.Collections.Generic.IEnumerable Test() + { + foreach (ref readonly int y in GetBuffer()) + { + System.Console.Write(y); + yield return 1; + } + + yield return -1; + } + + static ref readonly Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (8,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 35)); + + var expectedDiagnostics = new[] + { + // (8,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, @"foreach (ref readonly int y in GetBuffer()) + { + System.Console.Write(y); + yield return 1; + }").WithArguments("Program.GetBuffer()").WithLocation(8, 9) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Foreach_InIterator_16() + { + var src = @" +class Program +{ + static Buffer4 s_buffer; + + static System.Collections.Generic.IEnumerable Test() + { + foreach (ref readonly int y in GetBuffer()) + { + yield return 1; + System.Console.Write(y); + } + + yield return -1; + } + + static ref readonly Buffer4 GetBuffer() => ref s_buffer; +} +" + Buffer4Definition; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (8,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in GetBuffer()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 35)); + + var expectedDiagnostics = new[] + { + // (11,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(11, 34) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); } [ConditionalFact(typeof(CoreClrOnly))] - public void Foreach_InIterator_06() + public void Foreach_InIterator_17() { var src = @" class C @@ -21235,7 +22450,7 @@ static void Main() static System.Collections.Generic.IEnumerable Test(C x) { - foreach (var y in x.F) + foreach (ref readonly int y in x.F) { Increment(); System.Console.Write(' '); @@ -21255,240 +22470,107 @@ static void Increment() } } } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); - var verifier = CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); - - verifier.VerifyIL("Program.d__3.System.Collections.IEnumerator.MoveNext", -@" -{ - // Code size 151 (0x97) - .maxstack 3 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int Program.d__3.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0070 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld ""int Program.d__3.<>1__state"" - IL_0017: ldarg.0 - IL_0018: ldarg.0 - IL_0019: ldfld ""C Program.d__3.x"" - IL_001e: stfld ""C Program.d__3.<>7__wrap2"" - IL_0023: ldarg.0 - IL_0024: ldfld ""C Program.d__3.<>7__wrap2"" - IL_0029: ldfld ""Buffer4 C.F"" - IL_002e: pop - IL_002f: ldarg.0 - IL_0030: ldc.i4.0 - IL_0031: stfld ""int Program.d__3.<>7__wrap1"" - IL_0036: br.s IL_0085 - IL_0038: ldarg.0 - IL_0039: ldfld ""C Program.d__3.<>7__wrap2"" - IL_003e: ldflda ""Buffer4 C.F"" - IL_0043: ldarg.0 - IL_0044: ldfld ""int Program.d__3.<>7__wrap1"" - IL_0049: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)"" - IL_004e: ldind.i4 - IL_004f: call ""void Program.Increment()"" - IL_0054: ldc.i4.s 32 - IL_0056: call ""void System.Console.Write(char)"" - IL_005b: call ""void System.Console.Write(int)"" - IL_0060: ldarg.0 - IL_0061: ldc.i4.m1 - IL_0062: stfld ""int Program.d__3.<>2__current"" - IL_0067: ldarg.0 - IL_0068: ldc.i4.1 - IL_0069: stfld ""int Program.d__3.<>1__state"" - IL_006e: ldc.i4.1 - IL_006f: ret - IL_0070: ldarg.0 - IL_0071: ldc.i4.m1 - IL_0072: stfld ""int Program.d__3.<>1__state"" - IL_0077: ldarg.0 - IL_0078: ldarg.0 - IL_0079: ldfld ""int Program.d__3.<>7__wrap1"" - IL_007e: ldc.i4.1 - IL_007f: add - IL_0080: stfld ""int Program.d__3.<>7__wrap1"" - IL_0085: ldarg.0 - IL_0086: ldfld ""int Program.d__3.<>7__wrap1"" - IL_008b: ldc.i4.4 - IL_008c: blt.s IL_0038 - IL_008e: ldarg.0 - IL_008f: ldnull - IL_0090: stfld ""C Program.d__3.<>7__wrap2"" - IL_0095: ldc.i4.0 - IL_0096: ret -} -"); - comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: " 0 1 2 3", verify: Verification.Fails).VerifyDiagnostics(); +" + Buffer4Definition; + var expectedOutput = " 0 1 2 3"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyDiagnostics(); + comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.Fails).VerifyDiagnostics(); } [Fact] - public void Foreach_InIterator_07() + public void Foreach_InIterator_18() { var src = @" -class Program +class C { - static System.Collections.Generic.IEnumerable Test() - { - foreach (ref readonly int y in GetBuffer()) - { - } - - yield return -1; - } - - static ref readonly Buffer4 GetBuffer() => throw null; + public readonly Buffer4 F = default; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); - comp.VerifyDiagnostics( - // (6,35): error CS8176: Iterators cannot have by-reference locals - // foreach (ref readonly int y in GetBuffer()) - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "y").WithLocation(6, 35) - ); - } - [Fact] - public void Foreach_InIterator_08() - { - var src = @" class Program { - static System.Collections.Generic.IEnumerable Test() + static System.Collections.Generic.IEnumerable Test(C x) { - foreach (int y in GetBuffer()) + foreach (ref readonly int y in x.F) { yield return -1; + System.Console.Write(y); } } - - static ref readonly Buffer4 GetBuffer() => throw null; } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseDll); +" + Buffer4Definition; - comp.VerifyEmitDiagnostics( - // (6,9): error CS8178: A reference returned by a call to 'Program.GetBuffer()' cannot be preserved across 'await' or 'yield' boundary. - // foreach (int y in GetBuffer()) - Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, - @"foreach (int y in GetBuffer()) - { - yield return -1; - }").WithArguments("Program.GetBuffer()").WithLocation(6, 9) - ); + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (11,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (ref readonly int y in x.F) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 35)); + + var expectedDiagnostics = new[] + { + // (14,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(14, 34) + }; + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); } - [ConditionalFact(typeof(CoreClrOnly))] - public void Foreach_InIterator_09() + [Fact] + public void Foreach_InIterator_19() { var src = @" +class C +{ + public readonly Buffer4 F = default; +} + class Program { - static void Main() + static System.Collections.Generic.IEnumerable Test(C x) { - foreach (var a in Test()) - {} - } + ref readonly Buffer4 f = ref x.F; - static System.Collections.Generic.IEnumerable Test() - { - foreach (var y in GetBuffer()) + foreach (var i in f) System.Console.Write(i); + + foreach (var y in f) { - System.Console.Write(' '); System.Console.Write(y); yield return -1; } - } - static Buffer4 GetBuffer() - { - Buffer4 x = default; - x[0] = 111; - x[1] = 112; - x[2] = 113; - x[3] = 114; - - System.Console.Write(-1); - return x; + foreach (var j in f) System.Console.Write(j); + + foreach (var z in f) + { + System.Console.Write(z); + yield return -2; + } } } -"; - var comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); - var verifier = CompileAndVerify(comp, expectedOutput: "-1 111 112 113 114").VerifyDiagnostics(); +" + Buffer4Definition; - verifier.VerifyIL("Program.d__1.System.Collections.IEnumerator.MoveNext", -@" -{ - // Code size 121 (0x79) - .maxstack 3 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int Program.d__1.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0010 - IL_000a: ldloc.0 - IL_000b: ldc.i4.1 - IL_000c: beq.s IL_0059 - IL_000e: ldc.i4.0 - IL_000f: ret - IL_0010: ldarg.0 - IL_0011: ldc.i4.m1 - IL_0012: stfld ""int Program.d__1.<>1__state"" - IL_0017: ldarg.0 - IL_0018: call ""Buffer4 Program.GetBuffer()"" - IL_001d: stfld ""Buffer4 Program.d__1.<>7__wrap1"" - IL_0022: ldarg.0 - IL_0023: ldc.i4.0 - IL_0024: stfld ""int Program.d__1.<>7__wrap2"" - IL_0029: br.s IL_006e - IL_002b: ldarg.0 - IL_002c: ldflda ""Buffer4 Program.d__1.<>7__wrap1"" - IL_0031: ldarg.0 - IL_0032: ldfld ""int Program.d__1.<>7__wrap2"" - IL_0037: call ""ref readonly int .InlineArrayElementRefReadOnly, int>(in Buffer4, int)"" - IL_003c: ldind.i4 - IL_003d: ldc.i4.s 32 - IL_003f: call ""void System.Console.Write(char)"" - IL_0044: call ""void System.Console.Write(int)"" - IL_0049: ldarg.0 - IL_004a: ldc.i4.m1 - IL_004b: stfld ""int Program.d__1.<>2__current"" - IL_0050: ldarg.0 - IL_0051: ldc.i4.1 - IL_0052: stfld ""int Program.d__1.<>1__state"" - IL_0057: ldc.i4.1 - IL_0058: ret - IL_0059: ldarg.0 - IL_005a: ldc.i4.m1 - IL_005b: stfld ""int Program.d__1.<>1__state"" - IL_0060: ldarg.0 - IL_0061: ldarg.0 - IL_0062: ldfld ""int Program.d__1.<>7__wrap2"" - IL_0067: ldc.i4.1 - IL_0068: add - IL_0069: stfld ""int Program.d__1.<>7__wrap2"" - IL_006e: ldarg.0 - IL_006f: ldfld ""int Program.d__1.<>7__wrap2"" - IL_0074: ldc.i4.4 - IL_0075: blt.s IL_002b - IL_0077: ldc.i4.0 - IL_0078: ret -} -"); - comp = CreateCompilation(src + Buffer4Definition, targetFramework: TargetFramework.Net80, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: "-1 111 112 113 114").VerifyDiagnostics(); + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (11,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly Buffer4 f = ref x.F; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "f").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 35)); + + var expectedDiagnostics = new[] + { + // (15,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var y in f) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(15, 27), + // (21,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var j in f) System.Console.Write(j); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(21, 27), + // (23,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var z in f) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "f").WithLocation(23, 27) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyEmitDiagnostics(expectedDiagnostics); } [ConditionalFact(typeof(CoreClrOnly))] @@ -21870,12 +22952,12 @@ static void Main() "; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); comp.VerifyEmitDiagnostics( - // (7,37): error CS0306: The type 'Span' may not be used as a type argument + // (7,37): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // public static implicit operator System.Span?(Buffer4 b) => new [] {1, 2, 3, 4}; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "System.Span?").WithArguments("System.Span").WithLocation(7, 37), - // (12,36): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "System.Span?").WithArguments("System.Nullable", "T", "System.Span").WithLocation(7, 37), + // (12,36): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // System.Console.WriteLine(((System.Span?)b).Value[0]); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "System.Span?").WithArguments("System.Span").WithLocation(12, 36) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "System.Span?").WithArguments("System.Nullable", "T", "System.Span").WithLocation(12, 36) ); } @@ -22006,5 +23088,218 @@ struct ThreeStringBuffer { var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); var verifier = CompileAndVerify(comp, expectedOutput: "123124").VerifyDiagnostics(); } + + [Fact] + public void Initialization_Await_RefStruct() + { + var src = """ + using System.Threading.Tasks; + + var b = new Buffer(); + b[0] = await GetInt(); + b[1] = await GetInt(); + + static Task GetInt() => Task.FromResult(42); + + [System.Runtime.CompilerServices.InlineArray(4)] + ref struct Buffer + { + private int _element0; + } + """; + + CreateCompilation(src, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net80).VerifyDiagnostics( + // (3,1): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // var b = new Buffer(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(3, 1), + // (4,1): error CS0306: The type 'Buffer' may not be used as a type argument + // b[0] = await GetInt(); + Diagnostic(ErrorCode.ERR_BadTypeArgument, "b[0]").WithArguments("Buffer").WithLocation(4, 1), + // (5,1): error CS0306: The type 'Buffer' may not be used as a type argument + // b[1] = await GetInt(); + Diagnostic(ErrorCode.ERR_BadTypeArgument, "b[1]").WithArguments("Buffer").WithLocation(5, 1), + // (10,12): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // ref struct Buffer + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "Buffer").WithLocation(10, 12)); + + var expectedDiagnostics = new[] + { + // (4,1): error CS0306: The type 'Buffer' may not be used as a type argument + // b[0] = await GetInt(); + Diagnostic(ErrorCode.ERR_BadTypeArgument, "b[0]").WithArguments("Buffer").WithLocation(4, 1), + // (5,1): error CS0306: The type 'Buffer' may not be used as a type argument + // b[1] = await GetInt(); + Diagnostic(ErrorCode.ERR_BadTypeArgument, "b[1]").WithArguments("Buffer").WithLocation(5, 1), + // (10,12): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // ref struct Buffer + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "Buffer").WithLocation(10, 12) + }; + + CreateCompilation(src, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net80).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(src, targetFramework: TargetFramework.Net80).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Initialization_Await() + { + var src = """ + using System.Threading.Tasks; + + var b = new Buffer(); + b[0] = await GetInt(); + System.Console.Write(b[1]); + b[1] = await GetInt(); + System.Console.Write(b[1]); + + static Task GetInt() => Task.FromResult(42); + + [System.Runtime.CompilerServices.InlineArray(4)] + struct Buffer + { + private int _element0; + } + """; + foreach (var parseOptions in new[] { TestOptions.Regular12, TestOptions.RegularNext, TestOptions.RegularPreview }) + { + var verifier = CompileAndVerify(src, expectedOutput: ExecutionConditionUtil.IsDesktop ? null : "042", + parseOptions: parseOptions, targetFramework: TargetFramework.Net80, verify: Verification.FailsPEVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<
$>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ + { + // Code size 316 (0x13c) + .maxstack 3 + .locals init (int V_0, + int V_1, + System.Runtime.CompilerServices.TaskAwaiter V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<
$>d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0054 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_00cb + IL_0011: ldarg.0 + IL_0012: ldflda "Buffer Program.<
$>d__0.5__2" + IL_0017: initobj "Buffer" + IL_001d: call "System.Threading.Tasks.Task Program.<
$>g__GetInt|0_0()" + IL_0022: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0027: stloc.2 + IL_0028: ldloca.s V_2 + IL_002a: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_002f: brtrue.s IL_0070 + IL_0031: ldarg.0 + IL_0032: ldc.i4.0 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int Program.<
$>d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldloc.2 + IL_003c: stfld "System.Runtime.CompilerServices.TaskAwaiter Program.<
$>d__0.<>u__1" + IL_0041: ldarg.0 + IL_0042: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<
$>d__0.<>t__builder" + IL_0047: ldloca.s V_2 + IL_0049: ldarg.0 + IL_004a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.<
$>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.<
$>d__0)" + IL_004f: leave IL_013b + IL_0054: ldarg.0 + IL_0055: ldfld "System.Runtime.CompilerServices.TaskAwaiter Program.<
$>d__0.<>u__1" + IL_005a: stloc.2 + IL_005b: ldarg.0 + IL_005c: ldflda "System.Runtime.CompilerServices.TaskAwaiter Program.<
$>d__0.<>u__1" + IL_0061: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0067: ldarg.0 + IL_0068: ldc.i4.m1 + IL_0069: dup + IL_006a: stloc.0 + IL_006b: stfld "int Program.<
$>d__0.<>1__state" + IL_0070: ldloca.s V_2 + IL_0072: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0077: stloc.1 + IL_0078: ldarg.0 + IL_0079: ldflda "Buffer Program.<
$>d__0.5__2" + IL_007e: call "ref int .InlineArrayFirstElementRef(ref Buffer)" + IL_0083: ldloc.1 + IL_0084: stind.i4 + IL_0085: ldarg.0 + IL_0086: ldflda "Buffer Program.<
$>d__0.5__2" + IL_008b: ldc.i4.1 + IL_008c: call "ref int .InlineArrayElementRef(ref Buffer, int)" + IL_0091: ldind.i4 + IL_0092: call "void System.Console.Write(int)" + IL_0097: call "System.Threading.Tasks.Task Program.<
$>g__GetInt|0_0()" + IL_009c: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_00a1: stloc.2 + IL_00a2: ldloca.s V_2 + IL_00a4: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_00a9: brtrue.s IL_00e7 + IL_00ab: ldarg.0 + IL_00ac: ldc.i4.1 + IL_00ad: dup + IL_00ae: stloc.0 + IL_00af: stfld "int Program.<
$>d__0.<>1__state" + IL_00b4: ldarg.0 + IL_00b5: ldloc.2 + IL_00b6: stfld "System.Runtime.CompilerServices.TaskAwaiter Program.<
$>d__0.<>u__1" + IL_00bb: ldarg.0 + IL_00bc: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<
$>d__0.<>t__builder" + IL_00c1: ldloca.s V_2 + IL_00c3: ldarg.0 + IL_00c4: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.<
$>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.<
$>d__0)" + IL_00c9: leave.s IL_013b + IL_00cb: ldarg.0 + IL_00cc: ldfld "System.Runtime.CompilerServices.TaskAwaiter Program.<
$>d__0.<>u__1" + IL_00d1: stloc.2 + IL_00d2: ldarg.0 + IL_00d3: ldflda "System.Runtime.CompilerServices.TaskAwaiter Program.<
$>d__0.<>u__1" + IL_00d8: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_00de: ldarg.0 + IL_00df: ldc.i4.m1 + IL_00e0: dup + IL_00e1: stloc.0 + IL_00e2: stfld "int Program.<
$>d__0.<>1__state" + IL_00e7: ldloca.s V_2 + IL_00e9: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_00ee: stloc.1 + IL_00ef: ldarg.0 + IL_00f0: ldflda "Buffer Program.<
$>d__0.5__2" + IL_00f5: ldc.i4.1 + IL_00f6: call "ref int .InlineArrayElementRef(ref Buffer, int)" + IL_00fb: ldloc.1 + IL_00fc: stind.i4 + IL_00fd: ldarg.0 + IL_00fe: ldflda "Buffer Program.<
$>d__0.5__2" + IL_0103: ldc.i4.1 + IL_0104: call "ref int .InlineArrayElementRef(ref Buffer, int)" + IL_0109: ldind.i4 + IL_010a: call "void System.Console.Write(int)" + IL_010f: leave.s IL_0128 + } + catch System.Exception + { + IL_0111: stloc.3 + IL_0112: ldarg.0 + IL_0113: ldc.i4.s -2 + IL_0115: stfld "int Program.<
$>d__0.<>1__state" + IL_011a: ldarg.0 + IL_011b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<
$>d__0.<>t__builder" + IL_0120: ldloc.3 + IL_0121: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0126: leave.s IL_013b + } + IL_0128: ldarg.0 + IL_0129: ldc.i4.s -2 + IL_012b: stfld "int Program.<
$>d__0.<>1__state" + IL_0130: ldarg.0 + IL_0131: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<
$>d__0.<>t__builder" + IL_0136: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_013b: ret + } + """); + } + } } } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/LockTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/LockTests.cs index 61b08bdf399e5..61614ef54b64e 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/LockTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/LockTests.cs @@ -1861,9 +1861,6 @@ public void Await() } """; CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (4,7): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(4, 7), // (6,5): error CS1996: Cannot await in the body of a lock statement // await Task.Yield(); Diagnostic(ErrorCode.ERR_BadAwaitInLock, "await Task.Yield()").WithLocation(6, 5)); @@ -1875,19 +1872,137 @@ public void AsyncMethod() var source = """ #pragma warning disable 1998 // async method lacks 'await' operators using System.Threading; + using System.Threading.Tasks; class C { - async void M() + static async Task Main() { - lock (new Lock()) { } + lock (new Lock()) { System.Console.Write("L"); } } } """; - CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (8,15): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(8, 15)); + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 94 (0x5e) + .maxstack 2 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: nop + IL_0008: newobj "System.Threading.Lock..ctor()" + IL_000d: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0012: stloc.1 + .try + { + IL_0013: nop + IL_0014: ldstr "L" + IL_0019: call "void System.Console.Write(string)" + IL_001e: nop + IL_001f: nop + IL_0020: leave.s IL_002f + } + finally + { + IL_0022: ldloc.0 + IL_0023: ldc.i4.0 + IL_0024: bge.s IL_002e + IL_0026: ldloca.s V_1 + IL_0028: call "void System.Threading.Lock.Scope.Dispose()" + IL_002d: nop + IL_002e: endfinally + } + IL_002f: leave.s IL_0049 + } + catch System.Exception + { + IL_0031: stloc.2 + IL_0032: ldarg.0 + IL_0033: ldc.i4.s -2 + IL_0035: stfld "int C.
d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0040: ldloc.2 + IL_0041: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0046: nop + IL_0047: leave.s IL_005d + } + IL_0049: ldarg.0 + IL_004a: ldc.i4.s -2 + IL_004c: stfld "int C.
d__0.<>1__state" + IL_0051: ldarg.0 + IL_0052: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0057: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_005c: nop + IL_005d: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 87 (0x57) + .maxstack 2 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: newobj "System.Threading.Lock..ctor()" + IL_000c: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0011: stloc.1 + .try + { + IL_0012: ldstr "L" + IL_0017: call "void System.Console.Write(string)" + IL_001c: leave.s IL_002a + } + finally + { + IL_001e: ldloc.0 + IL_001f: ldc.i4.0 + IL_0020: bge.s IL_0029 + IL_0022: ldloca.s V_1 + IL_0024: call "void System.Threading.Lock.Scope.Dispose()" + IL_0029: endfinally + } + IL_002a: leave.s IL_0043 + } + catch System.Exception + { + IL_002c: stloc.2 + IL_002d: ldarg.0 + IL_002e: ldc.i4.s -2 + IL_0030: stfld "int C.
d__0.<>1__state" + IL_0035: ldarg.0 + IL_0036: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_003b: ldloc.2 + IL_003c: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0041: leave.s IL_0056 + } + IL_0043: ldarg.0 + IL_0044: ldc.i4.s -2 + IL_0046: stfld "int C.
d__0.<>1__state" + IL_004b: ldarg.0 + IL_004c: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0051: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0056: ret + } + """); } [Fact] @@ -1899,17 +2014,527 @@ public void AsyncMethod_WithAwait() class C { - async void M() + static async Task Main() { await Task.Yield(); - lock (new Lock()) { } + lock (new Lock()) { System.Console.Write("L"); } + await Task.Yield(); } } """; - CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (9,15): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(9, 15)); + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 311 (0x137) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, + System.Runtime.CompilerServices.YieldAwaitable V_2, + C.
d__0 V_3, + System.Threading.Lock.Scope V_4, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_5, + System.Exception V_6) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0019 + IL_0012: br.s IL_0058 + IL_0014: br IL_00e1 + IL_0019: nop + IL_001a: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_001f: stloc.2 + IL_0020: ldloca.s V_2 + IL_0022: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_0027: stloc.1 + IL_0028: ldloca.s V_1 + IL_002a: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_002f: brtrue.s IL_0074 + IL_0031: ldarg.0 + IL_0032: ldc.i4.0 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int C.
d__0.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldloc.1 + IL_003c: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_0041: ldarg.0 + IL_0042: stloc.3 + IL_0043: ldarg.0 + IL_0044: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0049: ldloca.s V_1 + IL_004b: ldloca.s V_3 + IL_004d: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.
d__0)" + IL_0052: nop + IL_0053: leave IL_0136 + IL_0058: ldarg.0 + IL_0059: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_005e: stloc.1 + IL_005f: ldarg.0 + IL_0060: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_0065: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_006b: ldarg.0 + IL_006c: ldc.i4.m1 + IL_006d: dup + IL_006e: stloc.0 + IL_006f: stfld "int C.
d__0.<>1__state" + IL_0074: ldloca.s V_1 + IL_0076: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_007b: nop + IL_007c: newobj "System.Threading.Lock..ctor()" + IL_0081: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0086: stloc.s V_4 + .try + { + IL_0088: nop + IL_0089: ldstr "L" + IL_008e: call "void System.Console.Write(string)" + IL_0093: nop + IL_0094: nop + IL_0095: leave.s IL_00a4 + } + finally + { + IL_0097: ldloc.0 + IL_0098: ldc.i4.0 + IL_0099: bge.s IL_00a3 + IL_009b: ldloca.s V_4 + IL_009d: call "void System.Threading.Lock.Scope.Dispose()" + IL_00a2: nop + IL_00a3: endfinally + } + IL_00a4: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_00a9: stloc.2 + IL_00aa: ldloca.s V_2 + IL_00ac: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_00b1: stloc.s V_5 + IL_00b3: ldloca.s V_5 + IL_00b5: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00ba: brtrue.s IL_00fe + IL_00bc: ldarg.0 + IL_00bd: ldc.i4.1 + IL_00be: dup + IL_00bf: stloc.0 + IL_00c0: stfld "int C.
d__0.<>1__state" + IL_00c5: ldarg.0 + IL_00c6: ldloc.s V_5 + IL_00c8: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_00cd: ldarg.0 + IL_00ce: stloc.3 + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_00d5: ldloca.s V_5 + IL_00d7: ldloca.s V_3 + IL_00d9: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.
d__0)" + IL_00de: nop + IL_00df: leave.s IL_0136 + IL_00e1: ldarg.0 + IL_00e2: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_00e7: stloc.s V_5 + IL_00e9: ldarg.0 + IL_00ea: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_00ef: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00f5: ldarg.0 + IL_00f6: ldc.i4.m1 + IL_00f7: dup + IL_00f8: stloc.0 + IL_00f9: stfld "int C.
d__0.<>1__state" + IL_00fe: ldloca.s V_5 + IL_0100: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_0105: nop + IL_0106: leave.s IL_0122 + } + catch System.Exception + { + IL_0108: stloc.s V_6 + IL_010a: ldarg.0 + IL_010b: ldc.i4.s -2 + IL_010d: stfld "int C.
d__0.<>1__state" + IL_0112: ldarg.0 + IL_0113: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0118: ldloc.s V_6 + IL_011a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_011f: nop + IL_0120: leave.s IL_0136 + } + IL_0122: ldarg.0 + IL_0123: ldc.i4.s -2 + IL_0125: stfld "int C.
d__0.<>1__state" + IL_012a: ldarg.0 + IL_012b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0130: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0135: nop + IL_0136: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 282 (0x11a) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, + System.Runtime.CompilerServices.YieldAwaitable V_2, + System.Threading.Lock.Scope V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_004b + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_00c8 + IL_0011: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_0016: stloc.2 + IL_0017: ldloca.s V_2 + IL_0019: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_001e: stloc.1 + IL_001f: ldloca.s V_1 + IL_0021: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_0026: brtrue.s IL_0067 + IL_0028: ldarg.0 + IL_0029: ldc.i4.0 + IL_002a: dup + IL_002b: stloc.0 + IL_002c: stfld "int C.
d__0.<>1__state" + IL_0031: ldarg.0 + IL_0032: ldloc.1 + IL_0033: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_0038: ldarg.0 + IL_0039: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_003e: ldloca.s V_1 + IL_0040: ldarg.0 + IL_0041: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.
d__0)" + IL_0046: leave IL_0119 + IL_004b: ldarg.0 + IL_004c: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_0051: stloc.1 + IL_0052: ldarg.0 + IL_0053: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_0058: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_005e: ldarg.0 + IL_005f: ldc.i4.m1 + IL_0060: dup + IL_0061: stloc.0 + IL_0062: stfld "int C.
d__0.<>1__state" + IL_0067: ldloca.s V_1 + IL_0069: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_006e: newobj "System.Threading.Lock..ctor()" + IL_0073: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0078: stloc.3 + .try + { + IL_0079: ldstr "L" + IL_007e: call "void System.Console.Write(string)" + IL_0083: leave.s IL_0091 + } + finally + { + IL_0085: ldloc.0 + IL_0086: ldc.i4.0 + IL_0087: bge.s IL_0090 + IL_0089: ldloca.s V_3 + IL_008b: call "void System.Threading.Lock.Scope.Dispose()" + IL_0090: endfinally + } + IL_0091: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_0096: stloc.2 + IL_0097: ldloca.s V_2 + IL_0099: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_009e: stloc.1 + IL_009f: ldloca.s V_1 + IL_00a1: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00a6: brtrue.s IL_00e4 + IL_00a8: ldarg.0 + IL_00a9: ldc.i4.1 + IL_00aa: dup + IL_00ab: stloc.0 + IL_00ac: stfld "int C.
d__0.<>1__state" + IL_00b1: ldarg.0 + IL_00b2: ldloc.1 + IL_00b3: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_00b8: ldarg.0 + IL_00b9: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_00be: ldloca.s V_1 + IL_00c0: ldarg.0 + IL_00c1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref C.
d__0)" + IL_00c6: leave.s IL_0119 + IL_00c8: ldarg.0 + IL_00c9: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_00ce: stloc.1 + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter C.
d__0.<>u__1" + IL_00d5: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00db: ldarg.0 + IL_00dc: ldc.i4.m1 + IL_00dd: dup + IL_00de: stloc.0 + IL_00df: stfld "int C.
d__0.<>1__state" + IL_00e4: ldloca.s V_1 + IL_00e6: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_00eb: leave.s IL_0106 + } + catch System.Exception + { + IL_00ed: stloc.s V_4 + IL_00ef: ldarg.0 + IL_00f0: ldc.i4.s -2 + IL_00f2: stfld "int C.
d__0.<>1__state" + IL_00f7: ldarg.0 + IL_00f8: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_00fd: ldloc.s V_4 + IL_00ff: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0104: leave.s IL_0119 + } + IL_0106: ldarg.0 + IL_0107: ldc.i4.s -2 + IL_0109: stfld "int C.
d__0.<>1__state" + IL_010e: ldarg.0 + IL_010f: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0114: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0119: ret + } + """); + } + + [Fact] + public void AsyncMethod_AwaitResource() + { + var source = """ + #pragma warning disable 1998 // async method lacks 'await' operators + using System.Threading; + using System.Threading.Tasks; + + class C + { + static async Task Main() + { + lock (await GetLock()) { System.Console.Write("L"); } + } + + static async Task GetLock() => new Lock(); + } + """; + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 211 (0xd3) + .maxstack 3 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Runtime.CompilerServices.TaskAwaiter V_2, + C.
d__0 V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_000c + IL_000a: br.s IL_000e + IL_000c: br.s IL_004a + IL_000e: nop + IL_000f: call "System.Threading.Tasks.Task C.GetLock()" + IL_0014: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0019: stloc.2 + IL_001a: ldloca.s V_2 + IL_001c: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_0021: brtrue.s IL_0066 + IL_0023: ldarg.0 + IL_0024: ldc.i4.0 + IL_0025: dup + IL_0026: stloc.0 + IL_0027: stfld "int C.
d__0.<>1__state" + IL_002c: ldarg.0 + IL_002d: ldloc.2 + IL_002e: stfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_0033: ldarg.0 + IL_0034: stloc.3 + IL_0035: ldarg.0 + IL_0036: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_003b: ldloca.s V_2 + IL_003d: ldloca.s V_3 + IL_003f: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__0)" + IL_0044: nop + IL_0045: leave IL_00d2 + IL_004a: ldarg.0 + IL_004b: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_0050: stloc.2 + IL_0051: ldarg.0 + IL_0052: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_0057: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_005d: ldarg.0 + IL_005e: ldc.i4.m1 + IL_005f: dup + IL_0060: stloc.0 + IL_0061: stfld "int C.
d__0.<>1__state" + IL_0066: ldarg.0 + IL_0067: ldloca.s V_2 + IL_0069: call "System.Threading.Lock System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_006e: stfld "System.Threading.Lock C.
d__0.<>s__1" + IL_0073: ldarg.0 + IL_0074: ldfld "System.Threading.Lock C.
d__0.<>s__1" + IL_0079: callvirt "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_007e: stloc.1 + IL_007f: ldarg.0 + IL_0080: ldnull + IL_0081: stfld "System.Threading.Lock C.
d__0.<>s__1" + .try + { + IL_0086: nop + IL_0087: ldstr "L" + IL_008c: call "void System.Console.Write(string)" + IL_0091: nop + IL_0092: nop + IL_0093: leave.s IL_00a2 + } + finally + { + IL_0095: ldloc.0 + IL_0096: ldc.i4.0 + IL_0097: bge.s IL_00a1 + IL_0099: ldloca.s V_1 + IL_009b: call "void System.Threading.Lock.Scope.Dispose()" + IL_00a0: nop + IL_00a1: endfinally + } + IL_00a2: leave.s IL_00be + } + catch System.Exception + { + IL_00a4: stloc.s V_4 + IL_00a6: ldarg.0 + IL_00a7: ldc.i4.s -2 + IL_00a9: stfld "int C.
d__0.<>1__state" + IL_00ae: ldarg.0 + IL_00af: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_00b4: ldloc.s V_4 + IL_00b6: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_00bb: nop + IL_00bc: leave.s IL_00d2 + } + IL_00be: ldarg.0 + IL_00bf: ldc.i4.s -2 + IL_00c1: stfld "int C.
d__0.<>1__state" + IL_00c6: ldarg.0 + IL_00c7: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_00cc: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_00d1: nop + IL_00d2: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 172 (0xac) + .maxstack 3 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Runtime.CompilerServices.TaskAwaiter V_2, + System.Exception V_3) + IL_0000: ldarg.0 + IL_0001: ldfld "int C.
d__0.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_003e + IL_000a: call "System.Threading.Tasks.Task C.GetLock()" + IL_000f: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" + IL_0014: stloc.2 + IL_0015: ldloca.s V_2 + IL_0017: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" + IL_001c: brtrue.s IL_005a + IL_001e: ldarg.0 + IL_001f: ldc.i4.0 + IL_0020: dup + IL_0021: stloc.0 + IL_0022: stfld "int C.
d__0.<>1__state" + IL_0027: ldarg.0 + IL_0028: ldloc.2 + IL_0029: stfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_002e: ldarg.0 + IL_002f: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0034: ldloca.s V_2 + IL_0036: ldarg.0 + IL_0037: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.
d__0)" + IL_003c: leave.s IL_00ab + IL_003e: ldarg.0 + IL_003f: ldfld "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_0044: stloc.2 + IL_0045: ldarg.0 + IL_0046: ldflda "System.Runtime.CompilerServices.TaskAwaiter C.
d__0.<>u__1" + IL_004b: initobj "System.Runtime.CompilerServices.TaskAwaiter" + IL_0051: ldarg.0 + IL_0052: ldc.i4.m1 + IL_0053: dup + IL_0054: stloc.0 + IL_0055: stfld "int C.
d__0.<>1__state" + IL_005a: ldloca.s V_2 + IL_005c: call "System.Threading.Lock System.Runtime.CompilerServices.TaskAwaiter.GetResult()" + IL_0061: callvirt "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0066: stloc.1 + .try + { + IL_0067: ldstr "L" + IL_006c: call "void System.Console.Write(string)" + IL_0071: leave.s IL_007f + } + finally + { + IL_0073: ldloc.0 + IL_0074: ldc.i4.0 + IL_0075: bge.s IL_007e + IL_0077: ldloca.s V_1 + IL_0079: call "void System.Threading.Lock.Scope.Dispose()" + IL_007e: endfinally + } + IL_007f: leave.s IL_0098 + } + catch System.Exception + { + IL_0081: stloc.3 + IL_0082: ldarg.0 + IL_0083: ldc.i4.s -2 + IL_0085: stfld "int C.
d__0.<>1__state" + IL_008a: ldarg.0 + IL_008b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_0090: ldloc.3 + IL_0091: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0096: leave.s IL_00ab + } + IL_0098: ldarg.0 + IL_0099: ldc.i4.s -2 + IL_009b: stfld "int C.
d__0.<>1__state" + IL_00a0: ldarg.0 + IL_00a1: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder" + IL_00a6: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_00ab: ret + } + """); } [Fact] @@ -1921,15 +2546,132 @@ public void AsyncLocalFunction() async void local() { - lock (new Lock()) { } + lock (new Lock()) { System.Console.Write("L"); } } local(); """; - CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (6,11): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(6, 11)); + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<<
$>g__local|0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 94 (0x5e) + .maxstack 2 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: nop + IL_0008: newobj "System.Threading.Lock..ctor()" + IL_000d: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0012: stloc.1 + .try + { + IL_0013: nop + IL_0014: ldstr "L" + IL_0019: call "void System.Console.Write(string)" + IL_001e: nop + IL_001f: nop + IL_0020: leave.s IL_002f + } + finally + { + IL_0022: ldloc.0 + IL_0023: ldc.i4.0 + IL_0024: bge.s IL_002e + IL_0026: ldloca.s V_1 + IL_0028: call "void System.Threading.Lock.Scope.Dispose()" + IL_002d: nop + IL_002e: endfinally + } + IL_002f: leave.s IL_0049 + } + catch System.Exception + { + IL_0031: stloc.2 + IL_0032: ldarg.0 + IL_0033: ldc.i4.s -2 + IL_0035: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0040: ldloc.2 + IL_0041: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" + IL_0046: nop + IL_0047: leave.s IL_005d + } + IL_0049: ldarg.0 + IL_004a: ldc.i4.s -2 + IL_004c: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0051: ldarg.0 + IL_0052: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0057: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" + IL_005c: nop + IL_005d: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<<
$>g__local|0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 87 (0x57) + .maxstack 2 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: newobj "System.Threading.Lock..ctor()" + IL_000c: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0011: stloc.1 + .try + { + IL_0012: ldstr "L" + IL_0017: call "void System.Console.Write(string)" + IL_001c: leave.s IL_002a + } + finally + { + IL_001e: ldloc.0 + IL_001f: ldc.i4.0 + IL_0020: bge.s IL_0029 + IL_0022: ldloca.s V_1 + IL_0024: call "void System.Threading.Lock.Scope.Dispose()" + IL_0029: endfinally + } + IL_002a: leave.s IL_0043 + } + catch System.Exception + { + IL_002c: stloc.2 + IL_002d: ldarg.0 + IL_002e: ldc.i4.s -2 + IL_0030: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0035: ldarg.0 + IL_0036: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_003b: ldloc.2 + IL_003c: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)" + IL_0041: leave.s IL_0056 + } + IL_0043: ldarg.0 + IL_0044: ldc.i4.s -2 + IL_0046: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_004b: ldarg.0 + IL_004c: ldflda "System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0051: call "void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()" + IL_0056: ret + } + """); } [Fact] @@ -1939,18 +2681,304 @@ public void AsyncLocalFunction_WithAwait() using System.Threading; using System.Threading.Tasks; - async void local() + async Task local() { await Task.Yield(); - lock (new Lock()) { } + lock (new Lock()) { System.Console.Write("L"); } + await Task.Yield(); } - local(); + await local(); """; - CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (7,11): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(7, 11)); + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<<
$>g__local|0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 311 (0x137) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, + System.Runtime.CompilerServices.YieldAwaitable V_2, + Program.<<
$>g__local|0_0>d V_3, + System.Threading.Lock.Scope V_4, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_5, + System.Exception V_6) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0019 + IL_0012: br.s IL_0058 + IL_0014: br IL_00e1 + IL_0019: nop + IL_001a: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_001f: stloc.2 + IL_0020: ldloca.s V_2 + IL_0022: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_0027: stloc.1 + IL_0028: ldloca.s V_1 + IL_002a: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_002f: brtrue.s IL_0074 + IL_0031: ldarg.0 + IL_0032: ldc.i4.0 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldloc.1 + IL_003c: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_0041: ldarg.0 + IL_0042: stloc.3 + IL_0043: ldarg.0 + IL_0044: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0049: ldloca.s V_1 + IL_004b: ldloca.s V_3 + IL_004d: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted$>g__local|0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<<
$>g__local|0_0>d)" + IL_0052: nop + IL_0053: leave IL_0136 + IL_0058: ldarg.0 + IL_0059: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_005e: stloc.1 + IL_005f: ldarg.0 + IL_0060: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_0065: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_006b: ldarg.0 + IL_006c: ldc.i4.m1 + IL_006d: dup + IL_006e: stloc.0 + IL_006f: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0074: ldloca.s V_1 + IL_0076: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_007b: nop + IL_007c: newobj "System.Threading.Lock..ctor()" + IL_0081: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0086: stloc.s V_4 + .try + { + IL_0088: nop + IL_0089: ldstr "L" + IL_008e: call "void System.Console.Write(string)" + IL_0093: nop + IL_0094: nop + IL_0095: leave.s IL_00a4 + } + finally + { + IL_0097: ldloc.0 + IL_0098: ldc.i4.0 + IL_0099: bge.s IL_00a3 + IL_009b: ldloca.s V_4 + IL_009d: call "void System.Threading.Lock.Scope.Dispose()" + IL_00a2: nop + IL_00a3: endfinally + } + IL_00a4: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_00a9: stloc.2 + IL_00aa: ldloca.s V_2 + IL_00ac: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_00b1: stloc.s V_5 + IL_00b3: ldloca.s V_5 + IL_00b5: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00ba: brtrue.s IL_00fe + IL_00bc: ldarg.0 + IL_00bd: ldc.i4.1 + IL_00be: dup + IL_00bf: stloc.0 + IL_00c0: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_00c5: ldarg.0 + IL_00c6: ldloc.s V_5 + IL_00c8: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_00cd: ldarg.0 + IL_00ce: stloc.3 + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_00d5: ldloca.s V_5 + IL_00d7: ldloca.s V_3 + IL_00d9: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted$>g__local|0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<<
$>g__local|0_0>d)" + IL_00de: nop + IL_00df: leave.s IL_0136 + IL_00e1: ldarg.0 + IL_00e2: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_00e7: stloc.s V_5 + IL_00e9: ldarg.0 + IL_00ea: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_00ef: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00f5: ldarg.0 + IL_00f6: ldc.i4.m1 + IL_00f7: dup + IL_00f8: stloc.0 + IL_00f9: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_00fe: ldloca.s V_5 + IL_0100: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_0105: nop + IL_0106: leave.s IL_0122 + } + catch System.Exception + { + IL_0108: stloc.s V_6 + IL_010a: ldarg.0 + IL_010b: ldc.i4.s -2 + IL_010d: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0112: ldarg.0 + IL_0113: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0118: ldloc.s V_6 + IL_011a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_011f: nop + IL_0120: leave.s IL_0136 + } + IL_0122: ldarg.0 + IL_0123: ldc.i4.s -2 + IL_0125: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_012a: ldarg.0 + IL_012b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0130: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0135: nop + IL_0136: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<<
$>g__local|0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 282 (0x11a) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, + System.Runtime.CompilerServices.YieldAwaitable V_2, + System.Threading.Lock.Scope V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_004b + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_00c8 + IL_0011: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_0016: stloc.2 + IL_0017: ldloca.s V_2 + IL_0019: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_001e: stloc.1 + IL_001f: ldloca.s V_1 + IL_0021: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_0026: brtrue.s IL_0067 + IL_0028: ldarg.0 + IL_0029: ldc.i4.0 + IL_002a: dup + IL_002b: stloc.0 + IL_002c: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0031: ldarg.0 + IL_0032: ldloc.1 + IL_0033: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_0038: ldarg.0 + IL_0039: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_003e: ldloca.s V_1 + IL_0040: ldarg.0 + IL_0041: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted$>g__local|0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<<
$>g__local|0_0>d)" + IL_0046: leave IL_0119 + IL_004b: ldarg.0 + IL_004c: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_0051: stloc.1 + IL_0052: ldarg.0 + IL_0053: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_0058: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_005e: ldarg.0 + IL_005f: ldc.i4.m1 + IL_0060: dup + IL_0061: stloc.0 + IL_0062: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_0067: ldloca.s V_1 + IL_0069: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_006e: newobj "System.Threading.Lock..ctor()" + IL_0073: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0078: stloc.3 + .try + { + IL_0079: ldstr "L" + IL_007e: call "void System.Console.Write(string)" + IL_0083: leave.s IL_0091 + } + finally + { + IL_0085: ldloc.0 + IL_0086: ldc.i4.0 + IL_0087: bge.s IL_0090 + IL_0089: ldloca.s V_3 + IL_008b: call "void System.Threading.Lock.Scope.Dispose()" + IL_0090: endfinally + } + IL_0091: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_0096: stloc.2 + IL_0097: ldloca.s V_2 + IL_0099: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_009e: stloc.1 + IL_009f: ldloca.s V_1 + IL_00a1: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00a6: brtrue.s IL_00e4 + IL_00a8: ldarg.0 + IL_00a9: ldc.i4.1 + IL_00aa: dup + IL_00ab: stloc.0 + IL_00ac: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_00b1: ldarg.0 + IL_00b2: ldloc.1 + IL_00b3: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_00b8: ldarg.0 + IL_00b9: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_00be: ldloca.s V_1 + IL_00c0: ldarg.0 + IL_00c1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted$>g__local|0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<<
$>g__local|0_0>d)" + IL_00c6: leave.s IL_0119 + IL_00c8: ldarg.0 + IL_00c9: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_00ce: stloc.1 + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<<
$>g__local|0_0>d.<>u__1" + IL_00d5: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00db: ldarg.0 + IL_00dc: ldc.i4.m1 + IL_00dd: dup + IL_00de: stloc.0 + IL_00df: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_00e4: ldloca.s V_1 + IL_00e6: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_00eb: leave.s IL_0106 + } + catch System.Exception + { + IL_00ed: stloc.s V_4 + IL_00ef: ldarg.0 + IL_00f0: ldc.i4.s -2 + IL_00f2: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_00f7: ldarg.0 + IL_00f8: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_00fd: ldloc.s V_4 + IL_00ff: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0104: leave.s IL_0119 + } + IL_0106: ldarg.0 + IL_0107: ldc.i4.s -2 + IL_0109: stfld "int Program.<<
$>g__local|0_0>d.<>1__state" + IL_010e: ldarg.0 + IL_010f: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__local|0_0>d.<>t__builder" + IL_0114: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0119: ret + } + """); } [Fact] @@ -1962,13 +2990,132 @@ public void AsyncLambda() var lam = async () => { - lock (new Lock()) { } + lock (new Lock()) { System.Console.Write("L"); } }; + + await lam(); """; - CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (6,11): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(6, 11)); + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<>c.<<
$>b__0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 94 (0x5e) + .maxstack 2 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: nop + IL_0008: newobj "System.Threading.Lock..ctor()" + IL_000d: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0012: stloc.1 + .try + { + IL_0013: nop + IL_0014: ldstr "L" + IL_0019: call "void System.Console.Write(string)" + IL_001e: nop + IL_001f: nop + IL_0020: leave.s IL_002f + } + finally + { + IL_0022: ldloc.0 + IL_0023: ldc.i4.0 + IL_0024: bge.s IL_002e + IL_0026: ldloca.s V_1 + IL_0028: call "void System.Threading.Lock.Scope.Dispose()" + IL_002d: nop + IL_002e: endfinally + } + IL_002f: leave.s IL_0049 + } + catch System.Exception + { + IL_0031: stloc.2 + IL_0032: ldarg.0 + IL_0033: ldc.i4.s -2 + IL_0035: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0040: ldloc.2 + IL_0041: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0046: nop + IL_0047: leave.s IL_005d + } + IL_0049: ldarg.0 + IL_004a: ldc.i4.s -2 + IL_004c: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0051: ldarg.0 + IL_0052: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0057: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_005c: nop + IL_005d: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<>c.<<
$>b__0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 87 (0x57) + .maxstack 2 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Exception V_2) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: newobj "System.Threading.Lock..ctor()" + IL_000c: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0011: stloc.1 + .try + { + IL_0012: ldstr "L" + IL_0017: call "void System.Console.Write(string)" + IL_001c: leave.s IL_002a + } + finally + { + IL_001e: ldloc.0 + IL_001f: ldc.i4.0 + IL_0020: bge.s IL_0029 + IL_0022: ldloca.s V_1 + IL_0024: call "void System.Threading.Lock.Scope.Dispose()" + IL_0029: endfinally + } + IL_002a: leave.s IL_0043 + } + catch System.Exception + { + IL_002c: stloc.2 + IL_002d: ldarg.0 + IL_002e: ldc.i4.s -2 + IL_0030: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0035: ldarg.0 + IL_0036: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_003b: ldloc.2 + IL_003c: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0041: leave.s IL_0056 + } + IL_0043: ldarg.0 + IL_0044: ldc.i4.s -2 + IL_0046: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_004b: ldarg.0 + IL_004c: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0051: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0056: ret + } + """); } [Fact] @@ -1981,13 +3128,301 @@ public void AsyncLambda_WithAwait() var lam = async () => { await Task.Yield(); - lock (new Lock()) { } + lock (new Lock()) { System.Console.Write("L"); } + await Task.Yield(); }; + + await lam(); """; - CreateCompilation([source, LockTypeDefinition]).VerifyDiagnostics( - // (7,11): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. - // lock (new Lock()) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(7, 11)); + var expectedOutput = "ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<>c.<<
$>b__0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 311 (0x137) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, + System.Runtime.CompilerServices.YieldAwaitable V_2, + Program.<>c.<<
$>b__0_0>d V_3, + System.Threading.Lock.Scope V_4, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_5, + System.Exception V_6) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0019 + IL_0012: br.s IL_0058 + IL_0014: br IL_00e1 + IL_0019: nop + IL_001a: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_001f: stloc.2 + IL_0020: ldloca.s V_2 + IL_0022: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_0027: stloc.1 + IL_0028: ldloca.s V_1 + IL_002a: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_002f: brtrue.s IL_0074 + IL_0031: ldarg.0 + IL_0032: ldc.i4.0 + IL_0033: dup + IL_0034: stloc.0 + IL_0035: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_003a: ldarg.0 + IL_003b: ldloc.1 + IL_003c: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_0041: ldarg.0 + IL_0042: stloc.3 + IL_0043: ldarg.0 + IL_0044: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0049: ldloca.s V_1 + IL_004b: ldloca.s V_3 + IL_004d: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedc.<<
$>b__0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<>c.<<
$>b__0_0>d)" + IL_0052: nop + IL_0053: leave IL_0136 + IL_0058: ldarg.0 + IL_0059: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_005e: stloc.1 + IL_005f: ldarg.0 + IL_0060: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_0065: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_006b: ldarg.0 + IL_006c: ldc.i4.m1 + IL_006d: dup + IL_006e: stloc.0 + IL_006f: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0074: ldloca.s V_1 + IL_0076: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_007b: nop + IL_007c: newobj "System.Threading.Lock..ctor()" + IL_0081: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0086: stloc.s V_4 + .try + { + IL_0088: nop + IL_0089: ldstr "L" + IL_008e: call "void System.Console.Write(string)" + IL_0093: nop + IL_0094: nop + IL_0095: leave.s IL_00a4 + } + finally + { + IL_0097: ldloc.0 + IL_0098: ldc.i4.0 + IL_0099: bge.s IL_00a3 + IL_009b: ldloca.s V_4 + IL_009d: call "void System.Threading.Lock.Scope.Dispose()" + IL_00a2: nop + IL_00a3: endfinally + } + IL_00a4: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_00a9: stloc.2 + IL_00aa: ldloca.s V_2 + IL_00ac: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_00b1: stloc.s V_5 + IL_00b3: ldloca.s V_5 + IL_00b5: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00ba: brtrue.s IL_00fe + IL_00bc: ldarg.0 + IL_00bd: ldc.i4.1 + IL_00be: dup + IL_00bf: stloc.0 + IL_00c0: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_00c5: ldarg.0 + IL_00c6: ldloc.s V_5 + IL_00c8: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_00cd: ldarg.0 + IL_00ce: stloc.3 + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_00d5: ldloca.s V_5 + IL_00d7: ldloca.s V_3 + IL_00d9: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedc.<<
$>b__0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<>c.<<
$>b__0_0>d)" + IL_00de: nop + IL_00df: leave.s IL_0136 + IL_00e1: ldarg.0 + IL_00e2: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_00e7: stloc.s V_5 + IL_00e9: ldarg.0 + IL_00ea: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_00ef: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00f5: ldarg.0 + IL_00f6: ldc.i4.m1 + IL_00f7: dup + IL_00f8: stloc.0 + IL_00f9: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_00fe: ldloca.s V_5 + IL_0100: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_0105: nop + IL_0106: leave.s IL_0122 + } + catch System.Exception + { + IL_0108: stloc.s V_6 + IL_010a: ldarg.0 + IL_010b: ldc.i4.s -2 + IL_010d: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0112: ldarg.0 + IL_0113: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0118: ldloc.s V_6 + IL_011a: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_011f: nop + IL_0120: leave.s IL_0136 + } + IL_0122: ldarg.0 + IL_0123: ldc.i4.s -2 + IL_0125: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_012a: ldarg.0 + IL_012b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0130: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0135: nop + IL_0136: ret + } + """); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.<>c.<<
$>b__0_0>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 282 (0x11a) + .maxstack 3 + .locals init (int V_0, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_1, + System.Runtime.CompilerServices.YieldAwaitable V_2, + System.Threading.Lock.Scope V_3, + System.Exception V_4) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_004b + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_00c8 + IL_0011: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_0016: stloc.2 + IL_0017: ldloca.s V_2 + IL_0019: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_001e: stloc.1 + IL_001f: ldloca.s V_1 + IL_0021: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_0026: brtrue.s IL_0067 + IL_0028: ldarg.0 + IL_0029: ldc.i4.0 + IL_002a: dup + IL_002b: stloc.0 + IL_002c: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0031: ldarg.0 + IL_0032: ldloc.1 + IL_0033: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_0038: ldarg.0 + IL_0039: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_003e: ldloca.s V_1 + IL_0040: ldarg.0 + IL_0041: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedc.<<
$>b__0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<>c.<<
$>b__0_0>d)" + IL_0046: leave IL_0119 + IL_004b: ldarg.0 + IL_004c: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_0051: stloc.1 + IL_0052: ldarg.0 + IL_0053: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_0058: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_005e: ldarg.0 + IL_005f: ldc.i4.m1 + IL_0060: dup + IL_0061: stloc.0 + IL_0062: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_0067: ldloca.s V_1 + IL_0069: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_006e: newobj "System.Threading.Lock..ctor()" + IL_0073: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0078: stloc.3 + .try + { + IL_0079: ldstr "L" + IL_007e: call "void System.Console.Write(string)" + IL_0083: leave.s IL_0091 + } + finally + { + IL_0085: ldloc.0 + IL_0086: ldc.i4.0 + IL_0087: bge.s IL_0090 + IL_0089: ldloca.s V_3 + IL_008b: call "void System.Threading.Lock.Scope.Dispose()" + IL_0090: endfinally + } + IL_0091: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_0096: stloc.2 + IL_0097: ldloca.s V_2 + IL_0099: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_009e: stloc.1 + IL_009f: ldloca.s V_1 + IL_00a1: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00a6: brtrue.s IL_00e4 + IL_00a8: ldarg.0 + IL_00a9: ldc.i4.1 + IL_00aa: dup + IL_00ab: stloc.0 + IL_00ac: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_00b1: ldarg.0 + IL_00b2: ldloc.1 + IL_00b3: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_00b8: ldarg.0 + IL_00b9: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_00be: ldloca.s V_1 + IL_00c0: ldarg.0 + IL_00c1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedc.<<
$>b__0_0>d>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.<>c.<<
$>b__0_0>d)" + IL_00c6: leave.s IL_0119 + IL_00c8: ldarg.0 + IL_00c9: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_00ce: stloc.1 + IL_00cf: ldarg.0 + IL_00d0: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.<>c.<<
$>b__0_0>d.<>u__1" + IL_00d5: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00db: ldarg.0 + IL_00dc: ldc.i4.m1 + IL_00dd: dup + IL_00de: stloc.0 + IL_00df: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_00e4: ldloca.s V_1 + IL_00e6: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_00eb: leave.s IL_0106 + } + catch System.Exception + { + IL_00ed: stloc.s V_4 + IL_00ef: ldarg.0 + IL_00f0: ldc.i4.s -2 + IL_00f2: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_00f7: ldarg.0 + IL_00f8: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_00fd: ldloc.s V_4 + IL_00ff: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" + IL_0104: leave.s IL_0119 + } + IL_0106: ldarg.0 + IL_0107: ldc.i4.s -2 + IL_0109: stfld "int Program.<>c.<<
$>b__0_0>d.<>1__state" + IL_010e: ldarg.0 + IL_010f: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<>c.<<
$>b__0_0>d.<>t__builder" + IL_0114: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()" + IL_0119: ret + } + """); } [Fact] @@ -2011,9 +3446,93 @@ IEnumerable M() } """; CreateCompilation([source, LockTypeDefinition]).VerifyEmitDiagnostics( - // (9,15): error CS4013: Instance of type 'Lock.Scope' cannot be used inside a nested function, query expression, iterator block or async method + // (9,15): error CS4007: Instance of type 'System.Threading.Lock.Scope' cannot be preserved across 'await' or 'yield' boundary. // lock (new Lock()) - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "new Lock()").WithArguments("System.Threading.Lock.Scope").WithLocation(9, 15)); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new Lock()").WithArguments("System.Threading.Lock.Scope").WithLocation(9, 15), + // (11,13): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return 2; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(11, 13)); + } + + [Fact] + public void Yield_Break() + { + var source = """ + #pragma warning disable CS0162 // Unreachable code detected + using System; + using System.Collections.Generic; + using System.Threading; + + static class Program + { + static void Main() + { + foreach (var x in M()) + { + Console.Write(x); + } + } + + static IEnumerable M() + { + yield return 1; + lock (new Lock()) + { + Console.Write("L"); + yield break; + Console.Write("B"); + } + yield return 2; + } + } + """; + var expectedOutput = "1ELD"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + } + + [Fact] + public void Yield_AroundOnly() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading; + + static class Program + { + static void Main() + { + foreach (var x in M()) + { + Console.Write(x); + } + } + + static IEnumerable M() + { + yield return 1; + lock (new Lock()) + { + Console.Write("L"); + } + yield return 2; + } + } + """; + var expectedOutput = "1ELD2"; + var verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.ReleaseExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + + verifier = CompileAndVerify([source, LockTypeDefinition], options: TestOptions.DebugExe, + verify: Verification.FailsILVerify, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); } [Fact] @@ -2038,10 +3557,455 @@ async IAsyncEnumerable M() } } """; - CreateCompilationWithTasksExtensions([source, LockTypeDefinition, AsyncStreamsTypes]).VerifyDiagnostics( - // (10,15): error CS9217: A lock statement on a value of type 'System.Threading.Lock' cannot be used in async methods or async lambda expressions. + CreateCompilationWithTasksExtensions([source, LockTypeDefinition, AsyncStreamsTypes]).VerifyEmitDiagnostics( + // (10,15): error CS4007: Instance of type 'System.Threading.Lock.Scope' cannot be preserved across 'await' or 'yield' boundary. // lock (new Lock()) - Diagnostic(ErrorCode.ERR_BadSpecialByRefLock, "new Lock()").WithLocation(10, 15)); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new Lock()").WithArguments("System.Threading.Lock.Scope").WithLocation(10, 15), + // (12,13): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return 2; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(12, 13)); + } + + [Fact] + public void Yield_Async_Break() + { + var source = """ + #pragma warning disable CS0162 // Unreachable code detected + using System; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + + static class Program + { + static async Task Main() + { + await foreach (var x in M()) + { + Console.Write(x); + } + } + + async static IAsyncEnumerable M() + { + yield return 1; + await Task.Yield(); + lock (new Lock()) + { + Console.Write("L"); + yield break; + Console.Write("B"); + } + await Task.Yield(); + yield return 2; + } + } + """; + var expectedOutput = "1ELD"; + var comp = CreateCompilationWithTasksExtensions([source, LockTypeDefinition, AsyncStreamsTypes], options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + + comp = CreateCompilationWithTasksExtensions([source, LockTypeDefinition, AsyncStreamsTypes], options: TestOptions.DebugExe); + verifier = CompileAndVerify(comp, verify: Verification.FailsILVerify, expectedOutput: expectedOutput); + verifier.VerifyDiagnostics(); + } + + [Fact] + public void Yield_Async_AroundOnly() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + + static class Program + { + static async Task Main() + { + await foreach (var x in M()) + { + Console.Write(x); + } + } + + static async IAsyncEnumerable M() + { + yield return 1; + lock (new Lock()) + { + Console.Write("L"); + } + await Task.Yield(); + yield return 2; + } + } + """; + var expectedOutput = "1ELD2"; + var comp = CreateCompilationWithTasksExtensions([source, LockTypeDefinition, AsyncStreamsTypes], options: TestOptions.DebugExe); + var verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 414 (0x19e) + .maxstack 3 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_2, + System.Runtime.CompilerServices.YieldAwaitable V_3, + Program.d__1 V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.d__1.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -5 + IL_000a: sub + IL_000b: switch ( + IL_002a, + IL_002f, + IL_0031, + IL_0038, + IL_0038, + IL_0033) + IL_0028: br.s IL_0038 + IL_002a: br IL_0125 + IL_002f: br.s IL_0065 + IL_0031: br.s IL_0038 + IL_0033: br IL_00ee + IL_0038: ldarg.0 + IL_0039: ldfld "bool Program.d__1.<>w__disposeMode" + IL_003e: brfalse.s IL_0045 + IL_0040: leave IL_0167 + IL_0045: ldarg.0 + IL_0046: ldc.i4.m1 + IL_0047: dup + IL_0048: stloc.0 + IL_0049: stfld "int Program.d__1.<>1__state" + IL_004e: nop + IL_004f: ldarg.0 + IL_0050: ldc.i4.1 + IL_0051: stfld "int Program.d__1.<>2__current" + IL_0056: ldarg.0 + IL_0057: ldc.i4.s -4 + IL_0059: dup + IL_005a: stloc.0 + IL_005b: stfld "int Program.d__1.<>1__state" + IL_0060: leave IL_0190 + IL_0065: ldarg.0 + IL_0066: ldc.i4.m1 + IL_0067: dup + IL_0068: stloc.0 + IL_0069: stfld "int Program.d__1.<>1__state" + IL_006e: ldarg.0 + IL_006f: ldfld "bool Program.d__1.<>w__disposeMode" + IL_0074: brfalse.s IL_007b + IL_0076: leave IL_0167 + IL_007b: newobj "System.Threading.Lock..ctor()" + IL_0080: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0085: stloc.1 + .try + { + IL_0086: nop + IL_0087: ldstr "L" + IL_008c: call "void System.Console.Write(string)" + IL_0091: nop + IL_0092: nop + IL_0093: leave.s IL_00a2 + } + finally + { + IL_0095: ldloc.0 + IL_0096: ldc.i4.m1 + IL_0097: bne.un.s IL_00a1 + IL_0099: ldloca.s V_1 + IL_009b: call "void System.Threading.Lock.Scope.Dispose()" + IL_00a0: nop + IL_00a1: endfinally + } + IL_00a2: ldarg.0 + IL_00a3: ldfld "bool Program.d__1.<>w__disposeMode" + IL_00a8: brfalse.s IL_00af + IL_00aa: leave IL_0167 + IL_00af: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_00b4: stloc.3 + IL_00b5: ldloca.s V_3 + IL_00b7: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_00bc: stloc.2 + IL_00bd: ldloca.s V_2 + IL_00bf: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00c4: brtrue.s IL_010a + IL_00c6: ldarg.0 + IL_00c7: ldc.i4.0 + IL_00c8: dup + IL_00c9: stloc.0 + IL_00ca: stfld "int Program.d__1.<>1__state" + IL_00cf: ldarg.0 + IL_00d0: ldloc.2 + IL_00d1: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.d__1.<>u__1" + IL_00d6: ldarg.0 + IL_00d7: stloc.s V_4 + IL_00d9: ldarg.0 + IL_00da: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_00df: ldloca.s V_2 + IL_00e1: ldloca.s V_4 + IL_00e3: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.d__1)" + IL_00e8: nop + IL_00e9: leave IL_019d + IL_00ee: ldarg.0 + IL_00ef: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.d__1.<>u__1" + IL_00f4: stloc.2 + IL_00f5: ldarg.0 + IL_00f6: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.d__1.<>u__1" + IL_00fb: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_0101: ldarg.0 + IL_0102: ldc.i4.m1 + IL_0103: dup + IL_0104: stloc.0 + IL_0105: stfld "int Program.d__1.<>1__state" + IL_010a: ldloca.s V_2 + IL_010c: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_0111: nop + IL_0112: ldarg.0 + IL_0113: ldc.i4.2 + IL_0114: stfld "int Program.d__1.<>2__current" + IL_0119: ldarg.0 + IL_011a: ldc.i4.s -5 + IL_011c: dup + IL_011d: stloc.0 + IL_011e: stfld "int Program.d__1.<>1__state" + IL_0123: leave.s IL_0190 + IL_0125: ldarg.0 + IL_0126: ldc.i4.m1 + IL_0127: dup + IL_0128: stloc.0 + IL_0129: stfld "int Program.d__1.<>1__state" + IL_012e: ldarg.0 + IL_012f: ldfld "bool Program.d__1.<>w__disposeMode" + IL_0134: brfalse.s IL_0138 + IL_0136: leave.s IL_0167 + IL_0138: leave.s IL_0167 + } + catch System.Exception + { + IL_013a: stloc.s V_5 + IL_013c: ldarg.0 + IL_013d: ldc.i4.s -2 + IL_013f: stfld "int Program.d__1.<>1__state" + IL_0144: ldarg.0 + IL_0145: ldc.i4.0 + IL_0146: stfld "int Program.d__1.<>2__current" + IL_014b: ldarg.0 + IL_014c: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_0151: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0156: nop + IL_0157: ldarg.0 + IL_0158: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_015d: ldloc.s V_5 + IL_015f: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0164: nop + IL_0165: leave.s IL_019d + } + IL_0167: ldarg.0 + IL_0168: ldc.i4.s -2 + IL_016a: stfld "int Program.d__1.<>1__state" + IL_016f: ldarg.0 + IL_0170: ldc.i4.0 + IL_0171: stfld "int Program.d__1.<>2__current" + IL_0176: ldarg.0 + IL_0177: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_017c: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0181: nop + IL_0182: ldarg.0 + IL_0183: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_0188: ldc.i4.0 + IL_0189: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_018e: nop + IL_018f: ret + IL_0190: ldarg.0 + IL_0191: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_0196: ldc.i4.1 + IL_0197: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_019c: nop + IL_019d: ret + } + """); + + comp = CreateCompilationWithTasksExtensions([source, LockTypeDefinition, AsyncStreamsTypes], options: TestOptions.ReleaseExe); + verifier = CompileAndVerify(comp, expectedOutput: expectedOutput, verify: Verification.FailsILVerify); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", """ + { + // Code size 383 (0x17f) + .maxstack 3 + .locals init (int V_0, + System.Threading.Lock.Scope V_1, + System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter V_2, + System.Runtime.CompilerServices.YieldAwaitable V_3, + Program.d__1 V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld "int Program.d__1.<>1__state" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: ldc.i4.s -5 + IL_000a: sub + IL_000b: switch ( + IL_010e, + IL_0054, + IL_0028, + IL_0028, + IL_0028, + IL_00d8) + IL_0028: ldarg.0 + IL_0029: ldfld "bool Program.d__1.<>w__disposeMode" + IL_002e: brfalse.s IL_0035 + IL_0030: leave IL_014b + IL_0035: ldarg.0 + IL_0036: ldc.i4.m1 + IL_0037: dup + IL_0038: stloc.0 + IL_0039: stfld "int Program.d__1.<>1__state" + IL_003e: ldarg.0 + IL_003f: ldc.i4.1 + IL_0040: stfld "int Program.d__1.<>2__current" + IL_0045: ldarg.0 + IL_0046: ldc.i4.s -4 + IL_0048: dup + IL_0049: stloc.0 + IL_004a: stfld "int Program.d__1.<>1__state" + IL_004f: leave IL_0172 + IL_0054: ldarg.0 + IL_0055: ldc.i4.m1 + IL_0056: dup + IL_0057: stloc.0 + IL_0058: stfld "int Program.d__1.<>1__state" + IL_005d: ldarg.0 + IL_005e: ldfld "bool Program.d__1.<>w__disposeMode" + IL_0063: brfalse.s IL_006a + IL_0065: leave IL_014b + IL_006a: newobj "System.Threading.Lock..ctor()" + IL_006f: call "System.Threading.Lock.Scope System.Threading.Lock.EnterScope()" + IL_0074: stloc.1 + .try + { + IL_0075: ldstr "L" + IL_007a: call "void System.Console.Write(string)" + IL_007f: leave.s IL_008d + } + finally + { + IL_0081: ldloc.0 + IL_0082: ldc.i4.m1 + IL_0083: bne.un.s IL_008c + IL_0085: ldloca.s V_1 + IL_0087: call "void System.Threading.Lock.Scope.Dispose()" + IL_008c: endfinally + } + IL_008d: ldarg.0 + IL_008e: ldfld "bool Program.d__1.<>w__disposeMode" + IL_0093: brfalse.s IL_009a + IL_0095: leave IL_014b + IL_009a: call "System.Runtime.CompilerServices.YieldAwaitable System.Threading.Tasks.Task.Yield()" + IL_009f: stloc.3 + IL_00a0: ldloca.s V_3 + IL_00a2: call "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter System.Runtime.CompilerServices.YieldAwaitable.GetAwaiter()" + IL_00a7: stloc.2 + IL_00a8: ldloca.s V_2 + IL_00aa: call "bool System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.IsCompleted.get" + IL_00af: brtrue.s IL_00f4 + IL_00b1: ldarg.0 + IL_00b2: ldc.i4.0 + IL_00b3: dup + IL_00b4: stloc.0 + IL_00b5: stfld "int Program.d__1.<>1__state" + IL_00ba: ldarg.0 + IL_00bb: ldloc.2 + IL_00bc: stfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.d__1.<>u__1" + IL_00c1: ldarg.0 + IL_00c2: stloc.s V_4 + IL_00c4: ldarg.0 + IL_00c5: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_00ca: ldloca.s V_2 + IL_00cc: ldloca.s V_4 + IL_00ce: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter, ref Program.d__1)" + IL_00d3: leave IL_017e + IL_00d8: ldarg.0 + IL_00d9: ldfld "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.d__1.<>u__1" + IL_00de: stloc.2 + IL_00df: ldarg.0 + IL_00e0: ldflda "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter Program.d__1.<>u__1" + IL_00e5: initobj "System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter" + IL_00eb: ldarg.0 + IL_00ec: ldc.i4.m1 + IL_00ed: dup + IL_00ee: stloc.0 + IL_00ef: stfld "int Program.d__1.<>1__state" + IL_00f4: ldloca.s V_2 + IL_00f6: call "void System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter.GetResult()" + IL_00fb: ldarg.0 + IL_00fc: ldc.i4.2 + IL_00fd: stfld "int Program.d__1.<>2__current" + IL_0102: ldarg.0 + IL_0103: ldc.i4.s -5 + IL_0105: dup + IL_0106: stloc.0 + IL_0107: stfld "int Program.d__1.<>1__state" + IL_010c: leave.s IL_0172 + IL_010e: ldarg.0 + IL_010f: ldc.i4.m1 + IL_0110: dup + IL_0111: stloc.0 + IL_0112: stfld "int Program.d__1.<>1__state" + IL_0117: ldarg.0 + IL_0118: ldfld "bool Program.d__1.<>w__disposeMode" + IL_011d: pop + IL_011e: leave.s IL_014b + } + catch System.Exception + { + IL_0120: stloc.s V_5 + IL_0122: ldarg.0 + IL_0123: ldc.i4.s -2 + IL_0125: stfld "int Program.d__1.<>1__state" + IL_012a: ldarg.0 + IL_012b: ldc.i4.0 + IL_012c: stfld "int Program.d__1.<>2__current" + IL_0131: ldarg.0 + IL_0132: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_0137: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_013c: ldarg.0 + IL_013d: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_0142: ldloc.s V_5 + IL_0144: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)" + IL_0149: leave.s IL_017e + } + IL_014b: ldarg.0 + IL_014c: ldc.i4.s -2 + IL_014e: stfld "int Program.d__1.<>1__state" + IL_0153: ldarg.0 + IL_0154: ldc.i4.0 + IL_0155: stfld "int Program.d__1.<>2__current" + IL_015a: ldarg.0 + IL_015b: ldflda "System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Program.d__1.<>t__builder" + IL_0160: call "void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()" + IL_0165: ldarg.0 + IL_0166: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_016b: ldc.i4.0 + IL_016c: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_0171: ret + IL_0172: ldarg.0 + IL_0173: ldflda "System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore Program.d__1.<>v__promiseOfValueOrEnd" + IL_0178: ldc.i4.1 + IL_0179: call "void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)" + IL_017e: ret + } + """); } [Theory, CombinatorialData] diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/OutVarTests.cs index 1c2c8c2f59050..213a94c3598ea 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/OutVarTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/OutVarTests.cs @@ -19581,9 +19581,9 @@ static void Test2(object x, System.ArgIterator y) // (11,25): error CS1601: Cannot make reference to variable of type 'ArgIterator' // static object Test1(out System.ArgIterator x) Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "out System.ArgIterator x").WithArguments("System.ArgIterator").WithLocation(11, 25), - // (8,25): error CS4012: Parameters or locals of type 'ArgIterator' cannot be declared in async methods or async lambda expressions. + // (8,25): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // Test2(Test1(out var x1), x1); - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.ArgIterator").WithLocation(8, 25), + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 25), // (6,16): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. // async void Test() Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Test").WithLocation(6, 16) @@ -19630,12 +19630,12 @@ static void Test2(object x, System.ArgIterator y) // (12,25): error CS1601: Cannot make reference to variable of type 'ArgIterator' // static object Test1(out System.ArgIterator x) Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "out System.ArgIterator x").WithArguments("System.ArgIterator").WithLocation(12, 25), - // (8,25): error CS4012: Parameters or locals of type 'ArgIterator' cannot be declared in async methods or async lambda expressions. + // (8,25): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // Test2(Test1(out System.ArgIterator x1), x1); - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "System.ArgIterator").WithArguments("System.ArgIterator").WithLocation(8, 25), - // (9,9): error CS4012: Parameters or locals of type 'ArgIterator' cannot be declared in async methods or async lambda expressions. + Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.ArgIterator").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 25), + // (9,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // var x = default(System.ArgIterator); - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.ArgIterator").WithLocation(9, 9), + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 9), // (9,13): warning CS0219: The variable 'x' is assigned but its value is never used // var x = default(System.ArgIterator); Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x").WithArguments("x").WithLocation(9, 13), diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/ParamsCollectionTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/ParamsCollectionTests.cs index 472585b36a149..99c3c6be72c5c 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/ParamsCollectionTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/ParamsCollectionTests.cs @@ -359,6 +359,85 @@ void assertAttributeData(string name) } } + [Fact] + public void Span_SingleElement_TempsAreNotReused() + { + var source = """ + using System; + + class Program + { + static void Main() + { + M(1); + M(2); + } + + static void M(params Span span) + { + Console.Write(span[0]); + Console.Write(span.Length); + } + } + """; + + var verifier = CompileAndVerify( + source, + targetFramework: TargetFramework.Net80, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped, + expectedOutput: ExpectedOutput("1121")); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.Main", """ + { + // Code size 29 (0x1d) + .maxstack 1 + .locals init (int V_0, + int V_1) + IL_0000: ldc.i4.1 + IL_0001: stloc.0 + IL_0002: ldloca.s V_0 + IL_0004: newobj "System.Span..ctor(ref int)" + IL_0009: call "void Program.M(params System.Span)" + IL_000e: ldc.i4.2 + IL_000f: stloc.1 + IL_0010: ldloca.s V_1 + IL_0012: newobj "System.Span..ctor(ref int)" + IL_0017: call "void Program.M(params System.Span)" + IL_001c: ret + } + """); + + verifier = CompileAndVerify( + source, + targetFramework: TargetFramework.Net70, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped, + expectedOutput: ExpectedOutput("1121")); + verifier.VerifyDiagnostics(); + verifier.VerifyIL("Program.Main", """ + { + // Code size 41 (0x29) + .maxstack 4 + IL_0000: ldc.i4.1 + IL_0001: newarr "int" + IL_0006: dup + IL_0007: ldc.i4.0 + IL_0008: ldc.i4.1 + IL_0009: stelem.i4 + IL_000a: newobj "System.Span..ctor(int[])" + IL_000f: call "void Program.M(params System.Span)" + IL_0014: ldc.i4.1 + IL_0015: newarr "int" + IL_001a: dup + IL_001b: ldc.i4.0 + IL_001c: ldc.i4.2 + IL_001d: stelem.i4 + IL_001e: newobj "System.Span..ctor(int[])" + IL_0023: call "void Program.M(params System.Span)" + IL_0028: ret + } + """); + } + [Fact] public void String() { @@ -4633,6 +4712,58 @@ static void Main() ); } + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73242")] + public void DelegateNaturalType_07() + { + var src = @" +class Helper + where T : System.Collections.Generic.List, new() +{ + static public void Test3(params T a) { System.Console.WriteLine("" {0}"", a is not null); } +} + +class Program +{ + static void Main() + { + DoTest3>(); + } + static void DoTest3() + where T : System.Collections.Generic.List, new() + { + var a3 = Helper.Test3; + M(a3)(); + } + + static T M(T t) { System.Console.WriteLine(typeof(T)); return t; } +} +"; + var comp = CreateCompilation(src, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + symbolValidator: (m) => + { + var delegateType = m.ContainingAssembly.GetTypeByMetadataName("<>f__AnonymousDelegate0`1"); + MethodSymbol delegateInvokeMethod = delegateType.DelegateInvokeMethod; + AssertEx.Equal("void <>f__AnonymousDelegate0.Invoke(params T1 arg)", delegateInvokeMethod.ToTestDisplayString()); + + // Strictly speaking it is a violation of language rules to decorate this parameter with ParamCollectionAttribute + // because it lacks constraints that would make it a valid 'params' type + // However, going through the trouble of porting constraints and differentiating/merging anonymous delegates based on them + // is probably not worth the trouble for this edge scenario. + // The types involved might be inaccessible on assembly level, etc. + VerifyParamsAndAttribute(delegateInvokeMethod.Parameters[0], isParamArray: false, isParamCollection: true); + Assert.False(delegateType.TypeParameters[0].HasConstructorConstraint); + Assert.Empty(delegateType.TypeParameters[0].ConstraintTypesNoUseSiteDiagnostics); + }, + expectedOutput: ExpectedOutput(@" +<>f__AnonymousDelegate0`1[System.Collections.Generic.List`1[System.Int64]] + True +")).VerifyDiagnostics(); + } + [Fact] public void BetterNess_01_ElementType() { @@ -4663,9 +4794,7 @@ static void Test(params System.Span a) CompileAndVerify( comp, - verify: ExecutionConditionUtil.IsMonoOrCoreClr ? - Verification.FailsILVerify with { ILVerifyMessage = "[InlineArrayAsSpan]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0xc }" } - : Verification.Skipped, + verify: Verification.Skipped, expectedOutput: ExpectedOutput(@" int int")).VerifyDiagnostics(); @@ -4703,9 +4832,7 @@ class C3 : C2 {} CompileAndVerify( comp, - verify: ExecutionConditionUtil.IsMonoOrCoreClr ? - Verification.FailsILVerify with { ILVerifyMessage = "[InlineArrayAsSpan]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0xc }" } - : Verification.Skipped, + verify: Verification.Skipped, expectedOutput: ExpectedOutput(@" C2 C2")).VerifyDiagnostics(); @@ -5919,7 +6046,6 @@ static void Main() Test(d, 2, 3); Test(2, d, 3); Test(2, 3, d); - Test(d, [3, 4]); Test2(d, d); Test2(d, 1); @@ -5933,7 +6059,6 @@ static void Main() Test2(d, 2, 3); Test2(2, d, 3); Test2(2, 3, d); - Test2(d, [3, 4]); } static void Test(int a, params IEnumerable b) @@ -5949,9 +6074,23 @@ static void Test2(int a, params T[] b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"CalledCalledCalledCalledCalledCalledCalled2Called2Called2Called2Called2Called2Called2Called2Called2Called2Called2Called2").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), + // (9,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(d, 1); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 1)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(9, 9), + // (10,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 2, 3)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(10, 9), + // (11,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(2, d, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(2, d, 3)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(11, 9), + // (12,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(2, 3, d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(2, 3, d)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(12, 9) + ); } [Fact] @@ -6062,7 +6201,7 @@ static void Main() var comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); var expected = new[] { - // (8,9): warning CS9220: One or more overloads of method 'Test1' having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. + // (8,9): warning CS9220: One or more overloads of method 'Test1' having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // Test1(d1); // Called2 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod, "Test1(d1)").WithArguments("Test1").WithLocation(8, 9), // (11,9): warning CS9220: One or more overloads of method 'Test1' having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. @@ -6077,6 +6216,9 @@ static void Main() // (20,9): warning CS9220: One or more overloads of method 'Test3' having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // Test3(d3, 1, 2); // Called7 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod, "Test3(d3, 1, 2)").WithArguments("Test3").WithLocation(20, 9), + // (21,9): error CS9218: 'Helpers.Test3(byte, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test3(d3, x, x); // Called6 + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test3(d3, x, x)").WithArguments("Helpers.Test3(byte, params System.Collections.Generic.IEnumerable)").WithLocation(21, 9), // (25,9): warning CS9220: One or more overloads of method 'Test4' having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // Test4(d3, x, x); // Called9 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod, "Test4(d3, x, x)").WithArguments("Test4").WithLocation(25, 9), @@ -6085,16 +6227,10 @@ static void Main() Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionMethod, "Test4(d3, d4, d4)").WithArguments("Test4").WithLocation(26, 9) }; - CompileAndVerify( - comp, - expectedOutput: @"Called2Called1Called3Called5Called3Called4Called7Called6Called8Called9Called9"). - VerifyDiagnostics(expected); + comp.VerifyDiagnostics(expected); comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext); - CompileAndVerify( - comp, - expectedOutput: @"Called2Called1Called3Called5Called3Called4Called7Called6Called8Called9Called9"). - VerifyDiagnostics(expected); + comp.VerifyDiagnostics(expected); comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12); comp.VerifyDiagnostics( @@ -6167,9 +6303,11 @@ static void Test(int a, System.DateTime b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called True").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(d, 2); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 2)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6194,9 +6332,11 @@ static void Test(params IEnumerable b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 2, 3)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6230,23 +6370,23 @@ static void Main() var comp1 = CreateCompilation(src1, references: [comp0Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); comp1.VerifyDiagnostics( - // (8,9): error CS9218: The type arguments for method 'Program.Test(params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + // (8,9): error CS9218: 'Program.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. // Test(d, 2, 3); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(d, 2, 3)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), - // (9,9): error CS9218: The type arguments for method 'Program.Test(params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 2, 3)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), + // (9,14): error CS9219: Ambiguity between expanded and normal forms of non-array params collection parameter of 'Program.Test(params IEnumerable)', the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument. // Test(d); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(d)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(9, 9) + Diagnostic(ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, "d").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(9, 14) ); comp1 = CreateCompilation(src1, references: [comp0Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext); comp1.VerifyDiagnostics( - // (8,9): error CS9218: The type arguments for method 'Program.Test(params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + // (8,9): error CS9218: 'Program.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. // Test(d, 2, 3); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(d, 2, 3)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), - // (9,9): error CS9218: The type arguments for method 'Program.Test(params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 2, 3)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), + // (9,14): error CS9219: Ambiguity between expanded and normal forms of non-array params collection parameter of 'Program.Test(params IEnumerable)', the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument. // Test(d); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(d)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(9, 9) + Diagnostic(ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, "d").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(9, 14) ); comp1 = CreateCompilation(src1, references: [comp0Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12); @@ -6276,9 +6416,11 @@ static void Test(params IEnumerable b) """; var comp2 = CreateCompilation(src2, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp2, - expectedOutput: @"Called").VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(d, 2, 3)").WithArguments("Program.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6312,23 +6454,23 @@ static void Main() var comp1 = CreateCompilation(src1, references: [comp0Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); comp1.VerifyDiagnostics( - // (8,9): error CS9218: The type arguments for method 'Program.Test(T, params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + // (8,9): error CS9218: 'Program.Test(T, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. // Test(0, d, 2, 3); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(0, d, 2, 3)").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), - // (9,9): error CS9218: The type arguments for method 'Program.Test(T, params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(0, d, 2, 3)").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), + // (9,17): error CS9219: Ambiguity between expanded and normal forms of non-array params collection parameter of 'Program.Test(T, params IEnumerable)', the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument. // Test(0, d); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(0, d)").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(9, 9) + Diagnostic(ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, "d").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(9, 17) ); comp1 = CreateCompilation(src1, references: [comp0Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext); comp1.VerifyDiagnostics( - // (8,9): error CS9218: The type arguments for method 'Program.Test(T, params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + // (8,9): error CS9218: 'Program.Test(T, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. // Test(0, d, 2, 3); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(0, d, 2, 3)").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), - // (9,9): error CS9218: The type arguments for method 'Program.Test(T, params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(0, d, 2, 3)").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), + // (9,17): error CS9219: Ambiguity between expanded and normal forms of non-array params collection parameter of 'Program.Test(T, params IEnumerable)', the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument. // Test(0, d); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(0, d)").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(9, 9) + Diagnostic(ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, "d").WithArguments("Program.Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(9, 17) ); comp1 = CreateCompilation(src1, references: [comp0Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12); @@ -6358,9 +6500,11 @@ static void Test(T a, params IEnumerable b) """; var comp2 = CreateCompilation(src2, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp2, - expectedOutput: @"Called").VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // Test(0, d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "Test(0, d, 2, 3)").WithArguments("Program.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6393,9 +6537,11 @@ public override void Test(params IEnumerable b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'C1.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new C2().Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C2().Test(d, 2, 3)").WithArguments("C1.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6428,9 +6574,11 @@ class C2 : C1 """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'C2.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new C2().Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C2().Test(d, 2, 3)").WithArguments("C2.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6468,9 +6616,11 @@ class C2 : C1 """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'C2.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new C2().Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C2().Test(d, 2, 3)").WithArguments("C2.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6508,9 +6658,11 @@ public override void Test(params IEnumerable b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'C2.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new C3().Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C3().Test(d, 2, 3)").WithArguments("C2.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -6735,9 +6887,9 @@ static void Test(params IEnumerable b) var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe); comp.VerifyDiagnostics( - // (8,14): error CS9219: Ambiguity between expanded and normal forms of non-array params collection parameter of 'Test(params IEnumerable)', the only corresponding argument has the type 'dynamic'. Consider casting the dynamic argument. + // (8,14): error CS8108: Cannot pass argument with dynamic type to params parameter 'b' of local function 'Test'. // Test(d); - Diagnostic(ErrorCode.ERR_ParamsCollectionAmbiguousDynamicArgument, "d").WithArguments("Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 14) + Diagnostic(ErrorCode.ERR_DynamicLocalFunctionParamsParameter, "d").WithArguments("b", "Test").WithLocation(8, 14) ); } @@ -6764,9 +6916,9 @@ void Test(params IEnumerable b) var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); comp1.VerifyDiagnostics( - // (8,9): error CS9218: The type arguments for method 'Test(params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + // (8,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'Test' with inferred type arguments. // Test(d, 2, 3); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(d, 2, 3)").WithArguments("Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "Test(d, 2, 3)").WithArguments("Test").WithLocation(8, 9) ); var src2 = """ @@ -6816,9 +6968,9 @@ void Test(T a, params IEnumerable b) var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); comp1.VerifyDiagnostics( - // (8,9): error CS9218: The type arguments for method 'Test(T, params IEnumerable)' cannot be inferred from the usage because an argument with dynamic type is used and the method has a non-array params collection parameter. Try specifying the type arguments explicitly. + // (8,9): error CS8322: Cannot pass argument with dynamic type to generic local function 'Test' with inferred type arguments. // Test(0, d, 2, 3); - Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs_DynamicArgumentWithParamsCollections, "Test(0, d, 2, 3)").WithArguments("Test(T, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + Diagnostic(ErrorCode.ERR_DynamicLocalFunctionTypeParameter, "Test(0, d, 2, 3)").WithArguments("Test").WithLocation(8, 9) ); var src2 = """ @@ -6871,7 +7023,6 @@ static void Main() test2(d, 2, 3); test2(2, d, 3); test2(2, 3, d); - test2(d, [3, 4]); void Test(int a, IEnumerable b) { @@ -6889,9 +7040,23 @@ void Test2(int a, int[] b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"CalledCalledCalledCalledCalledCalledCalled2Called2Called2Called2Called2Called2Called2").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (9,9): error CS9218: 'D.Invoke(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // test(d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "test(d)").WithArguments("D.Invoke(int, params System.Collections.Generic.IEnumerable)").WithLocation(9, 9), + // (10,9): error CS9218: 'D.Invoke(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // test(d, 1); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "test(d, 1)").WithArguments("D.Invoke(int, params System.Collections.Generic.IEnumerable)").WithLocation(10, 9), + // (11,9): error CS9218: 'D.Invoke(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "test(d, 2, 3)").WithArguments("D.Invoke(int, params System.Collections.Generic.IEnumerable)").WithLocation(11, 9), + // (12,9): error CS9218: 'D.Invoke(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // test(2, d, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "test(2, d, 3)").WithArguments("D.Invoke(int, params System.Collections.Generic.IEnumerable)").WithLocation(12, 9), + // (13,9): error CS9218: 'D.Invoke(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // test(2, 3, d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "test(2, 3, d)").WithArguments("D.Invoke(int, params System.Collections.Generic.IEnumerable)").WithLocation(13, 9) + ); } [Fact] @@ -6960,7 +7125,6 @@ static void Main() _ = c1[d, 2, 3]; _ = c1[2, d, 3]; _ = c1[2, 3, d]; - _ = c1[d, [3, 4]]; var c2 = new C2(); @@ -6970,7 +7134,6 @@ static void Main() _ = c2[d, 2, 3]; _ = c2[2, d, 3]; _ = c2[2, 3, d]; - _ = c2[d, [3, 4]]; } } @@ -6999,9 +7162,23 @@ class C2 """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"CalledCalledCalledCalledCalledCalledCalled2Called2Called2Called2Called2Called2Called2").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (9,13): error CS9218: 'C1.this[int, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = c1[d]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "c1[d]").WithArguments("C1.this[int, params System.Collections.Generic.IEnumerable]").WithLocation(9, 13), + // (10,13): error CS9218: 'C1.this[int, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = c1[d, 1]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "c1[d, 1]").WithArguments("C1.this[int, params System.Collections.Generic.IEnumerable]").WithLocation(10, 13), + // (11,13): error CS9218: 'C1.this[int, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = c1[d, 2, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "c1[d, 2, 3]").WithArguments("C1.this[int, params System.Collections.Generic.IEnumerable]").WithLocation(11, 13), + // (12,13): error CS9218: 'C1.this[int, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = c1[2, d, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "c1[2, d, 3]").WithArguments("C1.this[int, params System.Collections.Generic.IEnumerable]").WithLocation(12, 13), + // (13,13): error CS9218: 'C1.this[int, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = c1[2, 3, d]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "c1[2, 3, d]").WithArguments("C1.this[int, params System.Collections.Generic.IEnumerable]").WithLocation(13, 13) + ); } [Fact] @@ -7131,6 +7308,9 @@ static void Main() // (18,13): warning CS9221: One or more indexer overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // _ = new Test3()[d3, 1, 2]; // Called7 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionIndexer, "new Test3()[d3, 1, 2]").WithLocation(18, 13), + // (19,13): error CS9218: 'Test3.this[byte, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new Test3()[d3, x, x]; // Called6 + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test3()[d3, x, x]").WithArguments("Test3.this[byte, params System.Collections.Generic.IEnumerable]").WithLocation(19, 13), // (23,13): warning CS9221: One or more indexer overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // _ = new Test4()[d3, x, x]; // Called9 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionIndexer, "new Test4()[d3, x, x]").WithLocation(23, 13), @@ -7139,16 +7319,10 @@ static void Main() Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionIndexer, "new Test4()[d3, d4, d4]").WithLocation(24, 13) }; - CompileAndVerify( - comp, - expectedOutput: @"Called2Called1Called3Called5Called3Called4Called7Called6Called8Called9Called9"). - VerifyDiagnostics(expected); + comp.VerifyDiagnostics(expected); comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext); - CompileAndVerify( - comp, - expectedOutput: @"Called2Called1Called3Called5Called3Called4Called7Called6Called8Called9Called9"). - VerifyDiagnostics(expected); + comp.VerifyDiagnostics(expected); comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12); comp.VerifyDiagnostics( @@ -7221,9 +7395,11 @@ static void Main() """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called True").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,13): error CS9218: 'Program.this[int, params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new Program()[d, 2]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Program()[d, 2]").WithArguments("Program.this[int, params System.Collections.Generic.IEnumerable]").WithLocation(8, 13) + ); } [Fact] @@ -7252,9 +7428,11 @@ int this[params IEnumerable b] """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,13): error CS9218: 'Program.this[params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new Program()[d, 2, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Program()[d, 2, 3]").WithArguments("Program.this[params System.Collections.Generic.IEnumerable]").WithLocation(8, 13) + ); } [Fact] @@ -7291,9 +7469,11 @@ public override T this[params IEnumerable b] """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,13): error CS9218: 'C1.this[params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new C2()[d, 2, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C2()[d, 2, 3]").WithArguments("C1.this[params System.Collections.Generic.IEnumerable]").WithLocation(8, 13) + ); } [Fact] @@ -7330,9 +7510,11 @@ class C2 : C1 """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,13): error CS9218: 'C2.this[params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new C2()[d, 2, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C2()[d, 2, 3]").WithArguments("C2.this[params System.Collections.Generic.IEnumerable]").WithLocation(8, 13) + ); } [Fact] @@ -7374,9 +7556,11 @@ class C2 : C1 """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,13): error CS9218: 'C2.this[params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new C2()[d, 2, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C2()[d, 2, 3]").WithArguments("C2.this[params System.Collections.Generic.IEnumerable]").WithLocation(8, 13) + ); } [Fact] @@ -7418,9 +7602,11 @@ public override T this[params IEnumerable b] """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,13): error CS9218: 'C2.this[params IEnumerable]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // _ = new C3()[d, 2, 3]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new C3()[d, 2, 3]").WithArguments("C2.this[params System.Collections.Generic.IEnumerable]").WithLocation(8, 13) + ); } [Fact] @@ -7605,9 +7791,29 @@ public Test2(int a, params int[] b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"CalledCalledCalledCalledCalledCalledCalled2Called2Called2Called2Called2Called2Called2").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(d)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9), + // (9,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(d, 1); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(d, 1)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(9, 9), + // (10,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(d, 2, 3)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(10, 9), + // (11,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(2, d, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(2, d, 3)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(11, 9), + // (12,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(2, 3, d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(2, 3, d)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(12, 9), + // (13,21): error CS9176: There is no target type for the collection expression. + // new Test(d, [3, 4]); + Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[3, 4]").WithLocation(13, 21), + // (21,22): error CS9176: There is no target type for the collection expression. + // new Test2(d, [3, 4]); + Diagnostic(ErrorCode.ERR_CollectionExpressionNoTargetType, "[3, 4]").WithLocation(21, 22) + ); } [Fact] @@ -7739,6 +7945,9 @@ static void Main() // (18,9): warning CS9222: One or more constructor overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // new Test3(d3, 1, 2); // Called7 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor, "new Test3(d3, 1, 2)").WithLocation(18, 9), + // (19,9): error CS9218: 'Test3.Test3(byte, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test3(d3, x, x); // Called6 + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test3(d3, x, x)").WithArguments("Test3.Test3(byte, params System.Collections.Generic.IEnumerable)").WithLocation(19, 9), // (23,9): warning CS9222: One or more constructor overloads having non-array params collection parameter might be applicable only in expanded form which is not supported during dynamic dispatch. // new Test4(d3, x, x); // Called9 Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor, "new Test4(d3, x, x)").WithLocation(23, 9), @@ -7747,16 +7956,10 @@ static void Main() Diagnostic(ErrorCode.WRN_DynamicDispatchToParamsCollectionConstructor, "new Test4(d3, d4, d4)").WithLocation(24, 9) }; - CompileAndVerify( - comp, - expectedOutput: @"Called2Called1Called3Called5Called3Called4Called7Called6Called8Called9Called9"). - VerifyDiagnostics(expected); + comp.VerifyDiagnostics(expected); comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext); - CompileAndVerify( - comp, - expectedOutput: @"Called2Called1Called3Called5Called3Called4Called7Called6Called8Called9Called9"). - VerifyDiagnostics(expected); + comp.VerifyDiagnostics(expected); comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12); comp.VerifyDiagnostics( @@ -7831,9 +8034,11 @@ public Test(int a, System.DateTime b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called True").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(d, 2); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(d, 2)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -7861,9 +8066,11 @@ public Test(params IEnumerable b) """; var comp = CreateCompilation(src, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - CompileAndVerify( - comp, - expectedOutput: @"Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS9218: 'Program.Test.Test(params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(d, 2, 3); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(d, 2, 3)").WithArguments("Program.Test.Test(params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) + ); } [Fact] @@ -7931,7 +8138,10 @@ public Test(int a, params IEnumerable b) comp.VerifyDiagnostics( // (8,9): error CS0144: Cannot create an instance of the abstract type or interface 'Program.Test' // new Test(d); - Diagnostic(ErrorCode.ERR_NoNewAbstract, "new Test(d)").WithArguments("Program.Test").WithLocation(8, 9) + Diagnostic(ErrorCode.ERR_NoNewAbstract, "new Test(d)").WithArguments("Program.Test").WithLocation(8, 9), + // (8,9): error CS9218: 'Program.Test.Test(int, params IEnumerable)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // new Test(d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, "new Test(d)").WithArguments("Program.Test.Test(int, params System.Collections.Generic.IEnumerable)").WithLocation(8, 9) ); } @@ -15492,5 +15702,117 @@ static void Main() Diagnostic(ErrorCode.ERR_BadArgType, "x").WithArguments("1", "int", "params MyCollection").WithLocation(19, 14) ); } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73346")] + public void ParameterTypeSpecificity_01() + { + string source = """ +using System; + +namespace OverloadResolutionRepro +{ + public class C + { + public void Method(params Func[] projections) => Console.Write(1); + public void Method(params Func>[] projections) => Console.Write(2); + } + + public class Bar + { + public Wrapper WrappedValue { get; set; } = new Wrapper(); + } + + public struct Wrapper + { + } + + public class EntryPoint + { + static void Main() + { + new C().Method(x => x.WrappedValue); + } + } +} +"""; + var comp = CreateCompilation(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73346")] + public void ParameterTypeSpecificity_02() + { + string source = """ +using System; + +namespace OverloadResolutionRepro +{ + public class C + { + public C(params Func[] projections) => Console.Write(1); + public C(params Func>[] projections) => Console.Write(2); + } + + public class Bar + { + public Wrapper WrappedValue { get; set; } = new Wrapper(); + } + + public struct Wrapper + { + } + + public class EntryPoint + { + static void Main() + { + new C>(x => x.WrappedValue); + } + } +} +"""; + var comp = CreateCompilation(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73346")] + public void ParameterTypeSpecificity_03() + { + string source = """ +using System; +using System.Collections.Generic; + +namespace OverloadResolutionRepro +{ + public class C + { + public void Method(params IEnumerable> projections) => Console.Write(1); + public void Method(params IEnumerable>> projections) => Console.Write(2); + } + + public class Bar + { + public Wrapper WrappedValue { get; set; } = new Wrapper(); + } + + public struct Wrapper + { + } + + public class EntryPoint + { + static void Main() + { + new C().Method(x => x.WrappedValue); + } + } +} +"""; + var comp = CreateCompilation(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + } } } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/RefReadonlyParameterTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/RefReadonlyParameterTests.cs index 43b3ff8f5f371..444acde22d8ec 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/RefReadonlyParameterTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/RefReadonlyParameterTests.cs @@ -613,7 +613,7 @@ class B : System.Attribute // (1,2): error CS8358: Cannot use attribute constructor 'A.A(ref readonly int)' because it has 'in' or 'ref readonly' parameters. // [A(1)] Diagnostic(ErrorCode.ERR_AttributeCtorInParameter, "A(1)").WithArguments("A.A(ref readonly int)").WithLocation(1, 2), - // (1,4): warning CS9504: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter + // (1,4): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter // [A(1)] Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "1").WithArguments("1").WithLocation(1, 4), // (7,2): error CS8358: Cannot use attribute constructor 'B.B(ref readonly int)' because it has 'in' or 'ref readonly' parameters. @@ -801,10 +801,10 @@ static class C } """; CompileAndVerify(source, expectedOutput: "4445").VerifyDiagnostics( - // (6,20): warning CS9503: Argument 1 should be passed with 'ref' or 'in' keyword + // (6,20): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword // C.E((int p) => C.M(p)); Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "p").WithArguments("1").WithLocation(6, 20), - // (7,20): warning CS9504: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter + // (7,20): warning CS9193: Argument 1 should be a variable because it is passed to a 'ref readonly' parameter // C.E((int p) => C.M(5)); Diagnostic(ErrorCode.WRN_RefReadonlyNotVariable, "5").WithArguments("1").WithLocation(7, 20)); } @@ -4906,7 +4906,7 @@ void M2(int x) modifier == "" ? new[] { - // (6,11): warning CS9503: Argument 1 should be passed with 'ref' or 'in' keyword + // (6,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword // M(x); Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "x").WithArguments("1").WithLocation(6, 11) } @@ -5704,42 +5704,45 @@ static void Main() void M2(dynamic p) => M(p); } """; - var verifier = CompileAndVerify(source, targetFramework: TargetFramework.StandardAndCSharp, expectedOutput: "12"); + var verifier = CompileAndVerify(source, targetFramework: TargetFramework.StandardAndCSharp, expectedOutput: "exception2"); - verifier.VerifyDiagnostics( - // (10,17): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword - // c.M(d); - Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "d").WithArguments("1").WithLocation(10, 17), - // (21,29): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword - // void M2(dynamic p) => M(p); - Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "p").WithArguments("1").WithLocation(21, 29) - ); + verifier.VerifyDiagnostics(); verifier.VerifyIL("C.M2", """ { - // Code size 74 (0x4a) - .maxstack 4 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" - IL_0006: brtrue.s IL_002c - IL_0008: ldc.i4.0 - IL_0009: ldtoken "int" - IL_000e: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0013: ldtoken "C" - IL_0018: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_001d: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_0022: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0027: stsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" - IL_002c: ldsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" - IL_0031: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_0036: ldsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" - IL_003b: ldarg.1 - IL_003c: callvirt "int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_0041: stloc.0 - IL_0042: ldloca.s V_0 - IL_0044: call "void C.M(ref readonly int)" - IL_0049: ret + // Code size 92 (0x5c) + .maxstack 9 + IL_0000: ldsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" + IL_0005: brtrue.s IL_0045 + IL_0007: ldc.i4 0x102 + IL_000c: ldstr "M" + IL_0011: ldnull + IL_0012: ldtoken "C" + IL_0017: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" + IL_001c: ldc.i4.2 + IL_001d: newarr "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" + IL_0022: dup + IL_0023: ldc.i4.0 + IL_0024: ldc.i4.1 + IL_0025: ldnull + IL_0026: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_002b: stelem.ref + IL_002c: dup + IL_002d: ldc.i4.1 + IL_002e: ldc.i4.0 + IL_002f: ldnull + IL_0030: call "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)" + IL_0035: stelem.ref + IL_0036: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)" + IL_003b: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" + IL_0040: stsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" + IL_0045: ldsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" + IL_004a: ldfld "System.Action System.Runtime.CompilerServices.CallSite>.Target" + IL_004f: ldsfld "System.Runtime.CompilerServices.CallSite> C.<>o__2.<>p__0" + IL_0054: ldarg.0 + IL_0055: ldarg.1 + IL_0056: callvirt "void System.Action.Invoke(System.Runtime.CompilerServices.CallSite, C, dynamic)" + IL_005b: ret } """); } diff --git a/src/Compilers/CSharp/Test/Emit3/Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj b/src/Compilers/CSharp/Test/Emit3/Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj index 3276fae69d6c0..a5058e4b017cf 100644 --- a/src/Compilers/CSharp/Test/Emit3/Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj +++ b/src/Compilers/CSharp/Test/Emit3/Microsoft.CodeAnalysis.CSharp.Emit3.UnitTests.csproj @@ -4,7 +4,7 @@ Library Microsoft.CodeAnalysis.CSharp.UnitTests - $(NetRoslyn);net472 + $(NetRoslynNext);net472 true @@ -27,6 +27,7 @@ + diff --git a/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs b/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs new file mode 100644 index 0000000000000..88487d7c94dac --- /dev/null +++ b/src/Compilers/CSharp/Test/Emit3/RefStructInterfacesTests.cs @@ -0,0 +1,27510 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Linq; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +#nullable disable + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + public class RefStructInterfacesTests : CSharpTestBase + { + private static readonly TargetFramework s_targetFrameworkSupportingByRefLikeGenerics = TargetFramework.Net90; + + [Theory] + [CombinatorialData] + public void UnscopedRefInInterface_Method_01(bool isVirtual) + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + " + (isVirtual ? "virtual " : "") + @" ref int M()" + (isVirtual ? " => throw null" : "") + @"; +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr || !isVirtual ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.True(m.GlobalNamespace.GetMember("I.M").HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(6, 6) + ); + } + + [Fact] + public void UnscopedRefInInterface_Method_02() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + ref int M() + { + throw null; + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.True(m.GlobalNamespace.GetMember("I.M").HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(6, 6) + ); + } + + [Fact] + public void UnscopedRefInInterface_Method_03() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + sealed ref int M() + { + throw null; + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + + Assert.False(comp.GetMember("I.M").HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Method_04() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + abstract static ref int M(); +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + + Assert.False(comp.GetMember("I.M").HasUnscopedRefAttribute); + } + + [Theory] + [CombinatorialData] + public void UnscopedRefInInterface_Property_01(bool isVirtual) + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + " + (isVirtual ? "virtual " : "") + @" ref int P { get" + (isVirtual ? " => throw null" : "") + @"; } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr || !isVirtual ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I.P"); + Assert.True(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(6, 6) + ); + } + + [Fact] + public void UnscopedRefInInterface_Property_02() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + ref int P => throw null; +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I.P"); + Assert.True(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(6, 6) + ); + } + + [Fact] + public void UnscopedRefInInterface_Property_03() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + sealed ref int P => throw null; +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + + PropertySymbol propertySymbol = comp.GetMember("I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Property_04() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + abstract static ref int P { get; } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + + PropertySymbol propertySymbol = comp.GetMember("I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Property_05() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + ref int P + { + [UnscopedRef] + get; + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.True(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(8, 10) + ); + } + + [Fact] + public void UnscopedRefInInterface_Property_06() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + ref int P + { + [UnscopedRef] + get + { + throw null; + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.True(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(8, 10) + ); + } + + [Fact] + public void UnscopedRefInInterface_Property_07() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + sealed ref int P + { + [UnscopedRef] + get + { + throw null; + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (8,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 10) + ); + + PropertySymbol propertySymbol = comp.GetMember("I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Property_08() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + abstract static ref int P + { + [UnscopedRef] + get; + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (8,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 10) + ); + + PropertySymbol propertySymbol = comp.GetMember("I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Theory] + [CombinatorialData] + public void UnscopedRefInInterface_Indexer_01(bool isVirtual) + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + " + (isVirtual ? "virtual " : "") + @" ref int this[int i] { get" + (isVirtual ? " => throw null" : "") + @"; } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr || !isVirtual ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.True(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(6, 6) + ); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_02() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + ref int this[int i] => throw null; +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.True(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(6, 6) + ); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_03() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + sealed ref int this[int i] => throw null; +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + + PropertySymbol propertySymbol = comp.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_04() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + abstract static ref int this[int i] { get; } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (7,29): error CS0106: The modifier 'static' is not valid for this item + // abstract static ref int this[int i] { get; } + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(7, 29) + ); + + PropertySymbol propertySymbol = comp.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.IsStatic); + Assert.True(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_05() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + ref int this[int i] + { + [UnscopedRef] + get; + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.True(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(8, 10) + ); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_06() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + ref int this[int i] + { + [UnscopedRef] + get + { + throw null; + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.True(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(8, 10) + ); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_07() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + sealed ref int this[int i] + { + [UnscopedRef] + get + { + throw null; + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (8,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 10) + ); + + PropertySymbol propertySymbol = comp.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInInterface_Indexer_08() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + abstract static ref int this[int i] + { + [UnscopedRef] + get; + } +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net80); + + comp.VerifyDiagnostics( + // (6,29): error CS0106: The modifier 'static' is not valid for this item + // abstract static ref int this[int i] + Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(6, 29) + ); + + PropertySymbol propertySymbol = comp.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.IsStatic); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.True(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + [Fact] + public void UnscopedRefInImplementation_Method_01() + { + var src1 = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + [UnscopedRef] + ref int M(); +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.Net80); + MetadataReference[] comp1Refs = [comp1.EmitToImageReference(), comp1.ToMetadataReference()]; + + var src2 = @" +using System.Diagnostics.CodeAnalysis; + +class C : I +{ + [UnscopedRef] + public ref int M() + { + throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp2 = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp2.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + Assert.False(comp2.GetMember("C.M").HasUnscopedRefAttribute); + } + + var src3 = @" +using System.Diagnostics.CodeAnalysis; + +class C : I +{ + [UnscopedRef] + ref int I.M() + { + throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp3 = CreateCompilation(src3, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp3.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + Assert.False(comp3.GetMember("C.I.M").HasUnscopedRefAttribute); + } + + var src4 = @" +class C1 : I +{ + int f = 0; + public ref int M() + { + return ref f; + } +} + +class C2 : I +{ + int f = 0; + ref int I.M() + { + return ref f; + } +} + +class C3 +{ + int f = 0; + public ref int M() + { + return ref f; + } +} + +class C4 : C3, I {} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp4 = CreateCompilation(src4, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp4, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.False(m.GlobalNamespace.GetMember("C1.M").HasUnscopedRefAttribute); + Assert.False(m.GlobalNamespace.GetMember("C2.I.M").HasUnscopedRefAttribute); + Assert.False(m.GlobalNamespace.GetMember("C3.M").HasUnscopedRefAttribute); + } + } + + var src5 = @" +using System.Diagnostics.CodeAnalysis; + +interface C : I +{ + [UnscopedRef] + ref int I.M() + { + throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp5 = CreateCompilation(src5, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp5.VerifyDiagnostics( + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6) + ); + Assert.False(comp5.GetMember("C.I.M").HasUnscopedRefAttribute); + } + + var src6 = @" +interface C : I +{ + ref int I.M() + { + throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp6 = CreateCompilation(src6, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp6, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.False(m.GlobalNamespace.GetMember("C.I.M").HasUnscopedRefAttribute); + } + } + + var src7 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + [UnscopedRef] + public ref int M() + { + return ref f; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp7, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.True(m.GlobalNamespace.GetMember("C.M").HasUnscopedRefAttribute); + } + + CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(8, 6) + ); + } + + var src8 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + [UnscopedRef] + ref int I.M() + { + return ref f; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp8, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.True(m.GlobalNamespace.GetMember("C.I.M").HasUnscopedRefAttribute); + } + + CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(8, 6) + ); + } + + var src9 = @" +public struct C : I +{ + public ref int M() + { + throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp9 = CreateCompilation(src9, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp9, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.False(m.GlobalNamespace.GetMember("C.M").HasUnscopedRefAttribute); + } + } + + var src10 = @" +public struct C : I +{ + ref int I.M() + { + throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp10 = CreateCompilation(src10, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp10, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + Assert.False(m.GlobalNamespace.GetMember("C.I.M").HasUnscopedRefAttribute); + } + } + + var src11 = @" +public struct C : I +{ + public int f; + + public ref int M() + { + return ref f; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp11 = CreateCompilation(src11, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp11.VerifyDiagnostics( + // (8,20): error CS8170: Struct members cannot return 'this' or other instance members by reference + // return ref f; + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "f").WithLocation(8, 20) + ); + } + + var src12 = @" +public struct C : I +{ + public int f; + + ref int I.M() + { + return ref f; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp12 = CreateCompilation(src12, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp12.VerifyDiagnostics( + // (8,20): error CS8170: Struct members cannot return 'this' or other instance members by reference + // return ref f; + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "f").WithLocation(8, 20) + ); + } + } + + [Fact] + public void UnscopedRefInImplementation_Method_02() + { + var src1 = @" +public interface I +{ + ref int M(); +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.Net80); + MetadataReference[] comp1Refs = [comp1.EmitToImageReference(), comp1.ToMetadataReference()]; + + var src7 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + [UnscopedRef] + public ref int M() + { + return ref f; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp7.VerifyDiagnostics( + // (9,20): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.M()' doesn't have this attribute. + // public ref int M() + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "M").WithArguments("I.M()").WithLocation(9, 20) + ); + + Assert.True(comp7.GetMember("C.M").HasUnscopedRefAttribute); + } + + var src8 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + [UnscopedRef] + ref int I.M() + { + return ref f; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp8.VerifyDiagnostics( + // (9,15): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.M()' doesn't have this attribute. + // ref int I.M() + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "M").WithArguments("I.M()").WithLocation(9, 15) + ); + + Assert.True(comp8.GetMember("C.I.M").HasUnscopedRefAttribute); + } + } + + [Fact] + public void UnscopedRefInImplementation_Method_03() + { + var src = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ +#line 100 + [UnscopedRef] + ref int M(); +} + +public struct C : I +{ + public int f; + +#line 200 + [UnscopedRef] + public ref int M() + { + return ref f; + } +} +"; + + CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6) + ); + } + + [Theory] + [CombinatorialData] + public void UnscopedRefInImplementation_Property_01(bool onInterfaceProperty, bool onInterfaceGet, bool onImplementationProperty, bool onImplementationGet) + { + if (!onInterfaceProperty && !onInterfaceGet) + { + return; + } + + var src1 = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + " + (onInterfaceProperty ? "[UnscopedRef]" : "") + @" + ref int P { " + (onInterfaceGet ? "[UnscopedRef] " : "") + @"get; } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.Net80); + + var p = comp1.GetMember("I.P"); + Assert.Equal(onInterfaceProperty, p.HasUnscopedRefAttribute); + Assert.Equal(onInterfaceGet, p.GetMethod.HasUnscopedRefAttribute); + + MetadataReference[] comp1Refs = [comp1.EmitToImageReference(), comp1.ToMetadataReference()]; + + if (onImplementationProperty || onImplementationGet) + { + var src2 = @" +using System.Diagnostics.CodeAnalysis; + +class C : I +{ +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + public ref int P + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + => throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp2 = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.Net80); + + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp2.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6), + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + else + { + comp2.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6) + ); + } + } + else + { + comp2.VerifyDiagnostics( + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + + PropertySymbol propertySymbol = comp2.GetMember("C.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + var src3 = @" +using System.Diagnostics.CodeAnalysis; + +class C : I +{ +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + ref int I. P + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + => throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp3 = CreateCompilation(src3, references: [comp1Ref], targetFramework: TargetFramework.Net80); + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp3.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6), + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + else + { + comp3.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6) + ); + } + } + else + { + comp3.VerifyDiagnostics( + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + + PropertySymbol propertySymbol = comp3.GetMember("C.I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + if (!onImplementationProperty && !onImplementationGet) + { + var src4 = @" +class C1 : I +{ + int f = 0; + public ref int P + { get{ + return ref f; + }} +} + +class C2 : I +{ + int f = 0; + ref int I.P + { get{ + return ref f; + }} +} + +class C3 +{ + int f = 0; + public ref int P + { get{ + return ref f; + }} +} + +class C4 : C3, I {} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp4 = CreateCompilation(src4, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp4, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol c1P = m.GlobalNamespace.GetMember("C1.P"); + Assert.False(c1P.HasUnscopedRefAttribute); + Assert.False(c1P.GetMethod.HasUnscopedRefAttribute); + PropertySymbol c2P = m.GlobalNamespace.GetMember("C2.I.P"); + Assert.False(c2P.HasUnscopedRefAttribute); + Assert.False(c2P.GetMethod.HasUnscopedRefAttribute); + PropertySymbol c3P = m.GlobalNamespace.GetMember("C3.P"); + Assert.False(c3P.HasUnscopedRefAttribute); + Assert.False(c3P.GetMethod.HasUnscopedRefAttribute); + } + } + } + + if (onImplementationProperty || onImplementationGet) + { + var src5 = @" +using System.Diagnostics.CodeAnalysis; + +interface C : I +{ +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + ref int I.P + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + => throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp5 = CreateCompilation(src5, references: [comp1Ref], targetFramework: TargetFramework.Net80); + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp5.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6), + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + else + { + comp5.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6) + ); + } + } + else + { + comp5.VerifyDiagnostics( + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + + PropertySymbol propertySymbol = comp5.GetMember("C.I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + if (!onImplementationProperty && !onImplementationGet) + { + var src6 = @" +interface C : I +{ + ref int I.P => throw null; +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp6 = CreateCompilation(src6, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp6, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + } + + if (onImplementationProperty || onImplementationGet) + { + var src7 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + public ref int P + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp7, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.P"); + Assert.Equal(onImplementationProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onImplementationGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12); + if (onImplementationGet) + { + comp7.VerifyDiagnostics( + // (200,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(200, 10) + ); + } + else + { + comp7.VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6) + ); + } + } + + var src8 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + ref int I.P + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp8, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.I.P"); + Assert.Equal(onImplementationProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onImplementationGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12); + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp8.VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6), + // (200,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(200, 10) + ); + } + else + { + comp8.VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6) + ); + } + } + else + { + comp8.VerifyDiagnostics( + // (200,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(200, 10) + ); + } + } + } + + if (!onImplementationProperty && !onImplementationGet) + { + var src9 = @" +public struct C : I +{ + public ref int P => throw null; +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp9 = CreateCompilation(src9, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp9, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + var src10 = @" +public struct C : I +{ + ref int I.P => throw null; +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp10 = CreateCompilation(src10, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp10, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.I.P"); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + var src11 = @" +public struct C : I +{ + public int f; + + public ref int P + { get{ + return ref f; + }} +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp11 = CreateCompilation(src11, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp11.VerifyDiagnostics( + // (8,20): error CS8170: Struct members cannot return 'this' or other instance members by reference + // return ref f; + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "f").WithLocation(8, 20) + ); + } + + var src12 = @" +public struct C : I +{ + public int f; + + ref int I.P + { get{ + return ref f; + }} +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp12 = CreateCompilation(src12, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp12.VerifyDiagnostics( + // (8,20): error CS8170: Struct members cannot return 'this' or other instance members by reference + // return ref f; + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "f").WithLocation(8, 20) + ); + } + } + } + + [Theory] + [CombinatorialData] + public void UnscopedRefInImplementation_Property_02(bool onProperty, bool onGet) + { + if (!onProperty && !onGet) + { + return; + } + + var src1 = @" +public interface I +{ + ref int P { get; } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.Net80); + MetadataReference[] comp1Refs = [comp1.EmitToImageReference(), comp1.ToMetadataReference()]; + + var src7 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + " + (onProperty ? "[UnscopedRef]" : "") + @" + public ref int P + { +#line 200 + " + (onGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp7.VerifyDiagnostics( + // (201,9): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.P.get' doesn't have this attribute. + // get + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I.P.get").WithLocation(201, 9) + ); + + PropertySymbol propertySymbol = comp7.GetMember("C.P"); + Assert.Equal(onProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + var src8 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + " + (onProperty ? "[UnscopedRef]" : "") + @" + ref int I.P + { +#line 200 + " + (onGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp8.VerifyDiagnostics( + // (201,9): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.P.get' doesn't have this attribute. + // get + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I.P.get").WithLocation(201, 9) + ); + + PropertySymbol propertySymbol = comp8.GetMember("C.I.P"); + Assert.Equal(onProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + [Theory] + [CombinatorialData] + public void UnscopedRefInImplementation_Indexer_01(bool onInterfaceProperty, bool onInterfaceGet, bool onImplementationProperty, bool onImplementationGet) + { + if (!onInterfaceProperty && !onInterfaceGet) + { + return; + } + + var src1 = @" +using System.Diagnostics.CodeAnalysis; + +public interface I +{ + " + (onInterfaceProperty ? "[UnscopedRef]" : "") + @" + ref int this[int i] { " + (onInterfaceGet ? "[UnscopedRef] " : "") + @"get; } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.Net80); + + var p = comp1.GetMember("I." + WellKnownMemberNames.Indexer); + Assert.Equal(onInterfaceProperty, p.HasUnscopedRefAttribute); + Assert.Equal(onInterfaceGet, p.GetMethod.HasUnscopedRefAttribute); + + MetadataReference[] comp1Refs = [comp1.EmitToImageReference(), comp1.ToMetadataReference()]; + + if (onImplementationProperty || onImplementationGet) + { + var src2 = @" +using System.Diagnostics.CodeAnalysis; + +class C : I +{ +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + public ref int this[int i] + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + => throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp2 = CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.Net80); + + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp2.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6), + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + else + { + comp2.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6) + ); + } + } + else + { + comp2.VerifyDiagnostics( + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + + PropertySymbol propertySymbol = comp2.GetMember("C." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + var src3 = @" +using System.Diagnostics.CodeAnalysis; + +class C : I +{ +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + ref int I. this[int i] + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + => throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp3 = CreateCompilation(src3, references: [comp1Ref], targetFramework: TargetFramework.Net80); + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp3.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6), + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + else + { + comp3.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6) + ); + } + } + else + { + comp3.VerifyDiagnostics( + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + + PropertySymbol propertySymbol = comp3.GetMember("C.I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + if (!onImplementationProperty && !onImplementationGet) + { + var src4 = @" +class C1 : I +{ + int f = 0; + public ref int this[int i] + { get{ + return ref f; + }} +} + +class C2 : I +{ + int f = 0; + ref int I.this[int i] + { get{ + return ref f; + }} +} + +class C3 +{ + int f = 0; + public ref int this[int i] + { get{ + return ref f; + }} +} + +class C4 : C3, I {} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp4 = CreateCompilation(src4, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp4, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol c1P = m.GlobalNamespace.GetMember("C1." + WellKnownMemberNames.Indexer); + Assert.False(c1P.HasUnscopedRefAttribute); + Assert.False(c1P.GetMethod.HasUnscopedRefAttribute); + PropertySymbol c2P = m.GlobalNamespace.GetMember("C2.I." + (m is PEModuleSymbol ? "Item" : WellKnownMemberNames.Indexer)); + Assert.False(c2P.HasUnscopedRefAttribute); + Assert.False(c2P.GetMethod.HasUnscopedRefAttribute); + PropertySymbol c3P = m.GlobalNamespace.GetMember("C3." + WellKnownMemberNames.Indexer); + Assert.False(c3P.HasUnscopedRefAttribute); + Assert.False(c3P.GetMethod.HasUnscopedRefAttribute); + } + } + } + + if (onImplementationProperty || onImplementationGet) + { + var src5 = @" +using System.Diagnostics.CodeAnalysis; + +interface C : I +{ +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + ref int I.this[int i] + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + => throw null; + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp5 = CreateCompilation(src5, references: [comp1Ref], targetFramework: TargetFramework.Net80); + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp5.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6), + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + else + { + comp5.VerifyDiagnostics( + // (100,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(100, 6) + ); + } + } + else + { + comp5.VerifyDiagnostics( + // (200,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(200, 10) + ); + } + + PropertySymbol propertySymbol = comp5.GetMember("C.I." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + if (!onImplementationProperty && !onImplementationGet) + { + var src6 = @" +interface C : I +{ + ref int I.this[int i] => throw null; +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp6 = CreateCompilation(src6, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp6, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.I." + (m is PEModuleSymbol ? "Item" : WellKnownMemberNames.Indexer)); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + } + + if (onImplementationProperty || onImplementationGet) + { + var src7 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + public ref int this[int i] + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp7, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C." + WellKnownMemberNames.Indexer); + Assert.Equal(onImplementationProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onImplementationGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12); + if (onImplementationGet) + { + comp7.VerifyDiagnostics( + // (200,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(200, 10) + ); + } + else + { + comp7.VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6) + ); + } + } + + var src8 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; +#line 100 + " + (onImplementationProperty ? "[UnscopedRef]" : "") + @" + ref int I.this[int i] + { +#line 200 + " + (onImplementationGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp8, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.I." + (m is PEModuleSymbol ? "Item" : WellKnownMemberNames.Indexer)); + Assert.Equal(onImplementationProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onImplementationGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80, parseOptions: TestOptions.Regular12); + if (onImplementationProperty) + { + if (onImplementationGet) + { + comp8.VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6), + // (200,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(200, 10) + ); + } + else + { + comp8.VerifyDiagnostics( + // (100,6): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(100, 6) + ); + } + } + else + { + comp8.VerifyDiagnostics( + // (200,10): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // [UnscopedRef] + Diagnostic(ErrorCode.ERR_FeatureInPreview, "UnscopedRef").WithArguments("ref struct interfaces").WithLocation(200, 10) + ); + } + } + } + + if (!onImplementationProperty && !onImplementationGet) + { + var src9 = @" +public struct C : I +{ + public ref int this[int i] => throw null; +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp9 = CreateCompilation(src9, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp9, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C." + WellKnownMemberNames.Indexer); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + var src10 = @" +public struct C : I +{ + ref int I.this[int i] => throw null; +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp10 = CreateCompilation(src10, references: [comp1Ref], targetFramework: TargetFramework.Net80); + CompileAndVerify(comp10, sourceSymbolValidator: verify, symbolValidator: verify, verify: Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + PropertySymbol propertySymbol = m.GlobalNamespace.GetMember("C.I." + (m is PEModuleSymbol ? "Item" : WellKnownMemberNames.Indexer)); + Assert.False(propertySymbol.HasUnscopedRefAttribute); + Assert.False(propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + var src11 = @" +public struct C : I +{ + public int f; + + public ref int this[int i] + { get{ + return ref f; + }} +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp11 = CreateCompilation(src11, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp11.VerifyDiagnostics( + // (8,20): error CS8170: Struct members cannot return 'this' or other instance members by reference + // return ref f; + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "f").WithLocation(8, 20) + ); + } + + var src12 = @" +public struct C : I +{ + public int f; + + ref int I.this[int i] + { get{ + return ref f; + }} +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp12 = CreateCompilation(src12, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp12.VerifyDiagnostics( + // (8,20): error CS8170: Struct members cannot return 'this' or other instance members by reference + // return ref f; + Diagnostic(ErrorCode.ERR_RefReturnStructThis, "f").WithLocation(8, 20) + ); + } + } + } + + [Theory] + [CombinatorialData] + public void UnscopedRefInImplementation_Indexer_02(bool onProperty, bool onGet) + { + if (!onProperty && !onGet) + { + return; + } + + var src1 = @" +public interface I +{ + ref int this[int i] { get; } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.Net80); + MetadataReference[] comp1Refs = [comp1.EmitToImageReference(), comp1.ToMetadataReference()]; + + var src7 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + " + (onProperty ? "[UnscopedRef]" : "") + @" + public ref int this[int i] + { +#line 200 + " + (onGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp7 = CreateCompilation(src7, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp7.VerifyDiagnostics( + // (201,9): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.P.get' doesn't have this attribute. + // get + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I.this[int].get").WithLocation(201, 9) + ); + + PropertySymbol propertySymbol = comp7.GetMember("C." + WellKnownMemberNames.Indexer); + Assert.Equal(onProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + + var src8 = @" +using System.Diagnostics.CodeAnalysis; + +public struct C : I +{ + public int f; + + " + (onProperty ? "[UnscopedRef]" : "") + @" + ref int I.this[int i] + { +#line 200 + " + (onGet ? "[UnscopedRef] " : "") + @" + get + { + return ref f; + } + } +} +"; + + foreach (var comp1Ref in comp1Refs) + { + var comp8 = CreateCompilation(src8, references: [comp1Ref], targetFramework: TargetFramework.Net80); + comp8.VerifyDiagnostics( + // (201,9): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.P.get' doesn't have this attribute. + // get + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I.this[int].get").WithLocation(201, 9) + ); + + PropertySymbol propertySymbol = comp8.GetMember("C.I." + WellKnownMemberNames.Indexer); + Assert.Equal(onProperty, propertySymbol.HasUnscopedRefAttribute); + Assert.Equal(onGet, propertySymbol.GetMethod.HasUnscopedRefAttribute); + } + } + + // This is a clone of MethodArgumentsMustMatch_16 from RefFieldTests.cs + [Fact] + public void MethodArgumentsMustMatch_16_DirectInterface() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + interface R + { + public ref int FA(); + [UnscopedRef] public ref int FB(); + } + class Program + { + static void F1(ref R r1, ref int i1) { } + static void F2(ref R r2, [UnscopedRef] ref int i2) { } + static void F(ref R x) + { + R y = default; + F1(ref x, ref y.FA()); + F1(ref x, ref y.FB()); + F2(ref x, ref y.FA()); + F2(ref x, ref y.FB()); // 1 + } + } + """; + var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); + comp.VerifyDiagnostics(); + } + + // This is a clone of MethodArgumentsMustMatch_16 from RefFieldTests.cs + [Fact] + public void MethodArgumentsMustMatch_16_ConstrainedTypeParameter() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + interface R + { + public ref int FA(); + [UnscopedRef] public ref int FB(); + } + class Program where T : R, allows ref struct + { + static void F1(ref T r1, ref int i1) { } + static void F2(ref T r2, [UnscopedRef] ref int i2) { } + static void F(ref T x) + { + T y = default; + F1(ref x, ref y.FA()); + F1(ref x, ref y.FB()); + F2(ref x, ref y.FA()); + F2(ref x, ref y.FB()); // 1 + } + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (17,9): error CS8350: This combination of arguments to 'Program.F2(ref T, ref int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope + // F2(ref x, ref y.FB()); // 1 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, ref y.FB())").WithArguments("Program.F2(ref T, ref int)", "i2").WithLocation(17, 9), + // (17,23): error CS8168: Cannot return local 'y' by reference because it is not a ref local + // F2(ref x, ref y.FB()); // 1 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(17, 23)); + } + + // This is a clone of MethodArgumentsMustMatch_16 from RefFieldTests.cs + [Fact] + public void MethodArgumentsMustMatch_16_ClassConstrainedTypeParameter() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + interface R + { + public ref int FA(); + [UnscopedRef] public ref int FB(); + } + class Program where T : class, R + { + static void F1(ref T r1, ref int i1) { } + static void F2(ref T r2, [UnscopedRef] ref int i2) { } + static void F(ref T x) + { + T y = default; + F1(ref x, ref y.FA()); + F1(ref x, ref y.FB()); + F2(ref x, ref y.FA()); + F2(ref x, ref y.FB()); // 1 + } + } + """; + var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); + comp.VerifyDiagnostics(); + } + + // This is a clone of MethodArgumentsMustMatch_17 from RefFieldTests.cs + [Fact] + public void MethodArgumentsMustMatch_17() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + interface IR + { + public ref int FA(); + [UnscopedRef] public ref int FB(); + } + class Program where R : IR, allows ref struct + { + static void F1(ref R r1, in int i1) { } + static void F2(ref R r2, [UnscopedRef] in int i2) { } + static void F(ref R x) + { + R y = default; + F1(ref x, y.FA()); + F1(ref x, y.FB()); + F2(ref x, y.FA()); + F2(ref x, y.FB()); // 1 + F1(ref x, in y.FA()); + F1(ref x, in y.FB()); + F2(ref x, in y.FA()); + F2(ref x, in y.FB()); // 2 + } + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (17,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope + // F2(ref x, y.FB()); // 1 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(17, 9), + // (17,19): error CS8168: Cannot return local 'y' by reference because it is not a ref local + // F2(ref x, y.FB()); // 1 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(17, 19), + // (21,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope + // F2(ref x, in y.FB()); // 2 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, in y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(21, 9), + // (21,22): error CS8168: Cannot return local 'y' by reference because it is not a ref local + // F2(ref x, in y.FB()); // 2 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(21, 22)); + } + + // This is a clone of MethodArgumentsMustMatch_18 from RefFieldTests.cs + [Fact] + public void MethodArgumentsMustMatch_18() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + interface IR + { + public ref readonly int FA(); + [UnscopedRef] public ref readonly int FB(); + } + class Program where R : IR, allows ref struct + { + static void F1(ref R r1, in int i1) { } + static void F2(ref R r2, [UnscopedRef] in int i2) { } + static void F(ref R x) + { + R y = default; + F1(ref x, y.FA()); + F1(ref x, y.FB()); + F2(ref x, y.FA()); + F2(ref x, y.FB()); // 1 + F1(ref x, in y.FA()); + F1(ref x, in y.FB()); + F2(ref x, in y.FA()); + F2(ref x, in y.FB()); // 2 + } + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (17,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope + // F2(ref x, y.FB()); // 1 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(17, 9), + // (17,19): error CS8168: Cannot return local 'y' by reference because it is not a ref local + // F2(ref x, y.FB()); // 1 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(17, 19), + // (21,9): error CS8350: This combination of arguments to 'Program.F2(ref R, in int)' is disallowed because it may expose variables referenced by parameter 'i2' outside of their declaration scope + // F2(ref x, in y.FB()); // 2 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F2(ref x, in y.FB())").WithArguments("Program.F2(ref R, in int)", "i2").WithLocation(21, 9), + // (21,22): error CS8168: Cannot return local 'y' by reference because it is not a ref local + // F2(ref x, in y.FB()); // 2 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "y").WithArguments("y").WithLocation(21, 22)); + } + + // This is a clone of ReturnOnlyScope_01 from RefFieldTests.cs + [Fact] + public void ReturnOnlyScope_01() + { + // test that return scope is used in all return-ey locations. + var source = """ + using System.Diagnostics.CodeAnalysis; + + interface IRS where RSOut : IRSOut, allows ref struct + { + [UnscopedRef] + public RSOut ToRSOut(); + } + + interface IRSOut + { + } + + class Program where RS : IRS, allows ref struct where RSOut : IRSOut, allows ref struct + { + RS M1(ref RS rs) => rs; + void M2(ref RS rs, out RSOut rs1) => rs1 = rs.ToRSOut(); + + RS M3(ref RS rs) + { + return rs; + } + void M4(ref RS rs, out RSOut rs1) + { + rs1 = rs.ToRSOut(); + } + + void localContainer() + { + #pragma warning disable 8321 + RS M1(ref RS rs) => rs; + void M2(ref RS rs, out RSOut rs1) => rs1 = rs.ToRSOut(); + + RS M3(ref RS rs) + { + return rs; + } + void M4(ref RS rs, out RSOut rs1) + { + rs1 = rs.ToRSOut(); // 4 + } + } + + delegate RS ReturnsRefStruct(ref RS rs); + delegate void RefStructOut(ref RS rs, out RSOut rs1); + + void lambdaContainer() + { + ReturnsRefStruct d1 = (ref RS rs) => rs; + RefStructOut d2 = (ref RS rs, out RSOut rs1) => rs1 = rs.ToRSOut(); + + ReturnsRefStruct d3 = (ref RS rs) => + { + return rs; + }; + RefStructOut d4 = (ref RS rs, out RSOut rs1) => + { + rs1 = rs.ToRSOut(); + }; + } + } + """; + + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics(); + + Assert.True(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)); + } + + // This is a clone of ReturnRefToRefStruct_ValEscape_01 from RefFieldTests.cs + [Fact] + public void ReturnRefToRefStruct_ValEscape_01() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + class Repro where TRefStruct : IRefStruct, new() , allows ref struct + { + private static void Bad2(int value) + { + TRefStruct s1 = new TRefStruct(); + s1.RefProperty.RefField = ref value; // 2 + } + + private static void Bad3(int value) + { + TRefStruct s1 = new TRefStruct(); + s1.RefMethod().RefField = ref value; // 3 + } + } + + ref struct RefStruct + { + public ref int RefField; + } + + interface IRefStruct + { + [UnscopedRef] public ref RefStruct RefProperty {get;} + [UnscopedRef] public ref RefStruct RefMethod(); + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefProperty.RefField = ref value; // 2 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(8, 9), + // (14,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefMethod().RefField = ref value; // 3 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(14, 9)); + } + + // This is a clone of ReturnRefToRefStruct_ValEscape_02 from RefFieldTests.cs + [Fact] + public void ReturnRefToRefStruct_ValEscape_02() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + class Repro where TRefStruct : IRefStruct, allows ref struct + { + private static void Bad2(scoped ref TRefStruct s1, int value) + { + s1.RefProperty.RefField = ref value; // 2 + } + + private static void Bad3(scoped ref TRefStruct s1, int value) + { + s1.RefMethod().RefField = ref value; // 3 + } + + private static void Bad5(scoped in TRefStruct s1, int value) + { + s1.RefProperty.RefField = ref value; // 5 + } + + private static void Bad6(scoped in TRefStruct s1, int value) + { + s1.RefMethod().RefField = ref value; // 6 + } + + private static void Bad8(in TRefStruct s1, int value) + { + s1.RefProperty.RefField = ref value; // 8 + } + + private static void Bad9(in TRefStruct s1, int value) + { + s1.RefMethod().RefField = ref value; // 9 + } + } + + ref struct RefStruct + { + public ref int RefField; + } + + interface IRefStruct + { + [UnscopedRef] public ref RefStruct RefProperty {get;} + [UnscopedRef] public ref RefStruct RefMethod(); + } + """; + + // NB: 8 and 9 are not strictly necessary here because they are assigning to an implicit copy of a readonly variable, not to the original variable. + // However, it is not deeply problematic that an error is given here. + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefProperty.RefField = ref value; // 2 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(7, 9), + // (12,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefMethod().RefField = ref value; // 3 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(12, 9), + // (17,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefProperty.RefField = ref value; // 5 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(17, 9), + // (22,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefMethod().RefField = ref value; // 6 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(22, 9), + // (27,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefProperty.RefField = ref value; // 8 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefProperty.RefField = ref value").WithArguments("RefField", "value").WithLocation(27, 9), + // (32,9): error CS8374: Cannot ref-assign 'value' to 'RefField' because 'value' has a narrower escape scope than 'RefField'. + // s1.RefMethod().RefField = ref value; // 9 + Diagnostic(ErrorCode.ERR_RefAssignNarrower, "s1.RefMethod().RefField = ref value").WithArguments("RefField", "value").WithLocation(32, 9) + ); + } + + // This is a clone of ReturnRefToRefStruct_ValEscape_03 from RefFieldTests.cs + [Fact] + public void ReturnRefToRefStruct_ValEscape_03() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + class Repro where TRefStruct : IRefStruct, allows ref struct + { + private static void Bad1(ref TRefStruct s1, int value) + { + s1 = TRefStruct.New(ref value); // 1 + } + + private static void Bad2(scoped ref TRefStruct s1, int value) + { + s1.RefProperty = TRefStruct.New(ref value); // 2 + } + + private static void Bad3(scoped ref TRefStruct s1, int value) + { + s1.RefMethod() = TRefStruct.New(ref value); // 3 + } + + private static void Bad4(scoped ref TRefStruct s1, int value) + { + GetRef(ref s1) = TRefStruct.New(ref value); // 4 + } + + private static ref TRefStruct GetRef(ref TRefStruct s) => ref s; + } + + interface IRefStruct where TRefStruct : IRefStruct, allows ref struct + { + abstract static TRefStruct New(ref int i); + [UnscopedRef] public ref TRefStruct RefProperty {get;} + [UnscopedRef] public ref TRefStruct RefMethod(); + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,14): error CS8347: Cannot use a result of 'IRefStruct.New(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope + // s1 = TRefStruct.New(ref value); // 1 + Diagnostic(ErrorCode.ERR_EscapeCall, "TRefStruct.New(ref value)").WithArguments("IRefStruct.New(ref int)", "i").WithLocation(7, 14), + // (7,33): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter + // s1 = TRefStruct.New(ref value); // 1 + Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(7, 33), + // (12,26): error CS8347: Cannot use a result of 'IRefStruct.New(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope + // s1.RefProperty = TRefStruct.New(ref value); // 2 + Diagnostic(ErrorCode.ERR_EscapeCall, "TRefStruct.New(ref value)").WithArguments("IRefStruct.New(ref int)", "i").WithLocation(12, 26), + // (12,45): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter + // s1.RefProperty = TRefStruct.New(ref value); // 2 + Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(12, 45), + // (17,26): error CS8347: Cannot use a result of 'IRefStruct.New(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope + // s1.RefMethod() = TRefStruct.New(ref value); // 3 + Diagnostic(ErrorCode.ERR_EscapeCall, "TRefStruct.New(ref value)").WithArguments("IRefStruct.New(ref int)", "i").WithLocation(17, 26), + // (17,45): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter + // s1.RefMethod() = TRefStruct.New(ref value); // 3 + Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(17, 45), + // (22,26): error CS8347: Cannot use a result of 'IRefStruct.New(ref int)' in this context because it may expose variables referenced by parameter 'i' outside of their declaration scope + // GetRef(ref s1) = TRefStruct.New(ref value); // 4 + Diagnostic(ErrorCode.ERR_EscapeCall, "TRefStruct.New(ref value)").WithArguments("IRefStruct.New(ref int)", "i").WithLocation(22, 26), + // (22,45): error CS8166: Cannot return a parameter by reference 'value' because it is not a ref parameter + // GetRef(ref s1) = TRefStruct.New(ref value); // 4 + Diagnostic(ErrorCode.ERR_RefReturnParameter, "value").WithArguments("value").WithLocation(22, 45) + ); + } + + // This is a clone of ReturnRefToRefStruct_ValEscape_04 from RefFieldTests.cs + [Fact] + public void ReturnRefToRefStruct_ValEscape_04() + { + // test that the appropriate filtering of escape-values is occurring when the RTRS expression is on the RHS of an an assignment. + var source = """ + using System.Diagnostics.CodeAnalysis; + + class Repro where TRefStruct : IRefStruct, allows ref struct + { + private static void M1(ref TRefStruct s1, int value) + { + // 's2' only contributes STE, not RSTE, to the STE of 'RefMethod()' invocation. + // STE is equal to RSTE for 's2', so it doesn't matter. + var s2 = TRefStruct.New(ref value); + s1 = s2.RefMethod(); // 1 + } + + private static void M2(ref TRefStruct s1, ref TRefStruct s2) + { + // 's2' only contributes STE, not RSTE, to the STE of 'RefMethod()' invocation. + // RSTE of `s2` is narrower than STE of 's1', but STE of 's2' equals STE of 's1', so we expect no error here. + s1 = s2.RefMethod(); + } + } + + interface IRefStruct where TRefStruct : IRefStruct, allows ref struct + { + abstract static TRefStruct New(ref int i); + [UnscopedRef] public ref TRefStruct RefMethod(); + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (10,14): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope + // s1 = s2.RefMethod(); // 1 + Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(10, 14)); + } + + // This is a clone of LocalScope_DeclarationExpression_06 from RefEscapingTests.cs + [Fact] + public void LocalScope_DeclarationExpression_06() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + interface IRS where RS : IRS, allows ref struct + { + [UnscopedRef] + void M0(out RS rs2); + + RS M1() + { + // RSTE of `this` is CurrentMethod + // STE of rs4 (local variable) is also CurrentMethod + M0(out var rs4); + return rs4; // 1 + } + + [UnscopedRef] + RS M2() + { + M0(out var rs4); + return rs4; + } + } + """; + + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics(); + } + + // This is a clone of UnscopedRefAttribute_Method_03 from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_Method_03_DirectInterface(bool useCompilationReference) + { + var sourceA = +@"using System.Diagnostics.CodeAnalysis; +public interface S +{ + public ref T F1(); + [UnscopedRef] public ref T F2(); +}"; + var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }); + comp.VerifyEmitDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program +{ + static ref int F1() + { + var s = GetS(); + return ref s.F1(); + } + static ref int F2() + { + var s = GetS(); + return ref s.F2(); // 1 + } + + static S GetS() => throw null; +}"; + comp = CreateCompilation(sourceB, references: new[] { refA }); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of UnscopedRefAttribute_Method_03 from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_Method_03_ConstrainedTypeParameter(bool useCompilationReference, bool addStructConstraint) + { + var sourceA = +@"using System.Diagnostics.CodeAnalysis; +public interface S +{ + public ref T F1(); + [UnscopedRef] public ref T F2(); +}"; + var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }); + comp.VerifyEmitDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program where T : " + (addStructConstraint ? "struct, " : "") + @"S +{ + static ref int F1() + { + var s = GetS(); + return ref s.F1(); + } + static ref int F2() + { + var s = GetS(); + return ref s.F2(); // 1 + } + + static T GetS() => throw null; +}"; + comp = CreateCompilation(sourceB, references: new[] { refA }); + comp.VerifyEmitDiagnostics( + // (11,20): error CS8168: Cannot return local 's' by reference because it is not a ref local + // return ref s.F2(); // 1 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "s").WithArguments("s").WithLocation(11, 20)); + } + + // This is a clone of UnscopedRefAttribute_Method_03 from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_Method_03_ClassConstrainedTypeParameter(bool useCompilationReference) + { + var sourceA = +@"using System.Diagnostics.CodeAnalysis; +public interface S +{ + public ref T F1(); + [UnscopedRef] public ref T F2(); +}"; + var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }); + comp.VerifyEmitDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program where T : class, S +{ + static ref int F1() + { + var s = GetS(); + return ref s.F1(); + } + static ref int F2() + { + var s = GetS(); + return ref s.F2(); // 1 + } + + static T GetS() => throw null; +}"; + comp = CreateCompilation(sourceB, references: new[] { refA }); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of UnscopedRefAttribute_Property_02 from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_Property_02_DirectInterface(bool useCompilationReference) + { + var sourceA = +@"using System.Diagnostics.CodeAnalysis; +public interface S +{ + public ref T P1 {get;} + [UnscopedRef] public ref T P2 {get;} +}"; + var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }); + comp.VerifyEmitDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program +{ + static ref int F1() + { + var s = default(S); + return ref s.P1; + } + static ref int F2() + { + var s = default(S); + return ref s.P2; // 1 + } +}"; + comp = CreateCompilation(sourceB, references: new[] { refA }); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of UnscopedRefAttribute_Property_02 from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_Property_02_ConstrainedTypeParameter(bool useCompilationReference, bool addStructConstraint) + { + var sourceA = +@"using System.Diagnostics.CodeAnalysis; +public interface S +{ + public ref T P1 {get;} + [UnscopedRef] public ref T P2 {get;} +}"; + var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }); + comp.VerifyEmitDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program where T : " + (addStructConstraint ? "struct, " : "") + @"S" + (!addStructConstraint ? ", new()" : "") + @" +{ + static ref int F1() + { + var s = new T(); + return ref s.P1; + } + static ref int F2() + { + var s = new T(); + return ref s.P2; // 1 + } +}"; + comp = CreateCompilation(sourceB, references: new[] { refA }); + comp.VerifyEmitDiagnostics( + // (11,20): error CS8168: Cannot return local 's' by reference because it is not a ref local + // return ref s.P2; // 1 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "s").WithArguments("s").WithLocation(11, 20)); + } + + // This is a clone of UnscopedRefAttribute_Property_02 from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_Property_02_ClassConstrainedTypeParameter(bool useCompilationReference) + { + var sourceA = +@"using System.Diagnostics.CodeAnalysis; +public interface S +{ + public ref T P1 {get;} + [UnscopedRef] public ref T P2 {get;} +}"; + var comp = CreateCompilation(new[] { sourceA, UnscopedRefAttributeDefinition }); + comp.VerifyEmitDiagnostics(); + var refA = AsReference(comp, useCompilationReference); + + var sourceB = +@"class Program where T : class, S, new() +{ + static ref int F1() + { + var s = new T(); + return ref s.P1; + } + static ref int F2() + { + var s = new T(); + return ref s.P2; // 1 + } +}"; + comp = CreateCompilation(sourceB, references: new[] { refA }); + comp.VerifyEmitDiagnostics(); + } + + public enum ThreeState : byte + { + Unknown = 0, + False = 1, + True = 2, + } + + // This is a clone of UnscopedRefAttribute_NestedAccess_MethodOrProperty from RefFieldTests.cs + [Theory, CombinatorialData] + public void UnscopedRefAttribute_NestedAccess_MethodOrProperty(bool firstIsMethod, bool secondIsMethod, ThreeState tS1IsClass, ThreeState tS2IsClass) + { + var source = $$""" +using System.Diagnostics.CodeAnalysis; + +{{(tS1IsClass == ThreeState.True || tS2IsClass == ThreeState.True ? "" : """ +var c = new C, S2>(); +c.Value() = 12; +System.Console.WriteLine(c.Value()); +""")}} + +class C + where TS1 : {{(tS1IsClass switch { ThreeState.False => "struct, ", ThreeState.True => "class, ", _ => "" })}}IS1 + where TS2 : {{(tS2IsClass switch { ThreeState.False => "struct, ", ThreeState.True => "class, ", _ => "" })}}IS2 +{ + public ref int Value() => ref s1.S2{{csharp(firstIsMethod)}}.Value{{csharp(secondIsMethod)}}; +#line 100 + private TS1 s1; +} + +struct S1 : IS1 where TS2 : IS2 +{ + private TS2 s2; + [UnscopedRef] public ref TS2 S2{{csharp(firstIsMethod)}} => ref s2; +} + +struct S2 : IS2 +{ + private int value; + [UnscopedRef] public ref int Value{{csharp(secondIsMethod)}} => ref value; +} + +interface IS1 where TS2 : IS2 +{ + [UnscopedRef] public ref TS2 S2{{(firstIsMethod ? "();" : "{get;}")}} +} + +interface IS2 +{ + [UnscopedRef] public ref int Value{{(secondIsMethod ? "();" : "{get;}")}} +} +"""; + var verifier = CompileAndVerify(new[] { source, UnscopedRefAttributeDefinition }, expectedOutput: (tS1IsClass == ThreeState.True || tS2IsClass == ThreeState.True ? null : "12"), verify: Verification.Fails); + verifier.VerifyDiagnostics( + // 0.cs(100,17): warning CS0649: Field 'C.s1' is never assigned to, and will always have its default value + // private TS1 s1; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "s1").WithArguments("C.s1", tS1IsClass == ThreeState.True ? "null" : "").WithLocation(100, 17) + ); + verifier.VerifyMethodBody("C.Value", + tS1IsClass == ThreeState.True ? $$""" +{ + // Code size 28 (0x1c) + .maxstack 1 + // sequence point: s1.S2{{csharp(firstIsMethod)}}.Value{{csharp(secondIsMethod)}} + IL_0000: ldarg.0 + IL_0001: ldfld "TS1 C.s1" + IL_0006: box "TS1" + IL_000b: callvirt "ref TS2 IS1.S2{{il(firstIsMethod)}}" + IL_0010: constrained. "TS2" + IL_0016: callvirt "ref int IS2.Value{{il(secondIsMethod)}}" + IL_001b: ret +} +""" : $$""" +{ + // Code size 29 (0x1d) + .maxstack 1 + // sequence point: s1.S2{{csharp(firstIsMethod)}}.Value{{csharp(secondIsMethod)}} + IL_0000: ldarg.0 + IL_0001: ldflda "TS1 C.s1" + IL_0006: constrained. "TS1" + IL_000c: callvirt "ref TS2 IS1.S2{{il(firstIsMethod)}}" + IL_0011: constrained. "TS2" + IL_0017: callvirt "ref int IS2.Value{{il(secondIsMethod)}}" + IL_001c: ret +} +"""); + + static string csharp(bool method) => method ? "()" : ""; + static string il(bool method) => method ? "()" : ".get"; + } + + // This is a clone of UnscopedRefAttribute_NestedAccess_Properties_Invalid from RefFieldTests.cs + [Fact] + public void UnscopedRefAttribute_NestedAccess_Properties_Invalid_DirectInterface() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + class C + { + private S1 s1; + public ref int Value() => ref s1.S2.Value; + } + + struct S1 + { + private S2 s2; + public S2 S2 => s2; + } + + interface S2 + { + [UnscopedRef] public ref int Value {get;} + } + """; + CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }).VerifyDiagnostics( + // 0.cs(11,16): warning CS0649: Field 'S1.s2' is never assigned to, and will always have its default value null + // private S2 s2; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "s2").WithArguments("S1.s2", "null").WithLocation(11, 16)); + } + + // This is a clone of UnscopedRefAttribute_NestedAccess_Properties_Invalid from RefFieldTests.cs + [CombinatorialData] + [Theory] + public void UnscopedRefAttribute_NestedAccess_Properties_Invalid_ConstrainedTypeParameter(bool addStructConstraint) + { + var source = +@"using System.Diagnostics.CodeAnalysis; + +class C where T : " + (addStructConstraint ? "struct, " : "") + @"S2 +{ + private S1 s1; + public ref int Value() => ref s1.S2.Value; +} + +struct S1 where T : S2 +{ + private T s2; + public T S2 => s2; +} + +interface S2 +{ + [UnscopedRef] public ref int Value {get;} +} +"; + CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }).VerifyDiagnostics( + // 0.cs(6,35): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference + // public ref int Value() => ref s1.S2.Value; + Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "s1.S2").WithLocation(6, 35), + // 0.cs(11,15): warning CS0649: Field 'S1.s2' is never assigned to, and will always have its default value + // private T s2; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "s2").WithArguments("S1.s2", "").WithLocation(11, 15)); + } + + // This is a clone of UnscopedRefAttribute_NestedAccess_Properties_Invalid from RefFieldTests.cs + [Fact] + public void UnscopedRefAttribute_NestedAccess_Properties_Invalid_ClassConstrainedTypeParameter() + { + var source = +@"using System.Diagnostics.CodeAnalysis; + +class C where T : class, S2 +{ + private S1 s1; + public ref int Value() => ref s1.S2.Value; +} + +struct S1 where T : S2 +{ + private T s2; + public T S2 => s2; +} + +interface S2 +{ + [UnscopedRef] public ref int Value {get;} +} +"; + CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }).VerifyDiagnostics( + // 0.cs(11,15): warning CS0649: Field 'S1.s2' is never assigned to, and will always have its default value + // private T s2; + Diagnostic(ErrorCode.WRN_UnassignedInternalField, "s2").WithArguments("S1.s2", "").WithLocation(11, 15)); + } + + // This is a clone of UnscopedRef_ArgumentsMustMatch_01 from RefFieldTests.cs + [Fact] + public void UnscopedRef_ArgumentsMustMatch_01_DirectInterface() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + ref struct RefByteContainer + { + public ref byte RB; + + public RefByteContainer(ref byte rb) + { + RB = ref rb; + } + } + + interface ByteContainer + { + [UnscopedRef] + public RefByteContainer ByteRef {get;} + + [UnscopedRef] + public RefByteContainer GetByteRef(); + } + + public class Program + { + static void M11(ref ByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.ByteRef.get' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.ByteRef; + } + static void M12(ref ByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.GetByteRef()' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.GetByteRef(); + } + + static void M21(ref ByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.ByteRef; // 1 + } + static void M22(ref ByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.GetByteRef(); // 2 + } + + static RefByteContainer M31(ref ByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.ByteRef; + + static RefByteContainer M32(ref ByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.GetByteRef(); + + static RefByteContainer M41(scoped ref ByteContainer bc) + // error: `bc.ByteRef` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.ByteRef; // 3 + + static RefByteContainer M42(scoped ref ByteContainer bc) + // error: `bc.GetByteRef()` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.GetByteRef(); // 4 + } + """; + + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyDiagnostics(); + } + + // This is a clone of UnscopedRef_ArgumentsMustMatch_01 from RefFieldTests.cs + [Theory] + [CombinatorialData] + public void UnscopedRef_ArgumentsMustMatch_01_ConstrainedTypeParameter(bool addStructConstraint) + { + var source = $$""" + using System.Diagnostics.CodeAnalysis; + + ref struct RefByteContainer + { + public ref byte RB; + + public RefByteContainer(ref byte rb) + { + RB = ref rb; + } + } + + interface ByteContainer + { + [UnscopedRef] + public RefByteContainer ByteRef {get;} + + [UnscopedRef] + public RefByteContainer GetByteRef(); + } + + class Program where TByteContainer : {{(addStructConstraint ? "struct, " : "")}} ByteContainer + { + static void M11(ref TByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.ByteRef.get' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.ByteRef; + } + static void M12(ref TByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.GetByteRef()' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.GetByteRef(); + } + + static void M21(ref TByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.ByteRef; // 1 + } + static void M22(ref TByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.GetByteRef(); // 2 + } + + static RefByteContainer M31(ref TByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.ByteRef; + + static RefByteContainer M32(ref TByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.GetByteRef(); + + static RefByteContainer M41(scoped ref TByteContainer bc) + // error: `bc.ByteRef` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.ByteRef; // 3 + + static RefByteContainer M42(scoped ref TByteContainer bc) + // error: `bc.GetByteRef()` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.GetByteRef(); // 4 + } + """; + + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyDiagnostics( + // (40,15): error CS9077: Cannot return a parameter by reference 'bc' through a ref parameter; it can only be returned in a return statement + // rbc = bc.ByteRef; // 1 + Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "bc").WithArguments("bc").WithLocation(40, 15), + // (45,15): error CS9077: Cannot return a parameter by reference 'bc' through a ref parameter; it can only be returned in a return statement + // rbc = bc.GetByteRef(); // 2 + Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "bc").WithArguments("bc").WithLocation(45, 15), + // (58,12): error CS9075: Cannot return a parameter by reference 'bc' because it is scoped to the current method + // => bc.ByteRef; // 3 + Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "bc").WithArguments("bc").WithLocation(58, 12), + // (62,12): error CS9075: Cannot return a parameter by reference 'bc' because it is scoped to the current method + // => bc.GetByteRef(); // 4 + Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "bc").WithArguments("bc").WithLocation(62, 12) + ); + } + + // This is a clone of UnscopedRef_ArgumentsMustMatch_01 from RefFieldTests.cs + [Fact] + public void UnscopedRef_ArgumentsMustMatch_01_ClassConstrainedTypeParameter() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + ref struct RefByteContainer + { + public ref byte RB; + + public RefByteContainer(ref byte rb) + { + RB = ref rb; + } + } + + interface ByteContainer + { + [UnscopedRef] + public RefByteContainer ByteRef {get;} + + [UnscopedRef] + public RefByteContainer GetByteRef(); + } + + class Program where TByteContainer : class, ByteContainer + { + static void M11(ref TByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.ByteRef.get' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.ByteRef; + } + static void M12(ref TByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.GetByteRef()' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.GetByteRef(); + } + + static void M21(ref TByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.ByteRef; // 1 + } + static void M22(ref TByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.GetByteRef(); // 2 + } + + static RefByteContainer M31(ref TByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.ByteRef; + + static RefByteContainer M32(ref TByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.GetByteRef(); + + static RefByteContainer M41(scoped ref TByteContainer bc) + // error: `bc.ByteRef` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.ByteRef; // 3 + + static RefByteContainer M42(scoped ref TByteContainer bc) + // error: `bc.GetByteRef()` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.GetByteRef(); // 4 + } + """; + + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyDiagnostics(); + } + + // This is a clone of UnscopedRef_ArgumentsMustMatch_01 from RefFieldTests.cs + [Fact] + public void UnscopedRef_ArgumentsMustMatch_01() + { + var source = """ + using System.Diagnostics.CodeAnalysis; + + interface IRefByteContainer + { + + + //public RefByteContainer(ref byte rb) + //{ + // RB = ref rb; + //} + } + + interface IByteContainer where RefByteContainer : IRefByteContainer, allows ref struct + { + //public byte B; + + [UnscopedRef] + public RefByteContainer ByteRef {get;} + + [UnscopedRef] + public RefByteContainer GetByteRef(); + } + + class Program where RefByteContainer : IRefByteContainer, allows ref struct where ByteContainer : IByteContainer, allows ref struct + { + static void M11(ref ByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.ByteRef.get' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.ByteRef; + } + static void M12(ref ByteContainer bc) + { + // ok. because ref-safe-to-escape of 'this' in 'ByteContainer.GetByteRef()' is 'ReturnOnly', + // we know that 'ref bc' will not end up written to a ref field within 'bc'. + _ = bc.GetByteRef(); + } + + static void M21(ref ByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.ByteRef; // 1 + } + static void M22(ref ByteContainer bc, ref RefByteContainer rbc) + { + // error. ref-safe-to-escape of 'bc' is 'ReturnOnly', therefore 'bc.ByteRef' can't be assigned to a ref parameter. + rbc = bc.GetByteRef(); // 2 + } + + static RefByteContainer M31(ref ByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.ByteRef; + + static RefByteContainer M32(ref ByteContainer bc) + // ok. ref-safe-to-escape of 'bc' is 'ReturnOnly'. + => bc.GetByteRef(); + + static RefByteContainer M41(scoped ref ByteContainer bc) + // error: `bc.ByteRef` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.ByteRef; // 3 + + static RefByteContainer M42(scoped ref ByteContainer bc) + // error: `bc.GetByteRef()` may contain a reference to `bc`, whose ref-safe-to-escape is CurrentMethod. + => bc.GetByteRef(); // 4 + } + """; + + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (42,15): error CS9077: Cannot return a parameter by reference 'bc' through a ref parameter; it can only be returned in a return statement + // rbc = bc.ByteRef; // 1 + Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "bc").WithArguments("bc").WithLocation(42, 15), + // (47,15): error CS9077: Cannot return a parameter by reference 'bc' through a ref parameter; it can only be returned in a return statement + // rbc = bc.GetByteRef(); // 2 + Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "bc").WithArguments("bc").WithLocation(47, 15), + // (60,12): error CS9075: Cannot return a parameter by reference 'bc' because it is scoped to the current method + // => bc.ByteRef; // 3 + Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "bc").WithArguments("bc").WithLocation(60, 12), + // (64,12): error CS9075: Cannot return a parameter by reference 'bc' because it is scoped to the current method + // => bc.GetByteRef(); // 4 + Diagnostic(ErrorCode.ERR_RefReturnScopedParameter, "bc").WithArguments("bc").WithLocation(64, 12)); + } + + // This is a clone of PatternIndex_01 from RefFieldTests.cs + [Fact] + public void PatternIndex_01_DirectInterface() + { + string source = """ + using System; + using System.Diagnostics.CodeAnalysis; + interface R + { + public int Length {get;} + [UnscopedRef] public ref int this[int i] {get;} + } + class Program + { + static ref int F1(ref R r1) + { + ref int i1 = ref r1[^1]; + return ref i1; + } + static ref int F2(ref R r2, Index i) + { + ref int i2 = ref r2[i]; + return ref i2; + } + static ref int F3() + { + R r3 = GetR(); + ref int i3 = ref r3[^3]; + return ref i3; // 1 + } + static ref int F4(Index i) + { + R r4 = GetR(); + ref int i4 = ref r4[i]; + return ref i4; // 2 + } + + static R GetR() => null; + } + """; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyDiagnostics(); + } + + // This is a clone of PatternIndex_01 from RefFieldTests.cs + [Theory] + [CombinatorialData] + public void PatternIndex_01_ConstrainedTypeParameter(bool addStructConstraint) + { + string source = $$""" + using System; + using System.Diagnostics.CodeAnalysis; + interface R + { + public int Length {get;} + [UnscopedRef] public ref int this[int i] {get;} + } + class Program where TR : {{(addStructConstraint ? "struct, " : "")}} R {{(!addStructConstraint ? ", new()" : "")}} + { + static ref int F1(ref TR r1) + { + ref int i1 = ref r1[^1]; + return ref i1; + } + static ref int F2(ref TR r2, Index i) + { + ref int i2 = ref r2[i]; + return ref i2; + } + static ref int F3() + { + TR r3 = new TR(); + ref int i3 = ref r3[^3]; + return ref i3; // 1 + } + static ref int F4(Index i) + { + TR r4 = new TR(); + ref int i4 = ref r4[i]; + return ref i4; // 2 + } + } + """; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyDiagnostics( + // (24,20): error CS8157: Cannot return 'i3' by reference because it was initialized to a value that cannot be returned by reference + // return ref i3; // 1 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "i3").WithArguments("i3").WithLocation(24, 20), + // (30,20): error CS8157: Cannot return 'i4' by reference because it was initialized to a value that cannot be returned by reference + // return ref i4; // 2 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "i4").WithArguments("i4").WithLocation(30, 20)); + } + + // This is a clone of PatternIndex_01 from RefFieldTests.cs + [Fact] + public void PatternIndex_01_ClassConstrainedTypeParameter() + { + string source = """ + using System; + using System.Diagnostics.CodeAnalysis; + interface R + { + public int Length {get;} + [UnscopedRef] public ref int this[int i] {get;} + } + class Program where TR : class, R, new() + { + static ref int F1(ref TR r1) + { + ref int i1 = ref r1[^1]; + return ref i1; + } + static ref int F2(ref TR r2, Index i) + { + ref int i2 = ref r2[i]; + return ref i2; + } + static ref int F3() + { + TR r3 = new TR(); + ref int i3 = ref r3[^3]; + return ref i3; // 1 + } + static ref int F4(Index i) + { + TR r4 = new TR(); + ref int i4 = ref r4[i]; + return ref i4; // 2 + } + } + """; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyDiagnostics(); + } + + // This is a clone of MemberOfReadonlyRefLikeEscape from RefEscapingTests.cs + [Fact] + public void MemberOfReadonlyRefLikeEscape_DirectInterface() + { + var text = @" + using System; + using System.Diagnostics.CodeAnalysis; + public static class Program + { + public static void Main() + { + Span value1 = stackalloc int[1]; + + // Ok, the new value can be copied into SW but not the + // ref to the value + Get_SW().TryGet(out value1); + + // Error as the ref of this can escape into value2 + Span value2 = default; + Get_SW().TryGet2(out value2); + } + + static SW Get_SW() => throw null; + } + + interface SW + { + public void TryGet(out Span result); + + [UnscopedRef] + public void TryGet2(out Span result); + } +"; + CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }).VerifyDiagnostics(); + } + + // This is a clone of MemberOfReadonlyRefLikeEscape from RefEscapingTests.cs + [Theory] + [CombinatorialData] + public void MemberOfReadonlyRefLikeEscape_ConstrainedTypeParameter(bool addStructConstraint) + { + var text = @" + using System; + using System.Diagnostics.CodeAnalysis; + static class Program where TSW : " + (addStructConstraint ? "struct, " : "") + @"SW" + (!addStructConstraint ? ", new()" : "") + @" + { + public static void Main() + { + Span value1 = stackalloc int[1]; + + // Ok, the new value can be copied into SW but not the + // ref to the value + new TSW().TryGet(out value1); + + // Error as the ref of this can escape into value2 + Span value2 = default; + new TSW().TryGet2(out value2); + } + } + + interface SW + { + public void TryGet(out Span result); + + [UnscopedRef] + public void TryGet2(out Span result); + } +"; + CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }).VerifyDiagnostics( + // 0.cs(16,13): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference + // new TSW().TryGet2(out value2); + Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "new TSW()").WithLocation(16, 13), + // 0.cs(16,13): error CS8350: This combination of arguments to 'SW.TryGet2(out Span)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope + // new TSW().TryGet2(out value2); + Diagnostic(ErrorCode.ERR_CallArgMixing, "new TSW().TryGet2(out value2)").WithArguments("SW.TryGet2(out System.Span)", "this").WithLocation(16, 13) + ); + } + + // This is a clone of MemberOfReadonlyRefLikeEscape from RefEscapingTests.cs + [Fact] + public void MemberOfReadonlyRefLikeEscape_ClassConstrainedTypeParameter() + { + var text = @" + using System; + using System.Diagnostics.CodeAnalysis; + static class Program where TSW : class, SW, new() + { + public static void Main() + { + Span value1 = stackalloc int[1]; + + // Ok, the new value can be copied into SW but not the + // ref to the value + new TSW().TryGet(out value1); + + // Error as the ref of this can escape into value2 + Span value2 = default; + new TSW().TryGet2(out value2); + } + } + + interface SW + { + public void TryGet(out Span result); + + [UnscopedRef] + public void TryGet2(out Span result); + } +"; + CreateCompilationWithMscorlibAndSpan(new[] { text, UnscopedRefAttributeDefinition }).VerifyDiagnostics(); + } + + // This is a clone of DefensiveCopy_01 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_01_DirectInterface() + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program +{ + private static readonly Vec4 ReadOnlyVec = GetVec4(); + + static void Main() + { + // This refers to stack memory that has already been left out. + ref Vec4 local = ref Test1(); + Console.WriteLine(local); + } + + private static ref Vec4 Test1() + { + // Defensive copy occurs and it is placed in stack memory implicitly. + // The method returns a reference to the copy, which happens invalid memory access. + ref Vec4 xyzw1 = ref ReadOnlyVec.Self; + return ref xyzw1; + } + + private static ref Vec4 Test2() + { + var copy = ReadOnlyVec; + ref Vec4 xyzw2 = ref copy.Self; + return ref xyzw2; + } + + private static ref Vec4 Test3() + { + ref Vec4 xyzw3 = ref ReadOnlyVec.Self2(); + return ref xyzw3; + } + + private static ref Vec4 Test4() + { + var copy = ReadOnlyVec; + ref Vec4 xyzw4 = ref copy.Self2(); + return ref xyzw4; + } + + static Vec4 GetVec4() => throw null; +} + +public interface Vec4 +{ + [UnscopedRef] + public ref Vec4 Self {get;} + + [UnscopedRef] + public ref Vec4 Self2(); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_01 from RefEscapingTests.cs + [Theory] + [CombinatorialData] + public void DefensiveCopy_01_ConstrainedTypeParameter(bool addStructConstraint) + { + var source = +@" +using System; +using System.Runtime.CompilerServices; +using System.Diagnostics.CodeAnalysis; + +internal class Program where TVec4 : " + (addStructConstraint ? "struct, " : "") + @" Vec4 +{ + private static readonly TVec4 ReadOnlyVec = GetVec4(); + + static void Main() + { + // This refers to stack memory that has already been left out. + ref TVec4 local = ref Test1(); + Console.WriteLine(local); + } + + private static ref TVec4 Test1() + { + // Defensive copy occurs and it is placed in stack memory implicitly. + // The method returns a reference to the copy, which happens invalid memory access. + ref TVec4 xyzw1 = ref ReadOnlyVec.Self; + return ref xyzw1; + } + + private static ref TVec4 Test2() + { + var copy = ReadOnlyVec; + ref TVec4 xyzw2 = ref copy.Self; + return ref xyzw2; + } + + private static ref TVec4 Test3() + { + ref TVec4 xyzw3 = ref ReadOnlyVec.Self2(); + return ref xyzw3; + } + + private static ref TVec4 Test4() + { + var copy = ReadOnlyVec; + ref TVec4 xyzw4 = ref copy.Self2(); + return ref xyzw4; + } + + static TVec4 GetVec4() => throw null; +} + +public interface Vec4 where TVec4 : Vec4 +{ + [UnscopedRef] + public ref TVec4 Self {get;} + + [UnscopedRef] + public ref TVec4 Self2(); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics( + // (22,20): error CS8157: Cannot return 'xyzw1' by reference because it was initialized to a value that cannot be returned by reference + // return ref xyzw1; + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw1").WithArguments("xyzw1").WithLocation(22, 20), + // (29,20): error CS8157: Cannot return 'xyzw2' by reference because it was initialized to a value that cannot be returned by reference + // return ref xyzw2; + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw2").WithArguments("xyzw2").WithLocation(29, 20), + // (35,20): error CS8157: Cannot return 'xyzw3' by reference because it was initialized to a value that cannot be returned by reference + // return ref xyzw3; + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw3").WithArguments("xyzw3").WithLocation(35, 20), + // (42,20): error CS8157: Cannot return 'xyzw4' by reference because it was initialized to a value that cannot be returned by reference + // return ref xyzw4; + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "xyzw4").WithArguments("xyzw4").WithLocation(42, 20) + ); + } + + // This is a clone of DefensiveCopy_01 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_01_ClassConstrainedTypeParameter() + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program where TVec4 : class, Vec4 +{ + private static readonly TVec4 ReadOnlyVec = GetVec4(); + + static void Main() + { + // This refers to stack memory that has already been left out. + ref TVec4 local = ref Test1(); + Console.WriteLine(local); + } + + private static ref TVec4 Test1() + { + // Defensive copy occurs and it is placed in stack memory implicitly. + // The method returns a reference to the copy, which happens invalid memory access. + ref TVec4 xyzw1 = ref ReadOnlyVec.Self; + return ref xyzw1; + } + + private static ref TVec4 Test2() + { + var copy = ReadOnlyVec; + ref TVec4 xyzw2 = ref copy.Self; + return ref xyzw2; + } + + private static ref TVec4 Test3() + { + ref TVec4 xyzw3 = ref ReadOnlyVec.Self2(); + return ref xyzw3; + } + + private static ref TVec4 Test4() + { + var copy = ReadOnlyVec; + ref TVec4 xyzw4 = ref copy.Self2(); + return ref xyzw4; + } + + static TVec4 GetVec4() => throw null; +} + +public interface Vec4 where TVec4 : Vec4 +{ + [UnscopedRef] + public ref TVec4 Self {get;} + + [UnscopedRef] + public ref TVec4 Self2(); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_02 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_02_DirectInterface() + { + var source = +@"using System.Diagnostics.CodeAnalysis; + +class Program +{ + static ref Wrap m1(in Wrap i) + { + ref Wrap r1 = ref i.Self; // defensive copy + return ref r1; // ref to the local copy + } + + static ref Wrap m2(in Wrap i) + { + var copy = i; + ref Wrap r2 = ref copy.Self; + return ref r2; // ref to the local copy + } + + static ref Wrap m3(in Wrap i) + { + ref Wrap r3 = ref i.Self2(); + return ref r3; + } + + static ref Wrap m4(in Wrap i) + { + var copy = i; + ref Wrap r4 = ref copy.Self2(); + return ref r4; // ref to the local copy + } +} + +interface Wrap +{ + [UnscopedRef] + public ref Wrap Self {get;} + + [UnscopedRef] + public ref Wrap Self2(); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_02 from RefEscapingTests.cs + [Theory] + [CombinatorialData] + public void DefensiveCopy_02_ConstrainedTypeParameter(bool addStructConstraint) + { + var source = +@"using System.Diagnostics.CodeAnalysis; + +class Program where TWrap : " + (addStructConstraint ? "struct, " : "") + @"Wrap +{ + static ref TWrap m1(in TWrap i) + { + ref TWrap r1 = ref i.Self; // defensive copy + return ref r1; // ref to the local copy + } + + static ref TWrap m2(in TWrap i) + { + var copy = i; + ref TWrap r2 = ref copy.Self; + return ref r2; // ref to the local copy + } + + static ref TWrap m3(in TWrap i) + { + ref TWrap r3 = ref i.Self2(); + return ref r3; + } + + static ref TWrap m4(in TWrap i) + { + var copy = i; + ref TWrap r4 = ref copy.Self2(); + return ref r4; // ref to the local copy + } +} + +interface Wrap where T : Wrap +{ + [UnscopedRef] + public ref T Self {get;} + + [UnscopedRef] + public ref T Self2(); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics( + // (8,20): error CS8157: Cannot return 'r1' by reference because it was initialized to a value that cannot be returned by reference + // return ref r1; // ref to the local copy + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r1").WithArguments("r1").WithLocation(8, 20), + // (15,20): error CS8157: Cannot return 'r2' by reference because it was initialized to a value that cannot be returned by reference + // return ref r2; // ref to the local copy + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r2").WithArguments("r2").WithLocation(15, 20), + // (21,20): error CS8157: Cannot return 'r3' by reference because it was initialized to a value that cannot be returned by reference + // return ref r3; + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r3").WithArguments("r3").WithLocation(21, 20), + // (28,20): error CS8157: Cannot return 'r4' by reference because it was initialized to a value that cannot be returned by reference + // return ref r4; // ref to the local copy + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "r4").WithArguments("r4").WithLocation(28, 20) + ); + } + + // This is a clone of DefensiveCopy_02 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_02_ClassConstrainedTypeParameter() + { + var source = +@"using System.Diagnostics.CodeAnalysis; + +class Program where TWrap : class, Wrap +{ + static ref TWrap m1(in TWrap i) + { + ref TWrap r1 = ref i.Self; // defensive copy + return ref r1; // ref to the local copy + } + + static ref TWrap m2(in TWrap i) + { + var copy = i; + ref TWrap r2 = ref copy.Self; + return ref r2; // ref to the local copy + } + + static ref TWrap m3(in TWrap i) + { + ref TWrap r3 = ref i.Self2(); + return ref r3; + } + + static ref TWrap m4(in TWrap i) + { + var copy = i; + ref TWrap r4 = ref copy.Self2(); + return ref r4; // ref to the local copy + } +} + +interface Wrap where T : Wrap +{ + [UnscopedRef] + public ref T Self {get;} + + [UnscopedRef] + public ref T Self2(); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_05 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_05_DirectInterface() + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program +{ + private static readonly Vec4 ReadOnlyVec = default; + + static void Main() + { + } + + private static Span Test1() + { + var xyzw1 = ReadOnlyVec.Self; + return xyzw1; + } + + private static Span Test2() + { + var r2 = ReadOnlyVec; + var xyzw2 = r2.Self; + return xyzw2; + } +} + +public interface Vec4 +{ + [UnscopedRef] + public Span Self + { get; set; } +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_05 from RefEscapingTests.cs + [Theory] + [CombinatorialData] + public void DefensiveCopy_05_ConstrainedTypeParameter(bool addStructConstraint) + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program where TVec4 : " + (addStructConstraint ? "struct, " : "") + @" Vec4 +{ + private static readonly TVec4 ReadOnlyVec = default; + + static void Main() + { + } + + private static Span Test1() + { + var xyzw1 = ReadOnlyVec.Self; + return xyzw1; + } + + private static Span Test2() + { + var r2 = ReadOnlyVec; + var xyzw2 = r2.Self; + return xyzw2; + } +} + +public interface Vec4 +{ + [UnscopedRef] + public Span Self + { get; set; } +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics( + // (16,16): error CS8352: Cannot use variable 'xyzw1' in this context because it may expose referenced variables outside of their declaration scope + // return xyzw1; + Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw1").WithArguments("xyzw1").WithLocation(16, 16), + // (23,16): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope + // return xyzw2; + Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(23, 16) + ); + } + + // This is a clone of DefensiveCopy_05 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_05_ClassConstrainedTypeParameter() + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program where TVec4 : class, Vec4 +{ + private static readonly TVec4 ReadOnlyVec = default; + + static void Main() + { + } + + private static Span Test1() + { + var xyzw1 = ReadOnlyVec.Self; + return xyzw1; + } + + private static Span Test2() + { + var r2 = ReadOnlyVec; + var xyzw2 = r2.Self; + return xyzw2; + } +} + +public interface Vec4 +{ + [UnscopedRef] + public Span Self + { get; set; } +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_21 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_21_DirectInterface() + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program +{ + private static readonly Vec4 ReadOnlyVec = default; + + static void Main() + { + } + + private static Span Test1() + { + var (xyzw1, _) = ReadOnlyVec; + return xyzw1; + } + + private static Span Test2() + { + var r2 = ReadOnlyVec; + var (xyzw2, _) = r2; + return xyzw2; + } + + private static Span Test3() + { + ReadOnlyVec.Deconstruct(out var xyzw3, out _); + return xyzw3; + } + + private static Span Test4() + { + var r4 = ReadOnlyVec; + r4.Deconstruct(out var xyzw4, out _); + return xyzw4; + } +} + +public interface Vec4 +{ + [UnscopedRef] + public void Deconstruct(out Span x, out int i); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + // This is a clone of DefensiveCopy_21 from RefEscapingTests.cs + [Theory] + [CombinatorialData] + public void DefensiveCopy_21_ConstrainedTypeParameter(bool addStructConstraint) + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program where TVec4 : " + (addStructConstraint ? "struct, " : "") + @" Vec4 +{ + private static readonly TVec4 ReadOnlyVec = default; + + static void Main() + { + } + + private static Span Test1() + { + var (xyzw1, _) = ReadOnlyVec; + return xyzw1; + } + + private static Span Test2() + { + var r2 = ReadOnlyVec; + var (xyzw2, _) = r2; + return xyzw2; + } + + private static Span Test3() + { + ReadOnlyVec.Deconstruct(out var xyzw3, out _); + return xyzw3; + } + + private static Span Test4() + { + var r4 = ReadOnlyVec; + r4.Deconstruct(out var xyzw4, out _); + return xyzw4; + } +} + +public interface Vec4 +{ + [UnscopedRef] + public void Deconstruct(out Span x, out int i); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics( + // (16,16): error CS8352: Cannot use variable 'xyzw1' in this context because it may expose referenced variables outside of their declaration scope + // return xyzw1; + Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw1").WithArguments("xyzw1").WithLocation(16, 16), + // (23,16): error CS8352: Cannot use variable 'xyzw2' in this context because it may expose referenced variables outside of their declaration scope + // return xyzw2; + Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw2").WithArguments("xyzw2").WithLocation(23, 16), + // (29,16): error CS8352: Cannot use variable 'xyzw3' in this context because it may expose referenced variables outside of their declaration scope + // return xyzw3; + Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw3").WithArguments("xyzw3").WithLocation(29, 16), + // (36,16): error CS8352: Cannot use variable 'xyzw4' in this context because it may expose referenced variables outside of their declaration scope + // return xyzw4; + Diagnostic(ErrorCode.ERR_EscapeVariable, "xyzw4").WithArguments("xyzw4").WithLocation(36, 16) + ); + } + + // This is a clone of DefensiveCopy_21 from RefEscapingTests.cs + [Fact] + public void DefensiveCopy_21_ClassConstrainedTypeParameter() + { + var source = +@" +using System; +using System.Diagnostics.CodeAnalysis; + +internal class Program where TVec4 : class, Vec4 +{ + private static readonly TVec4 ReadOnlyVec = default; + + static void Main() + { + } + + private static Span Test1() + { + var (xyzw1, _) = ReadOnlyVec; + return xyzw1; + } + + private static Span Test2() + { + var r2 = ReadOnlyVec; + var (xyzw2, _) = r2; + return xyzw2; + } + + private static Span Test3() + { + ReadOnlyVec.Deconstruct(out var xyzw3, out _); + return xyzw3; + } + + private static Span Test4() + { + var r4 = ReadOnlyVec; + r4.Deconstruct(out var xyzw4, out _); + return xyzw4; + } +} + +public interface Vec4 +{ + [UnscopedRef] + public void Deconstruct(out Span x, out int i); +} +"; + var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void AllowsConstraint_01_SimpleTypeTypeParameter() + { + var src = @" +public class C + where T : allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + var c = m.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + Assert.True(t.GetPublicSymbol().AllowsRefLikeType); + AssertEx.Equal("C where T : allows ref struct", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + Assert.True(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)); + + CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (3,22): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(3, 22) + ); + + comp = CreateCompilation(src, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.RegularNext).VerifyDiagnostics( + // (3,22): error CS9240: Target runtime doesn't support by-ref-like generics. + // where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(3, 22) + ); + Assert.False(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)); + + comp = CreateCompilation(src, targetFramework: TargetFramework.Net80, parseOptions: TestOptions.RegularNext).VerifyDiagnostics( + // (3,22): error CS9240: Target runtime doesn't support by-ref-like generics. + // where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(3, 22) + ); + Assert.False(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)); + } + + [Fact] + public void AllowsConstraint_02_SimpleMethodTypeParameter() + { + var src = @" +public class C +{ + public void M() + where T : allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + var method = m.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (5,26): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(5, 26) + ); + + CreateCompilation(src, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.RegularNext).VerifyDiagnostics( + // (5,26): error CS9240: Target runtime doesn't support by-ref-like generics. + // where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(5, 26) + ); + } + + [Fact] + public void AllowsConstraint_03_TwoRefStructInARow() + { + var src = @" +public class C + where T : allows ref struct, ref struct +{ +} + +public class D + where T : allows ref struct, ref +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,34): error CS9241: 'ref struct' is already specified. + // where T : allows ref struct, ref struct + Diagnostic(ErrorCode.ERR_RefStructConstraintAlreadySpecified, "ref struct").WithLocation(3, 34), + // (8,34): error CS9241: 'ref struct' is already specified. + // where T : allows ref struct, ref + Diagnostic(ErrorCode.ERR_RefStructConstraintAlreadySpecified, @"ref +").WithLocation(8, 34), + // (8,37): error CS1003: Syntax error, 'struct' expected + // where T : allows ref struct, ref + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("struct").WithLocation(8, 37) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + + var d = comp.SourceModule.GlobalNamespace.GetMember("D"); + var dt = d.TypeParameters.Single(); + Assert.False(dt.HasReferenceTypeConstraint); + Assert.False(dt.HasValueTypeConstraint); + Assert.False(dt.HasUnmanagedTypeConstraint); + Assert.False(dt.HasNotNullConstraint); + Assert.True(dt.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_04_TwoAllows() + { + var src = @" +public class C + where T : allows ref struct, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, allows ref struct + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var ct = c.TypeParameters.Single(); + Assert.False(ct.HasReferenceTypeConstraint); + Assert.False(ct.HasValueTypeConstraint); + Assert.False(ct.HasUnmanagedTypeConstraint); + Assert.False(ct.HasNotNullConstraint); + Assert.True(ct.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_05_FollowedByStruct() + { + var src = @" +public class C + where T : allows ref struct, struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, struct + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15), + // (3,34): error CS0449: The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list. + // where T : allows ref struct, struct + Diagnostic(ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst, "struct").WithLocation(3, 34) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.True(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_06_AfterStruct() + { + var src = @" +public class C + where T : struct, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.True(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_07_FollowedByClass() + { + var src = @" +public class C + where T : allows ref struct, class +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (2,16): error CS9243: Cannot allow ref structs for a type parameter known from other constraints to be a class + // public class C + Diagnostic(ErrorCode.ERR_ClassIsCombinedWithRefStruct, "T").WithLocation(2, 16), + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, class + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15), + // (3,34): error CS0449: The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list. + // where T : allows ref struct, class + Diagnostic(ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst, "class").WithLocation(3, 34) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.True(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_08_AfterClass() + { + var src = @" +public class C + where T : class, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (2,16): error CS9243: Cannot allow ref structs for a type parameter known from other constraints to be a class + // public class C + Diagnostic(ErrorCode.ERR_ClassIsCombinedWithRefStruct, "T").WithLocation(2, 16) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.True(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_09_FollowedByDefault() + { + var src = @" +public class C + where T : allows ref struct, default +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15), + // (3,34): error CS8823: The 'default' constraint is valid on override and explicit interface implementation methods only. + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_DefaultConstraintOverrideOnly, "default").WithLocation(3, 34), + // (3,34): error CS0449: The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list. + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst, "default").WithLocation(3, 34) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_10_FollowedByDefault() + { + var src = @" +public class C +{ + public void M() + where T : allows ref struct, default + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (5,19): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(5, 19), + // (5,38): error CS8823: The 'default' constraint is valid on override and explicit interface implementation methods only. + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_DefaultConstraintOverrideOnly, "default").WithLocation(5, 38), + // (5,38): error CS0449: The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list. + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst, "default").WithLocation(5, 38) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_11_FollowedByDefault() + { + var src = @" +public class C : B +{ + public override void M() + where T : allows ref struct, default + { + } +} + +public class B +{ + public virtual void M() + where T : allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (5,19): error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except for either a 'class', or a 'struct' constraint. + // where T : allows ref struct, default + Diagnostic(ErrorCode.ERR_OverrideWithConstraints, "allows ref struct").WithLocation(5, 19) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_12_AfterDefault() + { + var src = @" +public class C + where T : default, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS8823: The 'default' constraint is valid on override and explicit interface implementation methods only. + // where T : default, allows ref struct + Diagnostic(ErrorCode.ERR_DefaultConstraintOverrideOnly, "default").WithLocation(3, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_13_AfterDefault() + { + var src = @" +public class C +{ + public void M() + where T : default, allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (5,19): error CS8823: The 'default' constraint is valid on override and explicit interface implementation methods only. + // where T : default, allows ref struct + Diagnostic(ErrorCode.ERR_DefaultConstraintOverrideOnly, "default").WithLocation(5, 19) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_14_AfterDefault() + { + var src = @" +public class C : B +{ + public override void M() + where T : default, allows ref struct + { + } +} + +public class B +{ + public virtual void M() + where T : allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (5,28): error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except for either a 'class', or a 'struct' constraint. + // where T : default, allows ref struct + Diagnostic(ErrorCode.ERR_OverrideWithConstraints, "allows ref struct").WithLocation(5, 28) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_15_FollowedByUnmanaged() + { + var src = @" +public class C + where T : allows ref struct, unmanaged +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, unmanaged + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15), + // (3,34): error CS0449: The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list. + // where T : allows ref struct, unmanaged + Diagnostic(ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst, "unmanaged").WithLocation(3, 34) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_16_AfterUnmanaged() + { + var src = @" +public class C + where T : unmanaged, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.True(t.HasValueTypeConstraint); + Assert.True(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_17_FollowedByNotNull() + { + var src = @" +public class C + where T : allows ref struct, notnull +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, notnull + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15), + // (3,34): error CS0449: The 'class', 'struct', 'unmanaged', 'notnull', and 'default' constraints cannot be combined or duplicated, and must be specified first in the constraints list. + // where T : allows ref struct, notnull + Diagnostic(ErrorCode.ERR_TypeConstraintsMustBeUniqueAndFirst, "notnull").WithLocation(3, 34) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.True(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_18_AfterNotNull() + { + var src = @" +public class C + where T : notnull, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.True(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_19_FollowedByType() + { + var src = @" +public class C + where T : allows ref struct, I1 +{ +} + +public interface I1 {} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, notnull + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + + Assert.Equal("I1", t.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_20_AfterType() + { + var src = @" +public class C + where T : I1, allows ref struct +{ +} + +public interface I1 {} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + + Assert.Equal("I1", t.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_21_AfterClassType() + { + var src = @" +public class C + where T : C1, allows ref struct +{ +} + +public class C1 {} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (2,16): error CS9243: Cannot allow ref structs for a type parameter known from other constraints to be a class + // public class C + Diagnostic(ErrorCode.ERR_ClassIsCombinedWithRefStruct, "T").WithLocation(2, 16) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + + Assert.Equal("C1", t.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_22_AfterSystemValueType() + { + var src = @" +public class C + where T : System.ValueType, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS0702: Constraint cannot be special class 'ValueType' + // where T : System.ValueType, allows ref struct + Diagnostic(ErrorCode.ERR_SpecialTypeAsBound, "System.ValueType").WithArguments("System.ValueType").WithLocation(3, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + + Assert.Empty(t.ConstraintTypesNoUseSiteDiagnostics); + + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_23_AfterSystemEnum() + { + var src = @" +public class C + where T : System.Enum, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + + Assert.Equal("System.Enum", t.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_24_FollowedByNew() + { + var src = @" +public class C + where T : allows ref struct, new() +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (3,15): error CS9242: The 'allows' constraint clause must be the last constraint specified + // where T : allows ref struct, new() + Diagnostic(ErrorCode.ERR_AllowsClauseMustBeLast, "allows").WithLocation(3, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.HasConstructorConstraint); + Assert.True(t.AllowsRefLikeType); + AssertEx.Equal("C where T : new(), allows ref struct", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + [Fact] + public void AllowsConstraint_25_AfterNew() + { + var src = @" +public class C + where T : new(), allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.HasConstructorConstraint); + Assert.True(t.AllowsRefLikeType); + AssertEx.Equal("C where T : new(), allows ref struct", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + + [Fact] + public void AllowsConstraint_26_PartialTypes() + { + var src = @" +partial class C where T : allows ref struct +{ +} + +partial class C where T : allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_27_PartialTypes() + { + var src = @" +partial class C +{ +} + +partial class C where T : allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_28_PartialTypes() + { + var src = @" +partial class C where T : allows ref struct +{ +} + +partial class C +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_29_PartialTypes() + { + var src = @" +partial class C where T : struct +{ +} + +partial class C where T : struct, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (2,15): error CS0265: Partial declarations of 'C' have inconsistent constraints for type parameter 'T' + // partial class C where T : struct + Diagnostic(ErrorCode.ERR_PartialWrongConstraints, "C").WithArguments("C", "T").WithLocation(2, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_30_PartialTypes() + { + var src = @" +partial class C where T : struct, allows ref struct +{ +} + +partial class C where T : struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (2,15): error CS0265: Partial declarations of 'C' have inconsistent constraints for type parameter 'T' + // partial class C where T : struct, allows ref struct + Diagnostic(ErrorCode.ERR_PartialWrongConstraints, "C").WithArguments("C", "T").WithLocation(2, 15) + ); + + var c = comp.SourceModule.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_31_PartialMethod() + { + var src = @" +partial class C +{ + partial void M() where T : allows ref struct; +} + +partial class C +{ + partial void M() where T : allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_32_PartialMethod() + { + var src = @" +partial class C +{ + partial void M(); +} + +partial class C +{ + partial void M() where T : allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (9,18): error CS0761: Partial method declarations of 'C.M()' have inconsistent constraints for type parameter 'T' + // partial void M() where T : allows ref struct + Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M").WithArguments("C.M()", "T").WithLocation(9, 18) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_33_PartialMethod() + { + var src = @" +partial class C +{ + partial void M() where T : allows ref struct; +} + +partial class C +{ + partial void M() + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (9,18): error CS0761: Partial method declarations of 'C.M()' have inconsistent constraints for type parameter 'T' + // partial void M() + Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M").WithArguments("C.M()", "T").WithLocation(9, 18) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_34_PartialMethod() + { + var src = @" +partial class C +{ + partial void M() where T : struct; +} + +partial class C +{ + partial void M() where T : struct, allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (9,18): error CS0761: Partial method declarations of 'C.M()' have inconsistent constraints for type parameter 'T' + // partial void M() where T : struct, allows ref struct + Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M").WithArguments("C.M()", "T").WithLocation(9, 18) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.False(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_35_PartialMethod() + { + var src = @" +partial class C +{ + partial void M() where T : struct, allows ref struct; +} + +partial class C +{ + partial void M() where T : struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (9,18): error CS0761: Partial method declarations of 'C.M()' have inconsistent constraints for type parameter 'T' + // partial void M() where T : struct + Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M").WithArguments("C.M()", "T").WithLocation(9, 18) + ); + + var method = comp.SourceModule.GlobalNamespace.GetMember("C.M"); + var t = method.TypeParameters.Single(); + Assert.True(t.AllowsRefLikeType); + } + + [Fact] + public void AllowsConstraint_36_InheritedByOverride() + { + var src = @" +class C1 +{ + public virtual void M1() where T : allows ref struct + { + } + public virtual void M2() where T : unmanaged + { + } +} + +class C2 : C1 +{ + public override void M1() where T : allows ref struct + { + } +} + +class C3 : C1 +{ + public override void M2() where T : unmanaged + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (14,44): error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except for either a 'class', or a 'struct' constraint. + // public override void M1() where T : allows ref struct + Diagnostic(ErrorCode.ERR_OverrideWithConstraints, "allows ref struct").WithLocation(14, 44), + // (21,44): error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except for either a 'class', or a 'struct' constraint. + // public override void M2() where T : unmanaged + Diagnostic(ErrorCode.ERR_OverrideWithConstraints, "unmanaged").WithLocation(21, 44) + ); + + var method1 = comp.SourceModule.GlobalNamespace.GetMember("C2.M1"); + var t1 = method1.TypeParameters.Single(); + Assert.True(t1.AllowsRefLikeType); + + var method2 = comp.SourceModule.GlobalNamespace.GetMember("C3.M2"); + var t2 = method2.TypeParameters.Single(); + Assert.True(t2.HasUnmanagedTypeConstraint); + } + + [Fact] + public void AllowsConstraint_37_InheritedByOverride() + { + var src1 = @" +public class C1 +{ + public virtual void M1() where T : allows ref struct + { + } + public virtual void M2() where T : unmanaged + { + } +} +"; + + var src2 = @" +class C2 : C1 +{ + public override void M1() + { + } + public override void M2() + { + } +} +"; + var comp1 = CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp1.VerifyDiagnostics(); + + var method1 = comp1.SourceModule.GlobalNamespace.GetMember("C2.M1"); + var t1 = method1.TypeParameters.Single(); + Assert.True(t1.AllowsRefLikeType); + + var method2 = comp1.SourceModule.GlobalNamespace.GetMember("C2.M2"); + var t2 = method2.TypeParameters.Single(); + Assert.True(t2.HasUnmanagedTypeConstraint); + + CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,29): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public override void M1() + Diagnostic(ErrorCode.ERR_FeatureInPreview, "T").WithArguments("ref struct interfaces").WithLocation(4, 29) + ); + + var comp2 = CreateCompilation(src1, targetFramework: TargetFramework.Net70); + + CreateCompilation(src2, references: [comp2.ToMetadataReference()], targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (4,29): error CS9240: Target runtime doesn't support by-ref-like generics. + // public override void M1() + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "T").WithLocation(4, 29) + ); + } + + [Fact] + public void AllowsConstraint_38_InheritedByOverride() + { + var src = @" +class C1 +{ + public virtual void M1() where T : S, allows ref struct + { + } + public virtual void M2() where T : class, S + { + } +} + +class C2 : C1 +{ + public override void M1() + { + } + public override void M2() + { + } +} + +class C {} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var method1 = comp.SourceModule.GlobalNamespace.GetMember("C2.M1"); + var t1 = method1.TypeParameters.Single(); + Assert.True(t1.AllowsRefLikeType); + Assert.Equal("C", t1.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + + var method2 = comp.SourceModule.GlobalNamespace.GetMember("C2.M2"); + var t2 = method2.TypeParameters.Single(); + Assert.True(t2.HasReferenceTypeConstraint); + Assert.Equal("C", t2.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + } + + [Fact] + public void AllowsConstraint_39_InheritedByExplicitImplementation() + { + var src = @" +interface C1 +{ + void M1() where T : allows ref struct; + void M2() where T : unmanaged; +} + +class C2 : C1 +{ + void C1.M1() where T : allows ref struct + { + } + + void C1.M2() where T : unmanaged + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,31): error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except for either a 'class', or a 'struct' constraint. + // void C1.M1() where T : allows ref struct + Diagnostic(ErrorCode.ERR_OverrideWithConstraints, "allows ref struct").WithLocation(10, 31), + // (14,31): error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly, except for either a 'class', or a 'struct' constraint. + // void C1.M2() where T : unmanaged + Diagnostic(ErrorCode.ERR_OverrideWithConstraints, "unmanaged").WithLocation(14, 31) + ); + + var method1 = comp.SourceModule.GlobalNamespace.GetMember("C2.C1.M1"); + var t1 = method1.TypeParameters.Single(); + Assert.True(t1.AllowsRefLikeType); + + var method2 = comp.SourceModule.GlobalNamespace.GetMember("C2.C1.M2"); + var t2 = method2.TypeParameters.Single(); + Assert.True(t2.HasUnmanagedTypeConstraint); + } + + [Fact] + public void AllowsConstraint_40_InheritedByExplicitImplementation() + { + var src1 = @" +public interface C1 +{ + void M1() where T : allows ref struct; + void M2() where T : unmanaged; +} +"; + + var src2 = @" +class C2 : C1 +{ + void C1.M1() + { + } + void C1.M2() + { + } +} +"; + var comp1 = CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp1.VerifyDiagnostics(); + + var method1 = comp1.SourceModule.GlobalNamespace.GetMember("C2.C1.M1"); + var t1 = method1.TypeParameters.Single(); + Assert.True(t1.AllowsRefLikeType); + + var method2 = comp1.SourceModule.GlobalNamespace.GetMember("C2.C1.M2"); + var t2 = method2.TypeParameters.Single(); + Assert.True(t2.HasUnmanagedTypeConstraint); + + CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + + CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,16): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // void C1.M1() + Diagnostic(ErrorCode.ERR_FeatureInPreview, "T").WithArguments("ref struct interfaces").WithLocation(4, 16) + ); + + var comp2 = CreateCompilation(src1, targetFramework: TargetFramework.Net70); + + CreateCompilation(src2, references: [comp2.ToMetadataReference()], targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (4,16): error CS9240: Target runtime doesn't support by-ref-like generics. + // void C1.M1() + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "T").WithLocation(4, 16) + ); + } + + [Fact] + public void AllowsConstraint_41_InheritedByExplicitImplementation() + { + var src = @" +interface C1 +{ + void M1() where T : S, allows ref struct; + void M2() where T : class, S; +} + +class C2 : C1 +{ + void C1.M1() + { + } + void C1.M2() + { + } +} + +class C {} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + + var method1 = comp.SourceModule.GlobalNamespace.GetMember("C2.C1.M1"); + var t1 = method1.TypeParameters.Single(); + Assert.True(t1.AllowsRefLikeType); + Assert.Equal("C", t1.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + + var method2 = comp.SourceModule.GlobalNamespace.GetMember("C2.C1.M2"); + var t2 = method2.TypeParameters.Single(); + Assert.True(t2.HasReferenceTypeConstraint); + Assert.Equal("C", t2.ConstraintTypesNoUseSiteDiagnostics.Single().ToTestDisplayString()); + } + + [Fact] + public void AllowsConstraint_42_ImplicitImplementationMustMatch() + { + var src = @" +interface C1 +{ + void M1() where T : allows ref struct; + void M2() where T : unmanaged; +} + +class C2 : C1 +{ + public void M1() where T : allows ref struct + { + } + + public void M2() where T : unmanaged + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics(); + } + + [Fact] + public void AllowsConstraint_43_ImplicitImplementationMustMatch() + { + var src = @" +interface C1 +{ + void M1() where T : allows ref struct; + void M2() where T : unmanaged; +} + +class C2 : C1 +{ + public void M1() + { + } + public void M2() + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,17): error CS0425: The constraints for type parameter 'T' of method 'C2.M1()' must match the constraints for type parameter 'T' of interface method 'C1.M1()'. Consider using an explicit interface implementation instead. + // public void M1() + Diagnostic(ErrorCode.ERR_ImplBadConstraints, "M1").WithArguments("T", "C2.M1()", "T", "C1.M1()").WithLocation(10, 17), + // (13,17): error CS0425: The constraints for type parameter 'T' of method 'C2.M2()' must match the constraints for type parameter 'T' of interface method 'C1.M2()'. Consider using an explicit interface implementation instead. + // public void M2() + Diagnostic(ErrorCode.ERR_ImplBadConstraints, "M2").WithArguments("T", "C2.M2()", "T", "C1.M2()").WithLocation(13, 17) + ); + } + + [Fact] + public void AllowsConstraint_44_ImplicitImplementationMustMatch() + { + var src = @" +interface C1 +{ + void M1() where T : S, allows ref struct; + void M2() where T : class, S; +} + +class C2 : C1 +{ + public void M1() where T : C, allows ref struct + { + } + public void M2() where T : class, C + { + } +} + +class C {} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,20): error CS9243: Cannot allow ref structs for a type parameter known from other constraints to be a class + // public void M1() where T : C, allows ref struct + Diagnostic(ErrorCode.ERR_ClassIsCombinedWithRefStruct, "T").WithLocation(10, 20), + // (13,17): error CS0425: The constraints for type parameter 'T' of method 'C2.M2()' must match the constraints for type parameter 'T' of interface method 'C1.M2()'. Consider using an explicit interface implementation instead. + // public void M2() where T : class, C + Diagnostic(ErrorCode.ERR_ImplBadConstraints, "M2").WithArguments("T", "C2.M2()", "T", "C1.M2()").WithLocation(13, 17), + // (13,42): error CS0450: 'C': cannot specify both a constraint class and the 'class' or 'struct' constraint + // public void M2() where T : class, C + Diagnostic(ErrorCode.ERR_RefValBoundWithClass, "C").WithArguments("C").WithLocation(13, 42) + ); + } + + [Fact] + public void AllowsConstraint_45_NotPresent() + { + var src = @" +public class C +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + var c = m.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters.Single(); + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.False(t.AllowsRefLikeType); + Assert.False(t.GetPublicSymbol().AllowsRefLikeType); + AssertEx.Equal("C", t.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + } + } + + [Fact] + public void AllowsConstraint_46() + { + var src = @" +class C + where T : allows ref struct + where U : T, allows ref struct +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + var c = m.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters[0]; + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + + var u = c.TypeParameters[1]; + Assert.False(u.HasReferenceTypeConstraint); + Assert.False(u.HasValueTypeConstraint); + Assert.False(u.HasUnmanagedTypeConstraint); + Assert.False(u.HasNotNullConstraint); + Assert.True(u.AllowsRefLikeType); + } + } + + [Fact] + public void AllowsConstraint_47() + { + var src = @" +class C + where T : allows ref struct + where U : T +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + var c = m.GlobalNamespace.GetMember("C"); + var t = c.TypeParameters[0]; + Assert.False(t.HasReferenceTypeConstraint); + Assert.False(t.HasValueTypeConstraint); + Assert.False(t.HasUnmanagedTypeConstraint); + Assert.False(t.HasNotNullConstraint); + Assert.True(t.AllowsRefLikeType); + + var u = c.TypeParameters[1]; + Assert.False(u.HasReferenceTypeConstraint); + Assert.False(u.HasValueTypeConstraint); + Assert.False(u.HasUnmanagedTypeConstraint); + Assert.False(u.HasNotNullConstraint); + Assert.False(u.AllowsRefLikeType); + } + } + + [Fact] + public void ImplementAnInterface_01() + { + var src = @" +interface I1 +{} + +ref struct S1 : I1 +{} + +struct S2 : I1 +{} +"; + var comp = CreateCompilation(src); + + CompileAndVerify(comp, sourceSymbolValidator: verify, symbolValidator: verify).VerifyDiagnostics(); + + void verify(ModuleSymbol m) + { + var s1 = m.GlobalNamespace.GetMember("S1"); + Assert.Equal("I1", s1.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); + } + + CreateCompilation(src, targetFramework: TargetFramework.Net70, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + + CreateCompilation(src, targetFramework: TargetFramework.Net70, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (5,17): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref struct S1 : I1 + Diagnostic(ErrorCode.ERR_FeatureInPreview, "I1").WithArguments("ref struct interfaces").WithLocation(5, 17) + ); + } + + [Fact] + public void ImplementAnInterface_02_IllegalBoxing() + { + var src = @" +interface I1 +{} + +ref struct S1 : I1 +{} + +class C +{ + static I1 Test1(S1 x) => x; + static I1 Test2(S1 x) => (I1)x; +} +"; + var comp = CreateCompilation(src); + + comp.VerifyDiagnostics( + // (10,30): error CS0029: Cannot implicitly convert type 'S1' to 'I1' + // static I1 Test1(S1 x) => x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("S1", "I1").WithLocation(10, 30), + // (11,30): error CS0030: Cannot convert type 'S1' to 'I1' + // static I1 Test2(S1 x) => (I1)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(I1)x").WithArguments("S1", "I1").WithLocation(11, 30) + ); + } + + [Fact] + public void ImplementAnInterface_03() + { + var src = @" +interface I1 +{ + void M1(); +} + +ref struct S1 : I1 +{ + public void M1() + { + System.Console.Write(""S1.M1""); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(T x) where T : I1 + { + x.M1(); + } +} +"; + var comp = CreateCompilation(src); + + comp.VerifyDiagnostics( + // (19,9): error CS9244: The type 'S1' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.Test(T)' + // Test(new S1()); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Test").WithArguments("C.Test(T)", "T", "S1").WithLocation(19, 9) + ); + } + + [Fact] + public void ImplementAnInterface_04() + { + var src = @" +interface I1 +{ + void M1(); +} + +ref struct S1 : I1 +{ + public void M1() + { + System.Console.Write(""S1.M1""); + } +} + +class C +{ + static void Main() + { + Test1(new S1()); + System.Console.Write("" ""); + Test2(new S1()); + } + + static void Test1(T x) where T : I1, allows ref struct + { + x.M1(); + } + + static void Test2(T x) where T : I1, allows ref struct + { + Test1(x); + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"S1.M1 S1.M1" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + verifier.VerifyIL("C.Test1(T)", +@" +{ + // Code size 14 (0xe) + .maxstack 1 + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""void I1.M1()"" + IL_000d: ret +} +"); + } + + [Fact] + public void ImplementAnInterface_05_Variance() + { + var src = @" +interface I1 +{ + void M1(T x); +} + +ref struct S1 : I1 +{ + public void M1(object x) + { + System.Console.Write(""S1.M1""); + System.Console.Write("" ""); + System.Console.Write(x); + } +} + +class C +{ + static void Main() + { + Test(new S1(), ""y""); + } + + static void Test(T x, string y) where T : I1, allows ref struct + { + x.M1(y); + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"S1.M1 y" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + verifier.VerifyIL("C.Test(T, string)", +@" +{ + // Code size 15 (0xf) + .maxstack 2 + IL_0000: ldarga.s V_0 + IL_0002: ldarg.1 + IL_0003: constrained. ""T"" + IL_0009: callvirt ""void I1.M1(string)"" + IL_000e: ret +} +"); + } + + [Fact] + public void ImplementAnInterface_06_DefaultImplementation() + { + var src1 = @" +public interface I1 +{ + virtual void M1() {} + static virtual void M2() {} + sealed void M3() {} + + public class C1 {} +} + +ref struct S1 : I1 +{ +} + +ref struct S2 : I1 +{ + public void M1() + { + } +} +"; + + var src2 = @" +class C +{ + static void Test1(I1 x) + { + x.M1(); + x.M3(); + } + + static void Test2(T x) where T : I1, allows ref struct + { + x.M1(); + T.M2(); +#line 100 + x.M3(); + _ = new T.C1(); + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.NetCoreApp); + + comp1.VerifyDiagnostics( + // (11,17): error CS9245: 'I1.M1()' cannot implement interface member 'I1.M1()' for ref struct 'S1'. + // ref struct S1 : I1 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.M1()", "I1.M1()", "S1").WithLocation(11, 17) + ); + + comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + // Specification suggests to report a warning for access to virtual (non-abstract) members. + // There is an open design question - https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#warn-on-dim-invocation + comp2.VerifyDiagnostics( + // (100,9): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // x.M3(); + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x.M3").WithLocation(100, 9), + // (101,17): error CS0704: Cannot do non-virtual member lookup in 'T' because it is a type parameter + // _ = new T.C1(); + Diagnostic(ErrorCode.ERR_LookupInTypeVariable, "T.C1").WithArguments("T").WithLocation(101, 17) + ); + } + + [Fact] + public void ImplementAnInterface_07_DefaultImplementation() + { + var src1 = @" +public interface I1 +{ + virtual int P1 => 1; + static virtual int P2 => 2; + sealed int P3 => 3; +} + +ref struct S1 : I1 +{ +} + +ref struct S2 : I1 +{ + public int P1 => 21; +} +"; + + var src2 = @" +class C +{ + static void Test1(I1 x) + { + _ = x.P1; + _ = x.P3; + } + + static void Test2(T x) where T : I1, allows ref struct + { + _ = x.P1; + _ = T.P2; +#line 100 + _ = x.P3; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.NetCoreApp); + + comp1.VerifyDiagnostics( + // (9,17): error CS9245: 'I1.P1.get' cannot implement interface member 'I1.P1.get' for ref struct 'S1'. + // ref struct S1 : I1 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.get", "I1.P1.get", "S1").WithLocation(9, 17) + ); + + comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + // Specification suggests to report a warning for access to virtual (non-abstract) members. + // There is an open design question - https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#warn-on-dim-invocation + comp2.VerifyDiagnostics( + // (100,13): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // _ = x.P3; + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x.P3").WithLocation(100, 13) + ); + } + + [Fact] + public void ImplementAnInterface_08_DefaultImplementation() + { + var src1 = @" +public interface I1 +{ + virtual int P1 {set{}} + static virtual int P2 {set{}} + sealed int P3 {set{}} +} + +ref struct S1 : I1 +{ +} + +ref struct S2 : I1 +{ + public int P1 {set{}} +} +"; + + var src2 = @" +class C +{ + static void Test1(I1 x) + { + x.P1 = 11; + x.P3 = 11; + } + + static void Test2(T x) where T : I1, allows ref struct + { + x.P1 = 123; + T.P2 = 123; + x.P3 = 123; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.NetCoreApp); + + comp1.VerifyDiagnostics( + // (9,17): error CS9245: 'I1.P1.set' cannot implement interface member 'I1.P1.set' for ref struct 'S1'. + // ref struct S1 : I1 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.set", "I1.P1.set", "S1").WithLocation(9, 17) + ); + + comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + // Specification suggests to report a warning for access to virtual (non-abstract) members. + // There is an open design question - https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#warn-on-dim-invocation + comp2.VerifyDiagnostics( + // (14,9): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // x.P3 = 123; + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x.P3").WithLocation(14, 9) + ); + } + + [Fact] + public void ImplementAnInterface_09_DefaultImplementation() + { + var src1 = @" +public interface I1 +{ + virtual int this[int x] => 1; +} + +public interface I2 +{ + sealed int this[long x] => 1; +} + +ref struct S1 : I1, I2 +{ +} + +ref struct S2 : I1, I2 +{ + public int this[int x] => 21; +} +"; + + var src2 = @" +class C +{ + static void Test1(I1 x) + { + _ = x[1]; + } + + static void Test1(I2 x) + { + _ = x[2]; + } + + static void Test2(T x) where T : I1, allows ref struct + { + _ = x[3]; + } + + static void Test3(T x) where T : I2, allows ref struct + { + _ = x[4]; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.NetCoreApp); + + comp1.VerifyDiagnostics( + // (12,17): error CS9245: 'I1.this[int].get' cannot implement interface member 'I1.this[int].get' for ref struct 'S1'. + // ref struct S1 : I1, I2 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].get", "I1.this[int].get", "S1").WithLocation(12, 17) + ); + + comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + // Specification suggests to report a warning for access to virtual (non-abstract) members. + // There is an open design question - https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#warn-on-dim-invocation + comp2.VerifyDiagnostics( + // (21,13): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // _ = x[4]; + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x[4]").WithLocation(21, 13) + ); + } + + [Fact] + public void ImplementAnInterface_10_DefaultImplementation() + { + var src1 = @" +public interface I1 +{ + virtual int this[int x] {set{}} +} + +public interface I2 +{ + sealed int this[long x] {set{}} +} + +ref struct S1 : I1, I2 +{ +} + +ref struct S2 : I1, I2 +{ + public int this[int x] {set{}} +} +"; + + var src2 = @" +class C +{ + static void Test1(I1 x) + { + x[1] = 1; + } + + static void Test1(I2 x) + { + x[2] = 2; + } + + static void Test2(T x) where T : I1, allows ref struct + { + x[3] = 3; + } + + static void Test3(T x) where T : I2, allows ref struct + { + x[4] = 4; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.NetCoreApp); + + comp1.VerifyDiagnostics( + // (12,17): error CS9245: 'I1.this[int].set' cannot implement interface member 'I1.this[int].set' for ref struct 'S1'. + // ref struct S1 : I1, I2 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].set", "I1.this[int].set", "S1").WithLocation(12, 17) + ); + + comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + // Specification suggests to report a warning for access to virtual (non-abstract) members. + // There is an open design question - https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#warn-on-dim-invocation + comp2.VerifyDiagnostics( + // (21,9): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // x[4] = 4; + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x[4]").WithLocation(21, 9) + ); + } + + [Fact] + public void ImplementAnInterface_11_DefaultImplementation() + { + var src1 = @" +public interface I1 +{ + virtual event System.Action E1 {add{} remove{}} + static virtual event System.Action E2 {add{} remove{}} + sealed event System.Action E3 {add{} remove{}} +} + +ref struct S1 : I1 +{ +} + +ref struct S2 : I1 +{ +#pragma warning disable CS0067 // The event 'S2.E1' is never used + public event System.Action E1; +} +"; + + var src2 = @" +class C +{ + static void Test1(I1 x) + { + x.E1 += null; + x.E3 += null; + x.E1 -= null; + x.E3 -= null; + } + + static void Test2(T x) where T : I1, allows ref struct + { + x.E1 += null; + T.E2 += null; +#line 100 + x.E3 += null; + x.E1 -= null; + T.E2 -= null; +#line 200 + x.E3 -= null; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: TargetFramework.NetCoreApp); + + comp1.VerifyDiagnostics( + // (9,17): error CS9245: 'I1.E1.add' cannot implement interface member 'I1.E1.add' for ref struct 'S1'. + // ref struct S1 : I1 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E1.add", "I1.E1.add", "S1").WithLocation(9, 17), + // (9,17): error CS9245: 'I1.E1.remove' cannot implement interface member 'I1.E1.remove' for ref struct 'S1'. + // ref struct S1 : I1 + Diagnostic(ErrorCode.ERR_RefStructDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E1.remove", "I1.E1.remove", "S1").WithLocation(9, 17) + ); + + comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + // Specification suggests to report a warning for access to virtual (non-abstract) members. + // There is an open design question - https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#warn-on-dim-invocation + comp2.VerifyDiagnostics( + // (100,9): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // x.E3 += null; + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x.E3 += null").WithLocation(100, 9), + // (200,9): error CS9246: A non-virtual instance interface member cannot be accessed on a type parameter that allows ref struct. + // x.E3 -= null; + Diagnostic(ErrorCode.ERR_BadNonVirtualInterfaceMemberAccessOnAllowsRefLike, "x.E3 -= null").WithLocation(200, 9) + ); + } + + [Fact] + public void ImplementAnInterface_12_Variance_ErrorScenarios() + { + var src = @" +interface I +{ + void M(T t); +} +interface IOut +{ + T MOut(); +} +ref struct S : I, IOut +{ + public void M(object o) { } + public object MOut() => null; +} +class Program +{ + static void Main() + { + Test1(new S()); + Test2(new S()); + } + static void Test1(T x) where T : I, allows ref struct + { + } + static void Test2(T x) where T : IOut, allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (19,9): error CS0315: The type 'S' cannot be used as type parameter 'T' in the generic type or method 'Program.Test1(T)'. There is no boxing conversion from 'S' to 'I'. + // Test1(new S()); + Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedValType, "Test1").WithArguments("Program.Test1(T)", "I", "T", "S").WithLocation(19, 9), + // (20,9): error CS0315: The type 'S' cannot be used as type parameter 'T' in the generic type or method 'Program.Test2(T)'. There is no boxing conversion from 'S' to 'IOut'. + // Test2(new S()); + Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedValType, "Test2").WithArguments("Program.Test2(T)", "IOut", "T", "S").WithLocation(20, 9) + ); + } + + [Fact] + public void Using_01() + { + var src = @" +ref struct S2 : System.IDisposable +{ + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + using (new S2()) + { + System.Console.Write(123); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 26 (0x1a) + .maxstack 1 + .locals init (S2 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ""S2"" + .try + { + IL_0008: ldc.i4.s 123 + IL_000a: call ""void System.Console.Write(int)"" + IL_000f: leave.s IL_0019 + } + finally + { + IL_0011: ldloca.s V_0 + IL_0013: call ""void S2.Dispose()"" + IL_0018: endfinally + } + IL_0019: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S2()') + Value: + IObjectCreationOperation (Constructor: S2..ctor()) (OperationKind.ObjectCreation, Type: S2) (Syntax: 'new S2()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IInvocationOperation ( void S2.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S2()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S2()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + } + + [Fact] + public void Using_02() + { + var src = @" +ref struct S2 : System.IDisposable +{ + void System.IDisposable.Dispose() + { + System.Console.Write('D'); + } +} + +struct S3 : System.IDisposable +{ + void System.IDisposable.Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test1(); + Test2(); + } + + static void Test1() + { + using (new S2()) + { + System.Console.Write(123); + } + } + + static void Test2() + { + using (new S3()) + { + System.Console.Write(456); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D456D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test1", +@" +{ + // Code size 32 (0x20) + .maxstack 1 + .locals init (S2 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ""S2"" + .try + { + IL_0008: ldc.i4.s 123 + IL_000a: call ""void System.Console.Write(int)"" + IL_000f: leave.s IL_001f + } + finally + { + IL_0011: ldloca.s V_0 + IL_0013: constrained. ""S2"" + IL_0019: callvirt ""void System.IDisposable.Dispose()"" + IL_001e: endfinally + } + IL_001f: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test1").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S2()') + Value: + IObjectCreationOperation (Constructor: S2..ctor()) (OperationKind.ObjectCreation, Type: S2) (Syntax: 'new S2()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S2()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S2()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + } + + [Fact] + public void Using_03() + { + var src = @" +ref struct S2 : System.IDisposable +{ + void System.IDisposable.Dispose() => throw null; + + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + using (var x = new S2()) + { + System.Console.Write(123); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 26 (0x1a) + .maxstack 1 + .locals init (S2 V_0) //x + IL_0000: ldloca.s V_0 + IL_0002: initobj ""S2"" + .try + { + IL_0008: ldc.i4.s 123 + IL_000a: call ""void System.Console.Write(int)"" + IL_000f: leave.s IL_0019 + } + finally + { + IL_0011: ldloca.s V_0 + IL_0013: call ""void S2.Dispose()"" + IL_0018: endfinally + } + IL_0019: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + Locals: [S2 x] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: S2, IsImplicit) (Syntax: 'x = new S2()') + Left: + ILocalReferenceOperation: x (IsDeclaration: True) (OperationKind.LocalReference, Type: S2, IsImplicit) (Syntax: 'x = new S2()') + Right: + IObjectCreationOperation (Constructor: S2..ctor()) (OperationKind.ObjectCreation, Type: S2) (Syntax: 'new S2()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IInvocationOperation ( void S2.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'x = new S2()') + Instance Receiver: + ILocalReferenceOperation: x (OperationKind.LocalReference, Type: S2, IsImplicit) (Syntax: 'x = new S2()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + } + + [Fact] + public void Using_04() + { + var src = @" +ref struct S2 : System.IDisposable +{ + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S2()); + } + + static void Test(T t) where T : System.IDisposable, allows ref struct + { + using (t) + { + System.Console.Write(123); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + // The code boxes type parameter that allows ref struct, however 'box' followed by 'brfalse' is + // documented as a valid sequence at https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md#special-il-sequences + // + // IL_000b: ldloc.0 + // IL_000c: box ""T"" + // IL_0011: brfalse.s IL_0020 + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 34 (0x22) + .maxstack 1 + .locals init (T V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + .try + { + IL_0002: ldc.i4.s 123 + IL_0004: call ""void System.Console.Write(int)"" + IL_0009: leave.s IL_0021 + } + finally + { + IL_000b: ldloc.0 + IL_000c: box ""T"" + IL_0011: brfalse.s IL_0020 + IL_0013: ldloca.s V_0 + IL_0015: constrained. ""T"" + IL_001b: callvirt ""void System.IDisposable.Dispose()"" + IL_0020: endfinally + } + IL_0021: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B6] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B5] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 't') + Next (Regular) Block[B4] + Block[B4] - Block + Predecessors: [B3] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B3] [B4] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B6] - Exit + Predecessors: [B2] + Statements (0) +"""); + } + + [Fact] + public void Using_05() + { + var src = @" +ref struct S2 : System.IDisposable +{ + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S2()); + } + + static void Test(T t) where T : struct, System.IDisposable, allows ref struct + { + using (t) + { + System.Console.Write(123); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 26 (0x1a) + .maxstack 1 + .locals init (T V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + .try + { + IL_0002: ldc.i4.s 123 + IL_0004: call ""void System.Console.Write(int)"" + IL_0009: leave.s IL_0019 + } + finally + { + IL_000b: ldloca.s V_0 + IL_000d: constrained. ""T"" + IL_0013: callvirt ""void System.IDisposable.Dispose()"" + IL_0018: endfinally + } + IL_0019: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 't') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73559")] + public void Using_06() + { + var src = @" +interface IMyDisposable +{ + void Dispose(); +} + +ref struct S2 : IMyDisposable +{ + public void Dispose() + { + } +} + +class C +{ + static void Main() + { + Test(new S2(), null); + } + + static void Test(T t, IMyDisposable s) where T : IMyDisposable, allows ref struct + { + using (t) + { + } + + using (s) + { + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + // https://github.com/dotnet/roslyn/issues/73559: Should we adjust wording for the error? Ref struct implement interfaces, but not convertible to them. + comp.VerifyDiagnostics( + // (23,16): error CS1674: 'T': type used in a using statement must be implicitly convertible to 'System.IDisposable'. + // using (t) + Diagnostic(ErrorCode.ERR_NoConvToIDisp, "t").WithArguments("T").WithLocation(23, 16), + // (27,16): error CS1674: 'IMyDisposable': type used in a using statement must be implicitly convertible to 'System.IDisposable'. + // using (s) + Diagnostic(ErrorCode.ERR_NoConvToIDisp, "s").WithArguments("IMyDisposable").WithLocation(27, 16) + ); + } + + [Fact] + public void Using_LanguageVersion_01() + { + var src1 = @" +public ref struct S2 : System.IDisposable +{ + public void Dispose() + { + } +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + using (new S2()) + { + } + + using (var s = new S2()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void Using_LanguageVersion_02() + { + var src1 = @" +public ref struct S2 : System.IDisposable +{ + void System.IDisposable.Dispose() + { + } +} + +public struct S3 : System.IDisposable +{ + void System.IDisposable.Dispose() + { + } +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + using (new S2()) + { + } + + using (var s = new S2()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,16): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // using (new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S2()").WithArguments("ref struct interfaces").WithLocation(6, 16), + // (10,16): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // using (var s = new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var s = new S2()").WithArguments("ref struct interfaces").WithLocation(10, 16) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (2,24): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S2 : System.IDisposable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.IDisposable").WithArguments("ref struct interfaces").WithLocation(2, 24) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var src3 = @" +class C +{ + static void Main() + { + using (new S3()) + { + } + + using (var s = new S3()) + { + } + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void Using_LanguageVersion_04() + { + var src = @" +class C +{ + static void Test(T t) where T : System.IDisposable, allows ref struct + { + using (t) + { + } + + using (var s = t) + { + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (4,67): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static void Test(T t) where T : System.IDisposable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(4, 67) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerableT_01() + { + var src = @" +using System.Collections.Generic; + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); +} + +class C +{ + static void Main() + { + foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 49 (0x31) + .maxstack 2 + .locals init (System.Collections.Generic.IEnumerator V_0, + S V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S"" + IL_0009: call ""System.Collections.Generic.IEnumerator S.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001c + IL_0011: ldloc.0 + IL_0012: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_0017: call ""void System.Console.Write(int)"" + IL_001c: ldloc.0 + IL_001d: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0022: brtrue.s IL_0011 + IL_0024: leave.s IL_0030 + } + finally + { + IL_0026: ldloc.0 + IL_0027: brfalse.s IL_002f + IL_0029: ldloc.0 + IL_002a: callvirt ""void System.IDisposable.Dispose()"" + IL_002f: endfinally + } + IL_0030: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation ( System.Collections.Generic.IEnumerator S.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator S.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator S.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void Foreach_IEnumerableT_02() + { + var src = @" +using System.Collections.Generic; + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } + + IEnumerator IEnumerable.GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); +} + +class C +{ + static void Main() + { + foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 49 (0x31) + .maxstack 2 + .locals init (System.Collections.Generic.IEnumerator V_0, + S V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S"" + IL_0009: call ""System.Collections.Generic.IEnumerator S.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001c + IL_0011: ldloc.0 + IL_0012: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_0017: call ""void System.Console.Write(int)"" + IL_001c: ldloc.0 + IL_001d: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0022: brtrue.s IL_0011 + IL_0024: leave.s IL_0030 + } + finally + { + IL_0026: ldloc.0 + IL_0027: brfalse.s IL_002f + IL_0029: ldloc.0 + IL_002a: callvirt ""void System.IDisposable.Dispose()"" + IL_002f: endfinally + } + IL_0030: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation ( System.Collections.Generic.IEnumerator S.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator S.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator S.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void Foreach_IEnumerableT_03() + { + var src = @" +using System.Collections.Generic; + +ref struct S : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => Get123(); +} + +struct S2 : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() + { + return Get456(); + } + + static IEnumerator Get456() + { + yield return 456; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => Get456(); +} + +class C +{ + static void Main() + { + Test1(); + Test2(); + } + + static void Test1() + { + foreach (var i in new S()) + { + System.Console.Write(i); + } + } + + static void Test2() + { + foreach (var i in new S2()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123456" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test1", +@" +{ + // Code size 55 (0x37) + .maxstack 2 + .locals init (System.Collections.Generic.IEnumerator V_0, + S V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S"" + IL_0009: constrained. ""S"" + IL_000f: callvirt ""System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()"" + IL_0014: stloc.0 + .try + { + IL_0015: br.s IL_0022 + IL_0017: ldloc.0 + IL_0018: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(int)"" + IL_0022: ldloc.0 + IL_0023: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0028: brtrue.s IL_0017 + IL_002a: leave.s IL_0036 + } + finally + { + IL_002c: ldloc.0 + IL_002d: brfalse.s IL_0035 + IL_002f: ldloc.0 + IL_0030: callvirt ""void System.IDisposable.Dispose()"" + IL_0035: endfinally + } + IL_0036: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test1").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation (virtual System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal("new S()", foreachSyntax.Expression.ToString()); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerableT_04(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IEnumerable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 48 (0x30) + .maxstack 1 + .locals init (System.Collections.Generic.IEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_001b + IL_0010: ldloc.0 + IL_0011: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_0016: call ""void System.Console.Write(int)"" + IL_001b: ldloc.0 + IL_001c: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0021: brtrue.s IL_0010 + IL_0023: leave.s IL_002f + } + finally + { + IL_0025: ldloc.0 + IL_0026: brfalse.s IL_002e + IL_0028: ldloc.0 + IL_0029: callvirt ""void System.IDisposable.Dispose()"" + IL_002e: endfinally + } + IL_002f: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerableT_05(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; + +interface IMyEnumerable +{ + IEnumerator GetEnumerator(); +} + +ref struct S : IMyEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IMyEnumerable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 48 (0x30) + .maxstack 1 + .locals init (System.Collections.Generic.IEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""System.Collections.Generic.IEnumerator IMyEnumerable.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_001b + IL_0010: ldloc.0 + IL_0011: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_0016: call ""void System.Console.Write(int)"" + IL_001b: ldloc.0 + IL_001c: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0021: brtrue.s IL_0010 + IL_0023: leave.s IL_002f + } + finally + { + IL_0025: ldloc.0 + IL_0026: brfalse.s IL_002e + IL_0028: ldloc.0 + IL_0029: callvirt ""void System.IDisposable.Dispose()"" + IL_002e: endfinally + } + IL_002f: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual System.Collections.Generic.IEnumerator IMyEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator IMyEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator IMyEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerableT_06(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; + +interface IMyEnumerable1 +{ + IEnumerator GetEnumerator(); +} + + +interface IMyEnumerable2 +{ + IEnumerator GetEnumerator(); +} + +ref struct S : IMyEnumerable1, IMyEnumerable2 +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IMyEnumerable1, IMyEnumerable2, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (37,27): warning CS0278: 'T' does not implement the 'collection' pattern. 'IMyEnumerable1.GetEnumerator()' is ambiguous with 'IMyEnumerable2.GetEnumerator()'. + // foreach (var i in t) + Diagnostic(ErrorCode.WRN_PatternIsAmbiguous, "t").WithArguments("T", "collection", "IMyEnumerable1.GetEnumerator()", "IMyEnumerable2.GetEnumerator()").WithLocation(37, 27), + // (37,27): error CS1579: foreach statement cannot operate on variables of type 'T' because 'T' does not contain a public instance or extension definition for 'GetEnumerator' + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_ForEachMissingMember, "t").WithArguments("T", "GetEnumerator").WithLocation(37, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.GetEnumeratorMethod); + Assert.Null(info.ElementType); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerableT_07(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; + +interface IMyEnumerable1 +{ + IEnumerator GetEnumerator(); +} + +interface IMyEnumerable2 +{ + IEnumerator GetEnumerator(); +} + +ref struct S : IMyEnumerable1, IMyEnumerable2, IEnumerable +{ + IEnumerator IMyEnumerable1.GetEnumerator() => throw null; + IEnumerator IMyEnumerable2.GetEnumerator() => throw null; + + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IMyEnumerable1, IMyEnumerable2, IEnumerable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics( + // (41,27): warning CS0278: 'T' does not implement the 'collection' pattern. 'IMyEnumerable1.GetEnumerator()' is ambiguous with 'IMyEnumerable2.GetEnumerator()'. + // foreach (var i in t) + Diagnostic(ErrorCode.WRN_PatternIsAmbiguous, "t").WithArguments("T", "collection", "IMyEnumerable1.GetEnumerator()", "IMyEnumerable2.GetEnumerator()").WithLocation(41, 27) + ); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 48 (0x30) + .maxstack 1 + .locals init (System.Collections.Generic.IEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_001b + IL_0010: ldloc.0 + IL_0011: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_0016: call ""void System.Console.Write(int)"" + IL_001b: ldloc.0 + IL_001c: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0021: brtrue.s IL_0010 + IL_0023: leave.s IL_002f + } + finally + { + IL_0025: ldloc.0 + IL_0026: brfalse.s IL_002e + IL_0028: ldloc.0 + IL_0029: callvirt ""void System.IDisposable.Dispose()"" + IL_002e: endfinally + } + IL_002f: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void Foreach_IEnumerableT_LanguageVersion_01() + { + var src1 = @" +using System.Collections.Generic; + +public ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + foreach (var i in new S()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerableT_LanguageVersion_03() + { + var src1 = @" +using System.Collections.Generic; + +public ref struct S : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; +} + +public struct S2 : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + foreach (var i in new S()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + + // Even though semantic analysis didn't produce any errors in C# 12 compiler, an attempt to emit was failing with + // "Unable to determine specific cause of the failure" error. + comp2.VerifyEmitDiagnostics( + // (6,27): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (var i in new S()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S()").WithArguments("ref struct interfaces").WithLocation(6, 27) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (4,23): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S : IEnumerable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "IEnumerable").WithArguments("ref struct interfaces").WithLocation(4, 23) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var src3 = @" +class C +{ + static void Main() + { + foreach (var i in new S2()) + { + } + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerableT_LanguageVersion_04() + { + var src = @" +using System.Collections.Generic; + +class C +{ + static void Test(T t) where T : IEnumerable, allows ref struct + { + foreach (var i in t) + { + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (6,65): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static void Test(T t) where T : IEnumerable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(6, 65) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerableT_LanguageVersion_05() + { + var src1 = @" +using System.Collections.Generic; + +public interface IMyEnumerable +{ + IEnumerator GetEnumerator(); +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Test(T t) where T : IMyEnumerable, allows ref struct + { + foreach (var i in t) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (4,67): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static void Test(T t) where T : IMyEnumerable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(4, 67) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_01(bool s1IsRefStruct) + { + var src = @" +using System.Collections.Generic; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 49 (0x31) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""int S2.Current.get"" + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: leave.s IL_0030 + } + finally + { + IL_0028: ldloca.s V_0 + IL_002a: call ""void S2.Dispose()"" + IL_002f: endfinally + } + IL_0030: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 S2.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation ( void S2.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void S2.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("void S2.Dispose()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_02(bool s1IsRefStruct) + { + var src = @" +using System.Collections.Generic; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } + + int IEnumerator.Current => throw null; + bool System.Collections.IEnumerator.MoveNext() => throw null; + + void System.IDisposable.Dispose() => throw null; +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 49 (0x31) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""int S2.Current.get"" + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: leave.s IL_0030 + } + finally + { + IL_0028: ldloca.s V_0 + IL_002a: call ""void S2.Dispose()"" + IL_002f: endfinally + } + IL_0030: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 S2.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation ( void S2.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void S2.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("void S2.Dispose()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_03(bool s1IsRefStruct, bool currentIsPublic, bool moveNextIsPublic, bool disposeIsPublic) + { + if (currentIsPublic && moveNextIsPublic) + { + return; + } + + var src = @" +using System.Collections.Generic; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + + " + (currentIsPublic ? "public int " : "int IEnumerator.") + @"Current => 123; + + object System.Collections.IEnumerator.Current => 123; + + " + (moveNextIsPublic ? "public bool " : "bool System.Collections.IEnumerator.") + @"MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + " + (disposeIsPublic ? "public void " : "void System.IDisposable.") + @"Dispose() + { + System.Console.Write('D'); + } + + public void Reset() { } +} + +class C +{ + static void Main() + { +#line 100 + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + if (!currentIsPublic) + { + comp.VerifyDiagnostics( + // (100,27): error CS0117: 'S2' does not contain a definition for 'Current' + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_NoSuchMember, "new S1()").WithArguments("S2", "Current").WithLocation(100, 27), + // (100,27): error CS0202: foreach requires that the return type 'S2' of 'S1.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "new S1()").WithArguments("S2", "S1.GetEnumerator()").WithLocation(100, 27) + ); + } + else + { + Assert.False(moveNextIsPublic); + + comp.VerifyDiagnostics( + // (100,27): error CS0117: 'S2' does not contain a definition for 'MoveNext' + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_NoSuchMember, "new S1()").WithArguments("S2", "MoveNext").WithLocation(100, 27), + // (100,27): error CS0202: foreach requires that the return type 'S2' of 'S1.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "new S1()").WithArguments("S2", "S1.GetEnumerator()").WithLocation(100, 27) + ); + } + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] +Block[B1] - Block + Predecessors: [B0] + Statements (1) + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(1): + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1, IsInvalid) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] +Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B4] + IInvalidOperation (OperationKind.Invalid, Type: System.Boolean, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(1): + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(0) + Next (Regular) Block[B3] + Entering: {R1} +.locals {R1} +{ + Locals: [var i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: var, IsImplicit) (Syntax: 'var') + Right: + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(1): + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(0) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvalidOperation (OperationKind.Invalid, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Children(2): + IOperation: (OperationKind.None, Type: System.Console) (Syntax: 'System.Console') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: var) (Syntax: 'i') + Next (Regular) Block[B2] + Leaving: {R1} +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.ElementType); + Assert.Null(info.MoveNextMethod); + Assert.Null(info.CurrentProperty); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_04(bool s1IsRefStruct, bool addExplicitImplementationOfCurrentAndMoveNext) + { + var src = @" +using System.Collections.Generic; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } +" + +(addExplicitImplementationOfCurrentAndMoveNext ? +@" + int IEnumerator.Current => throw null; + bool System.Collections.IEnumerator.MoveNext() => throw null; +" +: +"") + +@" + void System.IDisposable.Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 55 (0x37) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""int S2.Current.get"" + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: leave.s IL_0036 + } + finally + { + IL_0028: ldloca.s V_0 + IL_002a: constrained. ""S2"" + IL_0030: callvirt ""void System.IDisposable.Dispose()"" + IL_0035: endfinally + } + IL_0036: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 S2.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_05(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +using System.Collections.Generic; + +interface IGetEnumerator where TEnumerator : IEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : IEnumerator, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 74 (0x4a) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(int)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0049 + } + finally + { + IL_0033: ldloc.0 + IL_0034: box ""TEnumerator"" + IL_0039: brfalse.s IL_0048 + IL_003b: ldloca.s V_0 + IL_003d: constrained. ""TEnumerator"" + IL_0043: callvirt ""void System.IDisposable.Dispose()"" + IL_0048: endfinally + } + IL_0049: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual TEnumerator IGetEnumerator.GetEnumerator()) (OperationKind.Invocation, Type: TEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: TEnumerable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: TEnumerable) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 System.Collections.Generic.IEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 System.Collections.Generic.IEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_06(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +using System.Collections.Generic; + +interface IGetEnumerator where TEnumerator : IEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : struct, IEnumerator, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 66 (0x42) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""int System.Collections.Generic.IEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(int)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0041 + } + finally + { + IL_0033: ldloca.s V_0 + IL_0035: constrained. ""TEnumerator"" + IL_003b: callvirt ""void System.IDisposable.Dispose()"" + IL_0040: endfinally + } + IL_0041: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual TEnumerator IGetEnumerator.GetEnumerator()) (OperationKind.Invocation, Type: TEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: TEnumerable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: TEnumerable) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 System.Collections.Generic.IEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 System.Collections.Generic.IEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_07(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +interface IMyEnumerator : System.IDisposable +{ + T Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : IMyEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IMyEnumerator +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : IMyEnumerator, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 74 (0x4a) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""int IMyEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(int)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool IMyEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0049 + } + finally + { + IL_0033: ldloc.0 + IL_0034: box ""TEnumerator"" + IL_0039: brfalse.s IL_0048 + IL_003b: ldloca.s V_0 + IL_003d: constrained. ""TEnumerator"" + IL_0043: callvirt ""void System.IDisposable.Dispose()"" + IL_0048: endfinally + } + IL_0049: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual TEnumerator IGetEnumerator.GetEnumerator()) (OperationKind.Invocation, Type: TEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: TEnumerable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: TEnumerable) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean IMyEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 IMyEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean IMyEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 IMyEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean IMyEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 IMyEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_08(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +interface IMyEnumerator1 +{ + T Current {get;} + bool MoveNext(); +} + +interface IMyEnumerator2 +{ + T Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : IMyEnumerator1, IMyEnumerator2, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IMyEnumerator1, IMyEnumerator2 +{ + bool stop; + public int Current => 123; + + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : IMyEnumerator1, IMyEnumerator2, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (60,27): error CS0202: foreach requires that the return type 'TEnumerator' of 'IGetEnumerator.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "t").WithArguments("TEnumerator", "IGetEnumerator.GetEnumerator()").WithLocation(60, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.ElementType); + Assert.Null(info.MoveNextMethod); + Assert.Null(info.CurrentProperty); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumeratorT_09(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +using System.Collections.Generic; + +interface IMyEnumerator1 +{ + T Current {get;} + bool MoveNext(); +} + +interface IMyEnumerator2 +{ + T Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : IMyEnumerator1, IMyEnumerator2, IEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IMyEnumerator1, IMyEnumerator2, IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : IMyEnumerator1, IMyEnumerator2, IEnumerator, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (62,27): error CS0202: foreach requires that the return type 'TEnumerator' of 'IGetEnumerator.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "t").WithArguments("TEnumerator", "IGetEnumerator.GetEnumerator()").WithLocation(62, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.ElementType); + Assert.Null(info.MoveNextMethod); + Assert.Null(info.CurrentProperty); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_01(bool s1IsRefStruct) + { + var src = @" +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : System.IDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 49 (0x31) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""int S2.Current.get"" + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: leave.s IL_0030 + } + finally + { + IL_0028: ldloca.s V_0 + IL_002a: call ""void S2.Dispose()"" + IL_002f: endfinally + } + IL_0030: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 S2.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation ( void S2.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void S2.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("void S2.Dispose()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_02(bool s1IsRefStruct) + { + var src = @" +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : System.IDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Dispose() + { + System.Console.Write('D'); + } + + void System.IDisposable.Dispose() => throw null; +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 49 (0x31) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""int S2.Current.get"" + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: leave.s IL_0030 + } + finally + { + IL_0028: ldloca.s V_0 + IL_002a: call ""void S2.Dispose()"" + IL_002f: endfinally + } + IL_0030: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 S2.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation ( void S2.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void S2.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("void S2.Dispose()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_03(bool s1IsRefStruct) + { + var src = @" +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : System.IDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + void System.IDisposable.Dispose() + { + System.Console.Write('D'); + } +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S3 +{ + public S4 GetEnumerator() + { + return new S4(); + } +} + +struct S4 : System.IDisposable +{ + bool stop; + public int Current => 456; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + void System.IDisposable.Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test1(); + Test2(); + } + + static void Test1() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } + + static void Test2() + { + foreach (var i in new S3()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D456D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test1", +@" +{ + // Code size 55 (0x37) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""int S2.Current.get"" + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: leave.s IL_0036 + } + finally + { + IL_0028: ldloca.s V_0 + IL_002a: constrained. ""S2"" + IL_0030: callvirt ""void System.IDisposable.Dispose()"" + IL_0035: endfinally + } + IL_0036: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test1").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 S2.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal("new S1()", foreachSyntax.Expression.ToString()); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_04(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +interface ICustomEnumerator +{ + int Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : ICustomEnumerator, System.IDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 74 (0x4a) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""int ICustomEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(int)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool ICustomEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0049 + } + finally + { + IL_0033: ldloc.0 + IL_0034: box ""TEnumerator"" + IL_0039: brfalse.s IL_0048 + IL_003b: ldloca.s V_0 + IL_003d: constrained. ""TEnumerator"" + IL_0043: callvirt ""void System.IDisposable.Dispose()"" + IL_0048: endfinally + } + IL_0049: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual TEnumerator IGetEnumerator.GetEnumerator()) (OperationKind.Invocation, Type: TEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: TEnumerable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: TEnumerable) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean ICustomEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 ICustomEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_05(bool s1IsRefStruct, bool addStructConstraintToTEnumerable) + { + var src = @" +interface ICustomEnumerator +{ + int Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : ICustomEnumerator, System.IDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : struct, ICustomEnumerator, System.IDisposable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 66 (0x42) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""int ICustomEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(int)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool ICustomEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0041 + } + finally + { + IL_0033: ldloca.s V_0 + IL_0035: constrained. ""TEnumerator"" + IL_003b: callvirt ""void System.IDisposable.Dispose()"" + IL_0040: endfinally + } + IL_0041: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual TEnumerator IGetEnumerator.GetEnumerator()) (OperationKind.Invocation, Type: TEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: TEnumerable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: TEnumerable) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B5] + IInvocationOperation (virtual System.Boolean ICustomEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 ICustomEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: TEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B5] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_06(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +interface ICustomEnumerator +{ + int Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +interface IMyDisposable +{ + void Dispose(); +} + +ref struct S2 : ICustomEnumerator, IMyDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, IMyDisposable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (58,27): error CS9247: foreach statement cannot operate on enumerators of type 'TEnumerator' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_BadAllowByRefLikeEnumerator, "t").WithArguments("TEnumerator").WithLocation(58, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IDisposable_07(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +interface ICustomEnumerator +{ + int Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : ICustomEnumerator, System.IDisposable +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (53,27): error CS9247: foreach statement cannot operate on enumerators of type 'TEnumerator' because it is a type parameter that allows ref struct and it is not known at compile time to implement IDisposable. + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_BadAllowByRefLikeEnumerator, "t").WithArguments("TEnumerator").WithLocation(53, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean ICustomEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Int32 ICustomEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Fact] + public void Foreach_IDisposable_LanguageVersion_01() + { + var src1 = @" +public struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +public ref struct S2 : System.IDisposable +{ + public int Current => throw null; + public bool MoveNext() => throw null; + public void Dispose() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IDisposable_LanguageVersion_03() + { + var src1 = @" +public struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +public ref struct S2 : System.IDisposable +{ + public int Current => throw null; + public bool MoveNext() => throw null; + void System.IDisposable.Dispose() => throw null; +} + +public struct S3 +{ + public S4 GetEnumerator() + { + return new S4(); + } +} + +public struct S4 : System.IDisposable +{ + public int Current => throw null; + public bool MoveNext() => throw null; + void System.IDisposable.Dispose() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + foreach (var i in new S1()) {} + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,9): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (var i in new S1()) {} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "foreach (var i in new S1()) {}").WithArguments("ref struct interfaces").WithLocation(6, 9) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (10,24): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S2 : System.IDisposable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.IDisposable").WithArguments("ref struct interfaces").WithLocation(10, 24) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var src3 = @" +class C +{ + static void Main() + { + foreach (var i in new S3()) {} + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IDisposable_LanguageVersion_04() + { + var src = @" +interface ICustomEnumerator +{ + int Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +class C +{ + static void Test(TEnumerable t) + where TEnumerable : IGetEnumerator, allows ref struct + where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct + { + foreach (var i in t) {} + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (8,105): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // interface IGetEnumerator where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(8, 105), + // (16,65): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where TEnumerable : IGetEnumerator, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(16, 65), + // (17,75): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where TEnumerator : ICustomEnumerator, System.IDisposable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(17, 75) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_Pattern_01() + { + var src = @" +ref struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void Foreach_Pattern_02() + { + var src = @" +struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 +{ + bool stop; + public int Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void AwaitUsing_01() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await using (new S2()) + { + System.Console.Write(123); + } + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", +@" +{ + // Code size 229 (0xe5) + .maxstack 3 + .locals init (int V_0, + S2 V_1, + object V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.
d__0.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_006d + IL_000a: ldloca.s V_1 + IL_000c: initobj ""S2"" + IL_0012: ldarg.0 + IL_0013: ldnull + IL_0014: stfld ""object C.
d__0.<>7__wrap1"" + IL_0019: ldarg.0 + IL_001a: ldc.i4.0 + IL_001b: stfld ""int C.
d__0.<>7__wrap2"" + .try + { + IL_0020: ldc.i4.s 123 + IL_0022: call ""void System.Console.Write(int)"" + IL_0027: leave.s IL_0033 + } + catch object + { + IL_0029: stloc.2 + IL_002a: ldarg.0 + IL_002b: ldloc.2 + IL_002c: stfld ""object C.
d__0.<>7__wrap1"" + IL_0031: leave.s IL_0033 + } + IL_0033: ldloca.s V_1 + IL_0035: call ""System.Threading.Tasks.ValueTask S2.DisposeAsync()"" + IL_003a: stloc.s V_4 + IL_003c: ldloca.s V_4 + IL_003e: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_0043: stloc.3 + IL_0044: ldloca.s V_3 + IL_0046: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_004b: brtrue.s IL_0089 + IL_004d: ldarg.0 + IL_004e: ldc.i4.0 + IL_004f: dup + IL_0050: stloc.0 + IL_0051: stfld ""int C.
d__0.<>1__state"" + IL_0056: ldarg.0 + IL_0057: ldloc.3 + IL_0058: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_005d: ldarg.0 + IL_005e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0063: ldloca.s V_3 + IL_0065: ldarg.0 + IL_0066: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" + IL_006b: leave.s IL_00e4 + IL_006d: ldarg.0 + IL_006e: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_0073: stloc.3 + IL_0074: ldarg.0 + IL_0075: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_007a: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_0080: ldarg.0 + IL_0081: ldc.i4.m1 + IL_0082: dup + IL_0083: stloc.0 + IL_0084: stfld ""int C.
d__0.<>1__state"" + IL_0089: ldloca.s V_3 + IL_008b: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_0090: ldarg.0 + IL_0091: ldfld ""object C.
d__0.<>7__wrap1"" + IL_0096: stloc.2 + IL_0097: ldloc.2 + IL_0098: brfalse.s IL_00af + IL_009a: ldloc.2 + IL_009b: isinst ""System.Exception"" + IL_00a0: dup + IL_00a1: brtrue.s IL_00a5 + IL_00a3: ldloc.2 + IL_00a4: throw + IL_00a5: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_00aa: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_00af: ldarg.0 + IL_00b0: ldnull + IL_00b1: stfld ""object C.
d__0.<>7__wrap1"" + IL_00b6: leave.s IL_00d1 + } + catch System.Exception + { + IL_00b8: stloc.s V_5 + IL_00ba: ldarg.0 + IL_00bb: ldc.i4.s -2 + IL_00bd: stfld ""int C.
d__0.<>1__state"" + IL_00c2: ldarg.0 + IL_00c3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_00c8: ldloc.s V_5 + IL_00ca: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00cf: leave.s IL_00e4 + } + IL_00d1: ldarg.0 + IL_00d2: ldc.i4.s -2 + IL_00d4: stfld ""int C.
d__0.<>1__state"" + IL_00d9: ldarg.0 + IL_00da: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_00df: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00e4: ret +} +"); + + var tree = comp1.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp1, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S2()') + Value: + IObjectCreationOperation (Constructor: S2..ctor()) (OperationKind.ObjectCreation, Type: S2) (Syntax: 'new S2()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new S2()') + Expression: + IInvocationOperation ( System.Threading.Tasks.ValueTask S2.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S2()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S2()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var src2 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + public ValueTask DisposeAsync() + { + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await using (new S2()) + { + await Task.Yield(); + } + } +} +"; + + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp2.VerifyEmitDiagnostics( + // (17,22): error CS4007: Instance of type 'S2' cannot be preserved across 'await' or 'yield' boundary. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new S2()").WithArguments("S2").WithLocation(17, 22) + ); + } + + [Fact] + public void AwaitUsing_02() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +struct S3 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await Test1(); + await Test2(); + } + + static async Task Test1() + { + await using (new S2()) + { + System.Console.Write(123); + } + } + + static async Task Test2() + { + await using (new S3()) + { + System.Console.Write(456); + } + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D456D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", +@" +{ + // Code size 235 (0xeb) + .maxstack 3 + .locals init (int V_0, + S2 V_1, + object V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0073 + IL_000a: ldloca.s V_1 + IL_000c: initobj ""S2"" + IL_0012: ldarg.0 + IL_0013: ldnull + IL_0014: stfld ""object C.d__1.<>7__wrap1"" + IL_0019: ldarg.0 + IL_001a: ldc.i4.0 + IL_001b: stfld ""int C.d__1.<>7__wrap2"" + .try + { + IL_0020: ldc.i4.s 123 + IL_0022: call ""void System.Console.Write(int)"" + IL_0027: leave.s IL_0033 + } + catch object + { + IL_0029: stloc.2 + IL_002a: ldarg.0 + IL_002b: ldloc.2 + IL_002c: stfld ""object C.d__1.<>7__wrap1"" + IL_0031: leave.s IL_0033 + } + IL_0033: ldloca.s V_1 + IL_0035: constrained. ""S2"" + IL_003b: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_0040: stloc.s V_4 + IL_0042: ldloca.s V_4 + IL_0044: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_0049: stloc.3 + IL_004a: ldloca.s V_3 + IL_004c: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0051: brtrue.s IL_008f + IL_0053: ldarg.0 + IL_0054: ldc.i4.0 + IL_0055: dup + IL_0056: stloc.0 + IL_0057: stfld ""int C.d__1.<>1__state"" + IL_005c: ldarg.0 + IL_005d: ldloc.3 + IL_005e: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0063: ldarg.0 + IL_0064: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0069: ldloca.s V_3 + IL_006b: ldarg.0 + IL_006c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0071: leave.s IL_00ea + IL_0073: ldarg.0 + IL_0074: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0079: stloc.3 + IL_007a: ldarg.0 + IL_007b: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0080: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_0086: ldarg.0 + IL_0087: ldc.i4.m1 + IL_0088: dup + IL_0089: stloc.0 + IL_008a: stfld ""int C.d__1.<>1__state"" + IL_008f: ldloca.s V_3 + IL_0091: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_0096: ldarg.0 + IL_0097: ldfld ""object C.d__1.<>7__wrap1"" + IL_009c: stloc.2 + IL_009d: ldloc.2 + IL_009e: brfalse.s IL_00b5 + IL_00a0: ldloc.2 + IL_00a1: isinst ""System.Exception"" + IL_00a6: dup + IL_00a7: brtrue.s IL_00ab + IL_00a9: ldloc.2 + IL_00aa: throw + IL_00ab: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_00b0: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_00b5: ldarg.0 + IL_00b6: ldnull + IL_00b7: stfld ""object C.d__1.<>7__wrap1"" + IL_00bc: leave.s IL_00d7 + } + catch System.Exception + { + IL_00be: stloc.s V_5 + IL_00c0: ldarg.0 + IL_00c1: ldc.i4.s -2 + IL_00c3: stfld ""int C.d__1.<>1__state"" + IL_00c8: ldarg.0 + IL_00c9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00ce: ldloc.s V_5 + IL_00d0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00d5: leave.s IL_00ea + } + IL_00d7: ldarg.0 + IL_00d8: ldc.i4.s -2 + IL_00da: stfld ""int C.d__1.<>1__state"" + IL_00df: ldarg.0 + IL_00e0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00e5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00ea: ret +} +"); + + var tree = comp1.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test1").Single(); + + VerifyFlowGraph(comp1, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S2()') + Value: + IObjectCreationOperation (Constructor: S2..ctor()) (OperationKind.ObjectCreation, Type: S2) (Syntax: 'new S2()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new S2()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S2()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S2()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var src2 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() + { + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await using (new S2()) + { + await Task.Yield(); + } + } +} +"; + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp2.VerifyEmitDiagnostics( + // (17,22): error CS4007: Instance of type 'S2' cannot be preserved across 'await' or 'yield' boundary. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new S2()").WithArguments("S2").WithLocation(17, 22) + ); + } + + [Fact] + public void AwaitUsing_03() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() => throw null; + + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await using (new S2()) + { + System.Console.Write(123); + } + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", +@" +{ + // Code size 229 (0xe5) + .maxstack 3 + .locals init (int V_0, + S2 V_1, + object V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.
d__0.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_006d + IL_000a: ldloca.s V_1 + IL_000c: initobj ""S2"" + IL_0012: ldarg.0 + IL_0013: ldnull + IL_0014: stfld ""object C.
d__0.<>7__wrap1"" + IL_0019: ldarg.0 + IL_001a: ldc.i4.0 + IL_001b: stfld ""int C.
d__0.<>7__wrap2"" + .try + { + IL_0020: ldc.i4.s 123 + IL_0022: call ""void System.Console.Write(int)"" + IL_0027: leave.s IL_0033 + } + catch object + { + IL_0029: stloc.2 + IL_002a: ldarg.0 + IL_002b: ldloc.2 + IL_002c: stfld ""object C.
d__0.<>7__wrap1"" + IL_0031: leave.s IL_0033 + } + IL_0033: ldloca.s V_1 + IL_0035: call ""System.Threading.Tasks.ValueTask S2.DisposeAsync()"" + IL_003a: stloc.s V_4 + IL_003c: ldloca.s V_4 + IL_003e: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_0043: stloc.3 + IL_0044: ldloca.s V_3 + IL_0046: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_004b: brtrue.s IL_0089 + IL_004d: ldarg.0 + IL_004e: ldc.i4.0 + IL_004f: dup + IL_0050: stloc.0 + IL_0051: stfld ""int C.
d__0.<>1__state"" + IL_0056: ldarg.0 + IL_0057: ldloc.3 + IL_0058: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_005d: ldarg.0 + IL_005e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0063: ldloca.s V_3 + IL_0065: ldarg.0 + IL_0066: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" + IL_006b: leave.s IL_00e4 + IL_006d: ldarg.0 + IL_006e: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_0073: stloc.3 + IL_0074: ldarg.0 + IL_0075: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_007a: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_0080: ldarg.0 + IL_0081: ldc.i4.m1 + IL_0082: dup + IL_0083: stloc.0 + IL_0084: stfld ""int C.
d__0.<>1__state"" + IL_0089: ldloca.s V_3 + IL_008b: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_0090: ldarg.0 + IL_0091: ldfld ""object C.
d__0.<>7__wrap1"" + IL_0096: stloc.2 + IL_0097: ldloc.2 + IL_0098: brfalse.s IL_00af + IL_009a: ldloc.2 + IL_009b: isinst ""System.Exception"" + IL_00a0: dup + IL_00a1: brtrue.s IL_00a5 + IL_00a3: ldloc.2 + IL_00a4: throw + IL_00a5: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_00aa: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_00af: ldarg.0 + IL_00b0: ldnull + IL_00b1: stfld ""object C.
d__0.<>7__wrap1"" + IL_00b6: leave.s IL_00d1 + } + catch System.Exception + { + IL_00b8: stloc.s V_5 + IL_00ba: ldarg.0 + IL_00bb: ldc.i4.s -2 + IL_00bd: stfld ""int C.
d__0.<>1__state"" + IL_00c2: ldarg.0 + IL_00c3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_00c8: ldloc.s V_5 + IL_00ca: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00cf: leave.s IL_00e4 + } + IL_00d1: ldarg.0 + IL_00d2: ldc.i4.s -2 + IL_00d4: stfld ""int C.
d__0.<>1__state"" + IL_00d9: ldarg.0 + IL_00da: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_00df: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00e4: ret +} +"); + + var tree = comp1.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp1, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S2()') + Value: + IObjectCreationOperation (Constructor: S2..ctor()) (OperationKind.ObjectCreation, Type: S2) (Syntax: 'new S2()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new S2()') + Expression: + IInvocationOperation ( System.Threading.Tasks.ValueTask S2.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S2()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S2()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var src2 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() => throw null; + + public ValueTask DisposeAsync() + { + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await using (new S2()) + { + await Task.Yield(); + } + } +} +"; + + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp2.VerifyEmitDiagnostics( + // (19,22): error CS4007: Instance of type 'S2' cannot be preserved across 'await' or 'yield' boundary. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new S2()").WithArguments("S2").WithLocation(19, 22) + ); + } + + [Fact] + public void AwaitUsing_04() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : IAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + System.Console.Write(123); + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", +@" +{ + // Code size 241 (0xf1) + .maxstack 3 + .locals init (int V_0, + T V_1, + object V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0079 + IL_000a: call ""T System.Activator.CreateInstance()"" + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: ldnull + IL_0012: stfld ""object C.d__1.<>7__wrap1"" + IL_0017: ldarg.0 + IL_0018: ldc.i4.0 + IL_0019: stfld ""int C.d__1.<>7__wrap2"" + .try + { + IL_001e: ldc.i4.s 123 + IL_0020: call ""void System.Console.Write(int)"" + IL_0025: leave.s IL_0031 + } + catch object + { + IL_0027: stloc.2 + IL_0028: ldarg.0 + IL_0029: ldloc.2 + IL_002a: stfld ""object C.d__1.<>7__wrap1"" + IL_002f: leave.s IL_0031 + } + IL_0031: ldloc.1 + IL_0032: box ""T"" + IL_0037: brfalse.s IL_009c + IL_0039: ldloca.s V_1 + IL_003b: constrained. ""T"" + IL_0041: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_0046: stloc.s V_4 + IL_0048: ldloca.s V_4 + IL_004a: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_004f: stloc.3 + IL_0050: ldloca.s V_3 + IL_0052: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0057: brtrue.s IL_0095 + IL_0059: ldarg.0 + IL_005a: ldc.i4.0 + IL_005b: dup + IL_005c: stloc.0 + IL_005d: stfld ""int C.d__1.<>1__state"" + IL_0062: ldarg.0 + IL_0063: ldloc.3 + IL_0064: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0069: ldarg.0 + IL_006a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_006f: ldloca.s V_3 + IL_0071: ldarg.0 + IL_0072: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0077: leave.s IL_00f0 + IL_0079: ldarg.0 + IL_007a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_007f: stloc.3 + IL_0080: ldarg.0 + IL_0081: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0086: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_008c: ldarg.0 + IL_008d: ldc.i4.m1 + IL_008e: dup + IL_008f: stloc.0 + IL_0090: stfld ""int C.d__1.<>1__state"" + IL_0095: ldloca.s V_3 + IL_0097: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_009c: ldarg.0 + IL_009d: ldfld ""object C.d__1.<>7__wrap1"" + IL_00a2: stloc.2 + IL_00a3: ldloc.2 + IL_00a4: brfalse.s IL_00bb + IL_00a6: ldloc.2 + IL_00a7: isinst ""System.Exception"" + IL_00ac: dup + IL_00ad: brtrue.s IL_00b1 + IL_00af: ldloc.2 + IL_00b0: throw + IL_00b1: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_00b6: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_00bb: ldarg.0 + IL_00bc: ldnull + IL_00bd: stfld ""object C.d__1.<>7__wrap1"" + IL_00c2: leave.s IL_00dd + } + catch System.Exception + { + IL_00c4: stloc.s V_5 + IL_00c6: ldarg.0 + IL_00c7: ldc.i4.s -2 + IL_00c9: stfld ""int C.d__1.<>1__state"" + IL_00ce: ldarg.0 + IL_00cf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00d4: ldloc.s V_5 + IL_00d6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00db: leave.s IL_00f0 + } + IL_00dd: ldarg.0 + IL_00de: ldc.i4.s -2 + IL_00e0: stfld ""int C.d__1.<>1__state"" + IL_00e5: ldarg.0 + IL_00e6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00eb: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00f0: ret +} +"); + + var tree = comp1.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp1, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new T()') + Value: + ITypeParameterObjectCreationOperation (OperationKind.TypeParameterObjectCreation, Type: T) (Syntax: 'new T()') + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B6] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B5] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new T()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 'new T()') + Next (Regular) Block[B4] + Block[B4] - Block + Predecessors: [B3] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new T()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new T()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 'new T()') + Arguments(0) + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B3] [B4] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B6] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var src2 = @" +using System; +using System.Threading.Tasks; + +class C +{ + static async Task Test() where T : IAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + await Task.Yield(); + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics( + // (9,22): error CS4007: Instance of type 'T' cannot be preserved across 'await' or 'yield' boundary. + // await using (new T()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new T()").WithArguments("T").WithLocation(9, 22) + ); + } + + [Fact] + public void AwaitUsing_05() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +ref struct S2 : IAsyncDisposable +{ + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : struct, IAsyncDisposable, allows ref struct + { + await using (new T()) + { + System.Console.Write(123); + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", +@" +{ + // Code size 233 (0xe9) + .maxstack 3 + .locals init (int V_0, + T V_1, + object V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0071 + IL_000a: call ""T System.Activator.CreateInstance()"" + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: ldnull + IL_0012: stfld ""object C.d__1.<>7__wrap1"" + IL_0017: ldarg.0 + IL_0018: ldc.i4.0 + IL_0019: stfld ""int C.d__1.<>7__wrap2"" + .try + { + IL_001e: ldc.i4.s 123 + IL_0020: call ""void System.Console.Write(int)"" + IL_0025: leave.s IL_0031 + } + catch object + { + IL_0027: stloc.2 + IL_0028: ldarg.0 + IL_0029: ldloc.2 + IL_002a: stfld ""object C.d__1.<>7__wrap1"" + IL_002f: leave.s IL_0031 + } + IL_0031: ldloca.s V_1 + IL_0033: constrained. ""T"" + IL_0039: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_003e: stloc.s V_4 + IL_0040: ldloca.s V_4 + IL_0042: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_0047: stloc.3 + IL_0048: ldloca.s V_3 + IL_004a: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_004f: brtrue.s IL_008d + IL_0051: ldarg.0 + IL_0052: ldc.i4.0 + IL_0053: dup + IL_0054: stloc.0 + IL_0055: stfld ""int C.d__1.<>1__state"" + IL_005a: ldarg.0 + IL_005b: ldloc.3 + IL_005c: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0061: ldarg.0 + IL_0062: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0067: ldloca.s V_3 + IL_0069: ldarg.0 + IL_006a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_006f: leave.s IL_00e8 + IL_0071: ldarg.0 + IL_0072: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0077: stloc.3 + IL_0078: ldarg.0 + IL_0079: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_007e: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_0084: ldarg.0 + IL_0085: ldc.i4.m1 + IL_0086: dup + IL_0087: stloc.0 + IL_0088: stfld ""int C.d__1.<>1__state"" + IL_008d: ldloca.s V_3 + IL_008f: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_0094: ldarg.0 + IL_0095: ldfld ""object C.d__1.<>7__wrap1"" + IL_009a: stloc.2 + IL_009b: ldloc.2 + IL_009c: brfalse.s IL_00b3 + IL_009e: ldloc.2 + IL_009f: isinst ""System.Exception"" + IL_00a4: dup + IL_00a5: brtrue.s IL_00a9 + IL_00a7: ldloc.2 + IL_00a8: throw + IL_00a9: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_00ae: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_00b3: ldarg.0 + IL_00b4: ldnull + IL_00b5: stfld ""object C.d__1.<>7__wrap1"" + IL_00ba: leave.s IL_00d5 + } + catch System.Exception + { + IL_00bc: stloc.s V_5 + IL_00be: ldarg.0 + IL_00bf: ldc.i4.s -2 + IL_00c1: stfld ""int C.d__1.<>1__state"" + IL_00c6: ldarg.0 + IL_00c7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00cc: ldloc.s V_5 + IL_00ce: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00d3: leave.s IL_00e8 + } + IL_00d5: ldarg.0 + IL_00d6: ldc.i4.s -2 + IL_00d8: stfld ""int C.d__1.<>1__state"" + IL_00dd: ldarg.0 + IL_00de: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00e3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00e8: ret +} +"); + + var tree = comp1.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp1, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new T()') + Value: + ITypeParameterObjectCreationOperation (OperationKind.TypeParameterObjectCreation, Type: T) (Syntax: 'new T()') + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B4] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new T()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new T()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 'new T()') + Arguments(0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var src2 = @" +using System; +using System.Threading.Tasks; + +class C +{ + static async Task Test() where T : struct, IAsyncDisposable, allows ref struct + { + await using (new T()) + { + await Task.Yield(); + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics( + // (9,22): error CS4007: Instance of type 'T' cannot be preserved across 'await' or 'yield' boundary. + // await using (new T()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new T()").WithArguments("T").WithLocation(9, 22) + ); + } + + [Fact] + public void AwaitUsing_06() + { + var src1 = @" +using System.Threading.Tasks; + +interface IMyAsyncDisposable +{ + ValueTask DisposeAsync(); +} + +ref struct S2 : IMyAsyncDisposable +{ + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : IMyAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + System.Console.Write(123); + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.Passes : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", +@" +{ + // Code size 241 (0xf1) + .maxstack 3 + .locals init (int V_0, + T V_1, + object V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + System.Exception V_5) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0079 + IL_000a: call ""T System.Activator.CreateInstance()"" + IL_000f: stloc.1 + IL_0010: ldarg.0 + IL_0011: ldnull + IL_0012: stfld ""object C.d__1.<>7__wrap1"" + IL_0017: ldarg.0 + IL_0018: ldc.i4.0 + IL_0019: stfld ""int C.d__1.<>7__wrap2"" + .try + { + IL_001e: ldc.i4.s 123 + IL_0020: call ""void System.Console.Write(int)"" + IL_0025: leave.s IL_0031 + } + catch object + { + IL_0027: stloc.2 + IL_0028: ldarg.0 + IL_0029: ldloc.2 + IL_002a: stfld ""object C.d__1.<>7__wrap1"" + IL_002f: leave.s IL_0031 + } + IL_0031: ldloc.1 + IL_0032: box ""T"" + IL_0037: brfalse.s IL_009c + IL_0039: ldloca.s V_1 + IL_003b: constrained. ""T"" + IL_0041: callvirt ""System.Threading.Tasks.ValueTask IMyAsyncDisposable.DisposeAsync()"" + IL_0046: stloc.s V_4 + IL_0048: ldloca.s V_4 + IL_004a: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_004f: stloc.3 + IL_0050: ldloca.s V_3 + IL_0052: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0057: brtrue.s IL_0095 + IL_0059: ldarg.0 + IL_005a: ldc.i4.0 + IL_005b: dup + IL_005c: stloc.0 + IL_005d: stfld ""int C.d__1.<>1__state"" + IL_0062: ldarg.0 + IL_0063: ldloc.3 + IL_0064: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0069: ldarg.0 + IL_006a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_006f: ldloca.s V_3 + IL_0071: ldarg.0 + IL_0072: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0077: leave.s IL_00f0 + IL_0079: ldarg.0 + IL_007a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_007f: stloc.3 + IL_0080: ldarg.0 + IL_0081: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0086: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_008c: ldarg.0 + IL_008d: ldc.i4.m1 + IL_008e: dup + IL_008f: stloc.0 + IL_0090: stfld ""int C.d__1.<>1__state"" + IL_0095: ldloca.s V_3 + IL_0097: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_009c: ldarg.0 + IL_009d: ldfld ""object C.d__1.<>7__wrap1"" + IL_00a2: stloc.2 + IL_00a3: ldloc.2 + IL_00a4: brfalse.s IL_00bb + IL_00a6: ldloc.2 + IL_00a7: isinst ""System.Exception"" + IL_00ac: dup + IL_00ad: brtrue.s IL_00b1 + IL_00af: ldloc.2 + IL_00b0: throw + IL_00b1: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_00b6: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_00bb: ldarg.0 + IL_00bc: ldnull + IL_00bd: stfld ""object C.d__1.<>7__wrap1"" + IL_00c2: leave.s IL_00dd + } + catch System.Exception + { + IL_00c4: stloc.s V_5 + IL_00c6: ldarg.0 + IL_00c7: ldc.i4.s -2 + IL_00c9: stfld ""int C.d__1.<>1__state"" + IL_00ce: ldarg.0 + IL_00cf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00d4: ldloc.s V_5 + IL_00d6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_00db: leave.s IL_00f0 + } + IL_00dd: ldarg.0 + IL_00de: ldc.i4.s -2 + IL_00e0: stfld ""int C.d__1.<>1__state"" + IL_00e5: ldarg.0 + IL_00e6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_00eb: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_00f0: ret +} +"); + + var tree = comp1.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp1, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new T()') + Value: + ITypeParameterObjectCreationOperation (OperationKind.TypeParameterObjectCreation, Type: T) (Syntax: 'new T()') + Initializer: + null + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] + Statements (1) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Cons ... Write(123);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Cons ... .Write(123)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: '123') + ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 123) (Syntax: '123') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B6] + Finalizing: {R4} + Leaving: {R3} {R2} {R1} + } + .finally {R4} + { + Block[B3] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B5] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new T()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 'new T()') + Next (Regular) Block[B4] + Block[B4] - Block + Predecessors: [B3] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new T()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask IMyAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new T()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: T, IsImplicit) (Syntax: 'new T()') + Arguments(0) + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B3] [B4] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B6] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var src2 = @" +using System.Threading.Tasks; + +interface IMyAsyncDisposable +{ + ValueTask DisposeAsync(); +} + +class C +{ + static async Task Test() where T : IMyAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + await Task.Yield(); + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics( + // (13,22): error CS4007: Instance of type 'T' cannot be preserved across 'await' or 'yield' boundary. + // await using (new T()) + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new T()").WithArguments("T").WithLocation(13, 22) + ); + } + + [Fact] + public void AwaitUsing_07() + { + var src = @" +using System.Threading.Tasks; + +interface IMyAsyncDisposable1 +{ + ValueTask DisposeAsync(); +} + +interface IMyAsyncDisposable2 +{ + ValueTask DisposeAsync(); +} + +ref struct S2 : IMyAsyncDisposable1, IMyAsyncDisposable2 +{ + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : IMyAsyncDisposable1, IMyAsyncDisposable2, new(), allows ref struct + { + await using (new T()) + { + System.Console.Write(123); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (32,22): error CS0121: The call is ambiguous between the following methods or properties: 'IMyAsyncDisposable1.DisposeAsync()' and 'IMyAsyncDisposable2.DisposeAsync()' + // await using (new T()) + Diagnostic(ErrorCode.ERR_AmbigCall, "new T()").WithArguments("IMyAsyncDisposable1.DisposeAsync()", "IMyAsyncDisposable2.DisposeAsync()").WithLocation(32, 22), + // (32,22): error CS8410: 'T': type used in an asynchronous using statement must be implicitly convertible to 'System.IAsyncDisposable' or implement a suitable 'DisposeAsync' method. + // await using (new T()) + Diagnostic(ErrorCode.ERR_NoConvToIAsyncDisp, "new T()").WithArguments("T").WithLocation(32, 22) + ); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/72819")] + public void AwaitUsing_08() + { + var src = @" +using System; +using System.Threading.Tasks; + +interface IMyAsyncDisposable1 +{ + ValueTask DisposeAsync(); +} + +interface IMyAsyncDisposable2 +{ + ValueTask DisposeAsync(); +} + +ref struct S2 : IMyAsyncDisposable1, IMyAsyncDisposable2, IAsyncDisposable +{ + ValueTask IMyAsyncDisposable1.DisposeAsync() => throw null; + ValueTask IMyAsyncDisposable2.DisposeAsync() => throw null; + + public ValueTask DisposeAsync() + { + System.Console.Write('D'); + return ValueTask.CompletedTask; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : IMyAsyncDisposable1, IMyAsyncDisposable2, IAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + System.Console.Write(123); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + // https://github.com/dotnet/roslyn/issues/72819: The failure is likely unexpected, but is not specific to `allow ref struct` scenario. + comp.VerifyDiagnostics( + // (36,22): error CS0121: The call is ambiguous between the following methods or properties: 'IMyAsyncDisposable1.DisposeAsync()' and 'IMyAsyncDisposable2.DisposeAsync()' + // await using (new T()) + Diagnostic(ErrorCode.ERR_AmbigCall, "new T()").WithArguments("IMyAsyncDisposable1.DisposeAsync()", "IMyAsyncDisposable2.DisposeAsync()").WithLocation(36, 22) + ); + } + + [ConditionalFact(typeof(NoUsedAssembliesValidation))] // https://github.com/dotnet/roslyn/issues/73563 + [WorkItem("https://github.com/dotnet/roslyn/issues/73563")] + public void AwaitUsing_LanguageVersion_01() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +public ref struct S2 : IAsyncDisposable +{ + public ValueTask DisposeAsync() + { + return ValueTask.CompletedTask; + } +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await using (new S2()) + { + } + + await using (var s = new S2()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S2()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 22), + // (10,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (var s = new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 22) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitUsing_LanguageVersion_02() + { + var src1 = @" +using System; +using System.Threading.Tasks; + +public ref struct S2 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() + { + return ValueTask.CompletedTask; + } +} + +public struct S3 : IAsyncDisposable +{ + ValueTask IAsyncDisposable.DisposeAsync() + { + return ValueTask.CompletedTask; + } +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await using (new S2()) + { + } + + await using (var s = new S2()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,22): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S2()").WithArguments("ref struct interfaces").WithLocation(6, 22), + // (6,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S2()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 22), + // (10,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (var s = new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 22), + // (10,22): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (var s = new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var s = new S2()").WithArguments("ref struct interfaces").WithLocation(10, 22) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (5,24): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S2 : IAsyncDisposable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "IAsyncDisposable").WithArguments("ref struct interfaces").WithLocation(5, 24), + // (25,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S2()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(25, 22), + // (29,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (var s = new S2()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(29, 22) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var src3 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await using (new S3()) + { + } + + await using (var s = new S3()) + { + } + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitUsing_LanguageVersion_04() + { + var src = @" +using System; +using System.Threading.Tasks; + +class C +{ + static async Task Test() where T : IAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + } + + await using (var s = new T()) + { + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (7,75): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static async Task Test() where T : IAsyncDisposable, new(), allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(7, 75), + // (9,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new T()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new T()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 22), + // (13,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (var s = new T()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 22), + // (23,63): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static T CreateInstance() where T : allows ref struct => default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(23, 63) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitUsing_LanguageVersion_06() + { + var src = @" + +using System.Threading.Tasks; + +class C +{ + static async Task Test() where T : IMyAsyncDisposable, new(), allows ref struct + { + await using (new T()) + { + } + + await using (var s = new T()) + { + } + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} + +interface IMyAsyncDisposable +{ + ValueTask DisposeAsync(); +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (7,77): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static async Task Test() where T : IMyAsyncDisposable, new(), allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(7, 77), + // (9,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (new T()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new T()").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 22), + // (13,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await using (var s = new T()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 22), + // (23,63): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static T CreateInstance() where T : allows ref struct => default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(23, 63) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitForeach_IAsyncEnumerableT_01() + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +ref struct S : IAsyncEnumerable +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", +@" +{ + // Code size 405 (0x195) + .maxstack 3 + .locals init (int V_0, + S V_1, + System.Threading.CancellationToken V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + object V_5, + System.Runtime.CompilerServices.ValueTaskAwaiter V_6, + System.Threading.Tasks.ValueTask V_7, + System.Exception V_8) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.
d__0.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_003c + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_0111 + IL_0011: ldarg.0 + IL_0012: ldloca.s V_1 + IL_0014: dup + IL_0015: initobj ""S"" + IL_001b: ldloca.s V_2 + IL_001d: initobj ""System.Threading.CancellationToken"" + IL_0023: ldloc.2 + IL_0024: call ""System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator(System.Threading.CancellationToken)"" + IL_0029: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_002e: ldarg.0 + IL_002f: ldnull + IL_0030: stfld ""object C.
d__0.<>7__wrap2"" + IL_0035: ldarg.0 + IL_0036: ldc.i4.0 + IL_0037: stfld ""int C.
d__0.<>7__wrap3"" + IL_003c: nop + .try + { + IL_003d: ldloc.0 + IL_003e: brfalse.s IL_0093 + IL_0040: br.s IL_0052 + IL_0042: ldarg.0 + IL_0043: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_0048: callvirt ""int System.Collections.Generic.IAsyncEnumerator.Current.get"" + IL_004d: call ""void System.Console.Write(int)"" + IL_0052: ldarg.0 + IL_0053: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_0058: callvirt ""System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()"" + IL_005d: stloc.s V_4 + IL_005f: ldloca.s V_4 + IL_0061: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_0066: stloc.3 + IL_0067: ldloca.s V_3 + IL_0069: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_006e: brtrue.s IL_00af + IL_0070: ldarg.0 + IL_0071: ldc.i4.0 + IL_0072: dup + IL_0073: stloc.0 + IL_0074: stfld ""int C.
d__0.<>1__state"" + IL_0079: ldarg.0 + IL_007a: ldloc.3 + IL_007b: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_0080: ldarg.0 + IL_0081: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0086: ldloca.s V_3 + IL_0088: ldarg.0 + IL_0089: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" + IL_008e: leave IL_0194 + IL_0093: ldarg.0 + IL_0094: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_0099: stloc.3 + IL_009a: ldarg.0 + IL_009b: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_00a0: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_00a6: ldarg.0 + IL_00a7: ldc.i4.m1 + IL_00a8: dup + IL_00a9: stloc.0 + IL_00aa: stfld ""int C.
d__0.<>1__state"" + IL_00af: ldloca.s V_3 + IL_00b1: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_00b6: brtrue.s IL_0042 + IL_00b8: leave.s IL_00c6 + } + catch object + { + IL_00ba: stloc.s V_5 + IL_00bc: ldarg.0 + IL_00bd: ldloc.s V_5 + IL_00bf: stfld ""object C.
d__0.<>7__wrap2"" + IL_00c4: leave.s IL_00c6 + } + IL_00c6: ldarg.0 + IL_00c7: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_00cc: brfalse.s IL_0135 + IL_00ce: ldarg.0 + IL_00cf: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_00d4: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_00d9: stloc.s V_7 + IL_00db: ldloca.s V_7 + IL_00dd: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_00e2: stloc.s V_6 + IL_00e4: ldloca.s V_6 + IL_00e6: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_00eb: brtrue.s IL_012e + IL_00ed: ldarg.0 + IL_00ee: ldc.i4.1 + IL_00ef: dup + IL_00f0: stloc.0 + IL_00f1: stfld ""int C.
d__0.<>1__state"" + IL_00f6: ldarg.0 + IL_00f7: ldloc.s V_6 + IL_00f9: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" + IL_00fe: ldarg.0 + IL_00ff: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0104: ldloca.s V_6 + IL_0106: ldarg.0 + IL_0107: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" + IL_010c: leave IL_0194 + IL_0111: ldarg.0 + IL_0112: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" + IL_0117: stloc.s V_6 + IL_0119: ldarg.0 + IL_011a: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" + IL_011f: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_0125: ldarg.0 + IL_0126: ldc.i4.m1 + IL_0127: dup + IL_0128: stloc.0 + IL_0129: stfld ""int C.
d__0.<>1__state"" + IL_012e: ldloca.s V_6 + IL_0130: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_0135: ldarg.0 + IL_0136: ldfld ""object C.
d__0.<>7__wrap2"" + IL_013b: stloc.s V_5 + IL_013d: ldloc.s V_5 + IL_013f: brfalse.s IL_0158 + IL_0141: ldloc.s V_5 + IL_0143: isinst ""System.Exception"" + IL_0148: dup + IL_0149: brtrue.s IL_014e + IL_014b: ldloc.s V_5 + IL_014d: throw + IL_014e: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0153: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_0158: ldarg.0 + IL_0159: ldnull + IL_015a: stfld ""object C.
d__0.<>7__wrap2"" + IL_015f: ldarg.0 + IL_0160: ldnull + IL_0161: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_0166: leave.s IL_0181 + } + catch System.Exception + { + IL_0168: stloc.s V_8 + IL_016a: ldarg.0 + IL_016b: ldc.i4.s -2 + IL_016d: stfld ""int C.
d__0.<>1__state"" + IL_0172: ldarg.0 + IL_0173: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0178: ldloc.s V_8 + IL_017a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_017f: leave.s IL_0194 + } + IL_0181: ldarg.0 + IL_0182: ldc.i4.s -2 + IL_0184: stfld ""int C.
d__0.<>1__state"" + IL_0189: ldarg.0 + IL_018a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_018f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0194: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation ( System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator([System.Threading.CancellationToken token = default(System.Threading.CancellationToken)])) (OperationKind.Invocation, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(1): + IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: token) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'await forea ... }') + IDefaultValueOperation (OperationKind.DefaultValue, Type: System.Threading.CancellationToken, IsImplicit) (Syntax: 'await forea ... }') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IAwaitOperation (OperationKind.Await, Type: System.Boolean, IsImplicit) (Syntax: 'await forea ... }') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IAsyncEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator([System.Threading.CancellationToken token = default(System.Threading.CancellationToken)])", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator([System.Threading.CancellationToken token = default(System.Threading.CancellationToken)])", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Equal(1, op.Info.GetEnumeratorArguments.Length); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void AwaitForeach_IAsyncEnumerableT_02() + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +ref struct S : IAsyncEnumerable +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } + + IAsyncEnumerator IAsyncEnumerable.GetAsyncEnumerator(CancellationToken token) => throw null; +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.
d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", +@" +{ + // Code size 405 (0x195) + .maxstack 3 + .locals init (int V_0, + S V_1, + System.Threading.CancellationToken V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + object V_5, + System.Runtime.CompilerServices.ValueTaskAwaiter V_6, + System.Threading.Tasks.ValueTask V_7, + System.Exception V_8) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.
d__0.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_003c + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_0111 + IL_0011: ldarg.0 + IL_0012: ldloca.s V_1 + IL_0014: dup + IL_0015: initobj ""S"" + IL_001b: ldloca.s V_2 + IL_001d: initobj ""System.Threading.CancellationToken"" + IL_0023: ldloc.2 + IL_0024: call ""System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator(System.Threading.CancellationToken)"" + IL_0029: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_002e: ldarg.0 + IL_002f: ldnull + IL_0030: stfld ""object C.
d__0.<>7__wrap2"" + IL_0035: ldarg.0 + IL_0036: ldc.i4.0 + IL_0037: stfld ""int C.
d__0.<>7__wrap3"" + IL_003c: nop + .try + { + IL_003d: ldloc.0 + IL_003e: brfalse.s IL_0093 + IL_0040: br.s IL_0052 + IL_0042: ldarg.0 + IL_0043: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_0048: callvirt ""int System.Collections.Generic.IAsyncEnumerator.Current.get"" + IL_004d: call ""void System.Console.Write(int)"" + IL_0052: ldarg.0 + IL_0053: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_0058: callvirt ""System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()"" + IL_005d: stloc.s V_4 + IL_005f: ldloca.s V_4 + IL_0061: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_0066: stloc.3 + IL_0067: ldloca.s V_3 + IL_0069: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_006e: brtrue.s IL_00af + IL_0070: ldarg.0 + IL_0071: ldc.i4.0 + IL_0072: dup + IL_0073: stloc.0 + IL_0074: stfld ""int C.
d__0.<>1__state"" + IL_0079: ldarg.0 + IL_007a: ldloc.3 + IL_007b: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_0080: ldarg.0 + IL_0081: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0086: ldloca.s V_3 + IL_0088: ldarg.0 + IL_0089: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.
d__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" + IL_008e: leave IL_0194 + IL_0093: ldarg.0 + IL_0094: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_0099: stloc.3 + IL_009a: ldarg.0 + IL_009b: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__1"" + IL_00a0: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_00a6: ldarg.0 + IL_00a7: ldc.i4.m1 + IL_00a8: dup + IL_00a9: stloc.0 + IL_00aa: stfld ""int C.
d__0.<>1__state"" + IL_00af: ldloca.s V_3 + IL_00b1: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_00b6: brtrue.s IL_0042 + IL_00b8: leave.s IL_00c6 + } + catch object + { + IL_00ba: stloc.s V_5 + IL_00bc: ldarg.0 + IL_00bd: ldloc.s V_5 + IL_00bf: stfld ""object C.
d__0.<>7__wrap2"" + IL_00c4: leave.s IL_00c6 + } + IL_00c6: ldarg.0 + IL_00c7: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_00cc: brfalse.s IL_0135 + IL_00ce: ldarg.0 + IL_00cf: ldfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_00d4: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_00d9: stloc.s V_7 + IL_00db: ldloca.s V_7 + IL_00dd: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_00e2: stloc.s V_6 + IL_00e4: ldloca.s V_6 + IL_00e6: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_00eb: brtrue.s IL_012e + IL_00ed: ldarg.0 + IL_00ee: ldc.i4.1 + IL_00ef: dup + IL_00f0: stloc.0 + IL_00f1: stfld ""int C.
d__0.<>1__state"" + IL_00f6: ldarg.0 + IL_00f7: ldloc.s V_6 + IL_00f9: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" + IL_00fe: ldarg.0 + IL_00ff: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0104: ldloca.s V_6 + IL_0106: ldarg.0 + IL_0107: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.
d__0)"" + IL_010c: leave IL_0194 + IL_0111: ldarg.0 + IL_0112: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" + IL_0117: stloc.s V_6 + IL_0119: ldarg.0 + IL_011a: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.
d__0.<>u__2"" + IL_011f: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_0125: ldarg.0 + IL_0126: ldc.i4.m1 + IL_0127: dup + IL_0128: stloc.0 + IL_0129: stfld ""int C.
d__0.<>1__state"" + IL_012e: ldloca.s V_6 + IL_0130: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_0135: ldarg.0 + IL_0136: ldfld ""object C.
d__0.<>7__wrap2"" + IL_013b: stloc.s V_5 + IL_013d: ldloc.s V_5 + IL_013f: brfalse.s IL_0158 + IL_0141: ldloc.s V_5 + IL_0143: isinst ""System.Exception"" + IL_0148: dup + IL_0149: brtrue.s IL_014e + IL_014b: ldloc.s V_5 + IL_014d: throw + IL_014e: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0153: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_0158: ldarg.0 + IL_0159: ldnull + IL_015a: stfld ""object C.
d__0.<>7__wrap2"" + IL_015f: ldarg.0 + IL_0160: ldnull + IL_0161: stfld ""System.Collections.Generic.IAsyncEnumerator C.
d__0.<>7__wrap1"" + IL_0166: leave.s IL_0181 + } + catch System.Exception + { + IL_0168: stloc.s V_8 + IL_016a: ldarg.0 + IL_016b: ldc.i4.s -2 + IL_016d: stfld ""int C.
d__0.<>1__state"" + IL_0172: ldarg.0 + IL_0173: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_0178: ldloc.s V_8 + IL_017a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_017f: leave.s IL_0194 + } + IL_0181: ldarg.0 + IL_0182: ldc.i4.s -2 + IL_0184: stfld ""int C.
d__0.<>1__state"" + IL_0189: ldarg.0 + IL_018a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.
d__0.<>t__builder"" + IL_018f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_0194: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation ( System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator([System.Threading.CancellationToken token = default(System.Threading.CancellationToken)])) (OperationKind.Invocation, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(1): + IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: token) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'await forea ... }') + IDefaultValueOperation (OperationKind.DefaultValue, Type: System.Threading.CancellationToken, IsImplicit) (Syntax: 'await forea ... }') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IAwaitOperation (OperationKind.Await, Type: System.Boolean, IsImplicit) (Syntax: 'await forea ... }') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IAsyncEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator([System.Threading.CancellationToken token = default(System.Threading.CancellationToken)])", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator S.GetAsyncEnumerator([System.Threading.CancellationToken token = default(System.Threading.CancellationToken)])", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Equal(1, op.Info.GetEnumeratorArguments.Length); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void AwaitForeach_IAsyncEnumerableT_03() + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +ref struct S : IAsyncEnumerable +{ + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } + + IAsyncEnumerator IAsyncEnumerable.GetAsyncEnumerator(CancellationToken token) => Get123(); +} + +struct S2 : IAsyncEnumerable +{ + async static IAsyncEnumerator Get456() + { + await Task.Yield(); + yield return 456; + } + + IAsyncEnumerator IAsyncEnumerable.GetAsyncEnumerator(CancellationToken token) => Get456(); +} + +class C +{ + static async Task Main() + { + await Test1(); + await Test2(); + } + + static async Task Test1() + { + await foreach (var i in new S()) + { + System.Console.Write(i); + } + } + + static async Task Test2() + { + await foreach (var i in new S2()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123456" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", +@" +{ + // Code size 411 (0x19b) + .maxstack 3 + .locals init (int V_0, + S V_1, + System.Threading.CancellationToken V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + object V_5, + System.Runtime.CompilerServices.ValueTaskAwaiter V_6, + System.Threading.Tasks.ValueTask V_7, + System.Exception V_8) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0042 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_0117 + IL_0011: ldarg.0 + IL_0012: ldloca.s V_1 + IL_0014: dup + IL_0015: initobj ""S"" + IL_001b: ldloca.s V_2 + IL_001d: initobj ""System.Threading.CancellationToken"" + IL_0023: ldloc.2 + IL_0024: constrained. ""S"" + IL_002a: callvirt ""System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)"" + IL_002f: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_0034: ldarg.0 + IL_0035: ldnull + IL_0036: stfld ""object C.d__1.<>7__wrap2"" + IL_003b: ldarg.0 + IL_003c: ldc.i4.0 + IL_003d: stfld ""int C.d__1.<>7__wrap3"" + IL_0042: nop + .try + { + IL_0043: ldloc.0 + IL_0044: brfalse.s IL_0099 + IL_0046: br.s IL_0058 + IL_0048: ldarg.0 + IL_0049: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_004e: callvirt ""int System.Collections.Generic.IAsyncEnumerator.Current.get"" + IL_0053: call ""void System.Console.Write(int)"" + IL_0058: ldarg.0 + IL_0059: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_005e: callvirt ""System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()"" + IL_0063: stloc.s V_4 + IL_0065: ldloca.s V_4 + IL_0067: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_006c: stloc.3 + IL_006d: ldloca.s V_3 + IL_006f: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0074: brtrue.s IL_00b5 + IL_0076: ldarg.0 + IL_0077: ldc.i4.0 + IL_0078: dup + IL_0079: stloc.0 + IL_007a: stfld ""int C.d__1.<>1__state"" + IL_007f: ldarg.0 + IL_0080: ldloc.3 + IL_0081: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0086: ldarg.0 + IL_0087: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_008c: ldloca.s V_3 + IL_008e: ldarg.0 + IL_008f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0094: leave IL_019a + IL_0099: ldarg.0 + IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_009f: stloc.3 + IL_00a0: ldarg.0 + IL_00a1: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_00a6: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_00ac: ldarg.0 + IL_00ad: ldc.i4.m1 + IL_00ae: dup + IL_00af: stloc.0 + IL_00b0: stfld ""int C.d__1.<>1__state"" + IL_00b5: ldloca.s V_3 + IL_00b7: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_00bc: brtrue.s IL_0048 + IL_00be: leave.s IL_00cc + } + catch object + { + IL_00c0: stloc.s V_5 + IL_00c2: ldarg.0 + IL_00c3: ldloc.s V_5 + IL_00c5: stfld ""object C.d__1.<>7__wrap2"" + IL_00ca: leave.s IL_00cc + } + IL_00cc: ldarg.0 + IL_00cd: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00d2: brfalse.s IL_013b + IL_00d4: ldarg.0 + IL_00d5: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00da: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_00df: stloc.s V_7 + IL_00e1: ldloca.s V_7 + IL_00e3: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_00e8: stloc.s V_6 + IL_00ea: ldloca.s V_6 + IL_00ec: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_00f1: brtrue.s IL_0134 + IL_00f3: ldarg.0 + IL_00f4: ldc.i4.1 + IL_00f5: dup + IL_00f6: stloc.0 + IL_00f7: stfld ""int C.d__1.<>1__state"" + IL_00fc: ldarg.0 + IL_00fd: ldloc.s V_6 + IL_00ff: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0104: ldarg.0 + IL_0105: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_010a: ldloca.s V_6 + IL_010c: ldarg.0 + IL_010d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0112: leave IL_019a + IL_0117: ldarg.0 + IL_0118: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_011d: stloc.s V_6 + IL_011f: ldarg.0 + IL_0120: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0125: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_012b: ldarg.0 + IL_012c: ldc.i4.m1 + IL_012d: dup + IL_012e: stloc.0 + IL_012f: stfld ""int C.d__1.<>1__state"" + IL_0134: ldloca.s V_6 + IL_0136: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_013b: ldarg.0 + IL_013c: ldfld ""object C.d__1.<>7__wrap2"" + IL_0141: stloc.s V_5 + IL_0143: ldloc.s V_5 + IL_0145: brfalse.s IL_015e + IL_0147: ldloc.s V_5 + IL_0149: isinst ""System.Exception"" + IL_014e: dup + IL_014f: brtrue.s IL_0154 + IL_0151: ldloc.s V_5 + IL_0153: throw + IL_0154: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0159: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_015e: ldarg.0 + IL_015f: ldnull + IL_0160: stfld ""object C.d__1.<>7__wrap2"" + IL_0165: ldarg.0 + IL_0166: ldnull + IL_0167: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_016c: leave.s IL_0187 + } + catch System.Exception + { + IL_016e: stloc.s V_8 + IL_0170: ldarg.0 + IL_0171: ldc.i4.s -2 + IL_0173: stfld ""int C.d__1.<>1__state"" + IL_0178: ldarg.0 + IL_0179: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_017e: ldloc.s V_8 + IL_0180: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0185: leave.s IL_019a + } + IL_0187: ldarg.0 + IL_0188: ldc.i4.s -2 + IL_018a: stfld ""int C.d__1.<>1__state"" + IL_018f: ldarg.0 + IL_0190: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0195: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_019a: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test1").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation (virtual System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])) (OperationKind.Invocation, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(1): + IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: cancellationToken) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'new S()') + IDefaultValueOperation (OperationKind.DefaultValue, Type: System.Threading.CancellationToken, IsImplicit) (Syntax: 'new S()') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IAwaitOperation (OperationKind.Await, Type: System.Boolean, IsImplicit) (Syntax: 'await forea ... }') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IAsyncEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IAsyncDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().First(); + AssertEx.Equal("new S()", foreachSyntax.Expression.ToString()); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Equal(1, op.Info.GetEnumeratorArguments.Length); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerableT_04(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +ref struct S : IAsyncEnumerable +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : " + (addStructConstraint ? "struct, " : "") + @"IAsyncEnumerable, allows ref struct + { + await foreach (var i in default(T)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", +@" +{ + // Code size 411 (0x19b) + .maxstack 3 + .locals init (int V_0, + T V_1, + System.Threading.CancellationToken V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + object V_5, + System.Runtime.CompilerServices.ValueTaskAwaiter V_6, + System.Threading.Tasks.ValueTask V_7, + System.Exception V_8) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0042 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_0117 + IL_0011: ldarg.0 + IL_0012: ldloca.s V_1 + IL_0014: dup + IL_0015: initobj ""T"" + IL_001b: ldloca.s V_2 + IL_001d: initobj ""System.Threading.CancellationToken"" + IL_0023: ldloc.2 + IL_0024: constrained. ""T"" + IL_002a: callvirt ""System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)"" + IL_002f: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_0034: ldarg.0 + IL_0035: ldnull + IL_0036: stfld ""object C.d__1.<>7__wrap2"" + IL_003b: ldarg.0 + IL_003c: ldc.i4.0 + IL_003d: stfld ""int C.d__1.<>7__wrap3"" + IL_0042: nop + .try + { + IL_0043: ldloc.0 + IL_0044: brfalse.s IL_0099 + IL_0046: br.s IL_0058 + IL_0048: ldarg.0 + IL_0049: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_004e: callvirt ""int System.Collections.Generic.IAsyncEnumerator.Current.get"" + IL_0053: call ""void System.Console.Write(int)"" + IL_0058: ldarg.0 + IL_0059: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_005e: callvirt ""System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()"" + IL_0063: stloc.s V_4 + IL_0065: ldloca.s V_4 + IL_0067: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_006c: stloc.3 + IL_006d: ldloca.s V_3 + IL_006f: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0074: brtrue.s IL_00b5 + IL_0076: ldarg.0 + IL_0077: ldc.i4.0 + IL_0078: dup + IL_0079: stloc.0 + IL_007a: stfld ""int C.d__1.<>1__state"" + IL_007f: ldarg.0 + IL_0080: ldloc.3 + IL_0081: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0086: ldarg.0 + IL_0087: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_008c: ldloca.s V_3 + IL_008e: ldarg.0 + IL_008f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0094: leave IL_019a + IL_0099: ldarg.0 + IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_009f: stloc.3 + IL_00a0: ldarg.0 + IL_00a1: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_00a6: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_00ac: ldarg.0 + IL_00ad: ldc.i4.m1 + IL_00ae: dup + IL_00af: stloc.0 + IL_00b0: stfld ""int C.d__1.<>1__state"" + IL_00b5: ldloca.s V_3 + IL_00b7: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_00bc: brtrue.s IL_0048 + IL_00be: leave.s IL_00cc + } + catch object + { + IL_00c0: stloc.s V_5 + IL_00c2: ldarg.0 + IL_00c3: ldloc.s V_5 + IL_00c5: stfld ""object C.d__1.<>7__wrap2"" + IL_00ca: leave.s IL_00cc + } + IL_00cc: ldarg.0 + IL_00cd: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00d2: brfalse.s IL_013b + IL_00d4: ldarg.0 + IL_00d5: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00da: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_00df: stloc.s V_7 + IL_00e1: ldloca.s V_7 + IL_00e3: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_00e8: stloc.s V_6 + IL_00ea: ldloca.s V_6 + IL_00ec: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_00f1: brtrue.s IL_0134 + IL_00f3: ldarg.0 + IL_00f4: ldc.i4.1 + IL_00f5: dup + IL_00f6: stloc.0 + IL_00f7: stfld ""int C.d__1.<>1__state"" + IL_00fc: ldarg.0 + IL_00fd: ldloc.s V_6 + IL_00ff: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0104: ldarg.0 + IL_0105: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_010a: ldloca.s V_6 + IL_010c: ldarg.0 + IL_010d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0112: leave IL_019a + IL_0117: ldarg.0 + IL_0118: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_011d: stloc.s V_6 + IL_011f: ldarg.0 + IL_0120: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0125: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_012b: ldarg.0 + IL_012c: ldc.i4.m1 + IL_012d: dup + IL_012e: stloc.0 + IL_012f: stfld ""int C.d__1.<>1__state"" + IL_0134: ldloca.s V_6 + IL_0136: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_013b: ldarg.0 + IL_013c: ldfld ""object C.d__1.<>7__wrap2"" + IL_0141: stloc.s V_5 + IL_0143: ldloc.s V_5 + IL_0145: brfalse.s IL_015e + IL_0147: ldloc.s V_5 + IL_0149: isinst ""System.Exception"" + IL_014e: dup + IL_014f: brtrue.s IL_0154 + IL_0151: ldloc.s V_5 + IL_0153: throw + IL_0154: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0159: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_015e: ldarg.0 + IL_015f: ldnull + IL_0160: stfld ""object C.d__1.<>7__wrap2"" + IL_0165: ldarg.0 + IL_0166: ldnull + IL_0167: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_016c: leave.s IL_0187 + } + catch System.Exception + { + IL_016e: stloc.s V_8 + IL_0170: ldarg.0 + IL_0171: ldc.i4.s -2 + IL_0173: stfld ""int C.d__1.<>1__state"" + IL_0178: ldarg.0 + IL_0179: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_017e: ldloc.s V_8 + IL_0180: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0185: leave.s IL_019a + } + IL_0187: ldarg.0 + IL_0188: ldc.i4.s -2 + IL_018a: stfld ""int C.d__1.<>1__state"" + IL_018f: ldarg.0 + IL_0190: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0195: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_019a: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'default(T)') + Value: + IInvocationOperation (virtual System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])) (OperationKind.Invocation, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 'default(T)') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IDefaultValueOperation (OperationKind.DefaultValue, Type: T) (Syntax: 'default(T)') + Arguments(1): + IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: cancellationToken) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'await forea ... }') + IDefaultValueOperation (OperationKind.DefaultValue, Type: System.Threading.CancellationToken, IsImplicit) (Syntax: 'await forea ... }') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IAwaitOperation (OperationKind.Await, Type: System.Boolean, IsImplicit) (Syntax: 'await forea ... }') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IAsyncEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'default(T)') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'default(T)') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Equal(1, op.Info.GetEnumeratorArguments.Length); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerableT_05(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +interface IMyAsyncEnumerable +{ + IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} + +ref struct S : IMyAsyncEnumerable +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : " + (addStructConstraint ? "struct, " : "") + @"IMyAsyncEnumerable, allows ref struct + { + await foreach (var i in default(T)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", +@" +{ + // Code size 411 (0x19b) + .maxstack 3 + .locals init (int V_0, + T V_1, + System.Threading.CancellationToken V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + object V_5, + System.Runtime.CompilerServices.ValueTaskAwaiter V_6, + System.Threading.Tasks.ValueTask V_7, + System.Exception V_8) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0042 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_0117 + IL_0011: ldarg.0 + IL_0012: ldloca.s V_1 + IL_0014: dup + IL_0015: initobj ""T"" + IL_001b: ldloca.s V_2 + IL_001d: initobj ""System.Threading.CancellationToken"" + IL_0023: ldloc.2 + IL_0024: constrained. ""T"" + IL_002a: callvirt ""System.Collections.Generic.IAsyncEnumerator IMyAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)"" + IL_002f: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_0034: ldarg.0 + IL_0035: ldnull + IL_0036: stfld ""object C.d__1.<>7__wrap2"" + IL_003b: ldarg.0 + IL_003c: ldc.i4.0 + IL_003d: stfld ""int C.d__1.<>7__wrap3"" + IL_0042: nop + .try + { + IL_0043: ldloc.0 + IL_0044: brfalse.s IL_0099 + IL_0046: br.s IL_0058 + IL_0048: ldarg.0 + IL_0049: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_004e: callvirt ""int System.Collections.Generic.IAsyncEnumerator.Current.get"" + IL_0053: call ""void System.Console.Write(int)"" + IL_0058: ldarg.0 + IL_0059: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_005e: callvirt ""System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()"" + IL_0063: stloc.s V_4 + IL_0065: ldloca.s V_4 + IL_0067: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_006c: stloc.3 + IL_006d: ldloca.s V_3 + IL_006f: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0074: brtrue.s IL_00b5 + IL_0076: ldarg.0 + IL_0077: ldc.i4.0 + IL_0078: dup + IL_0079: stloc.0 + IL_007a: stfld ""int C.d__1.<>1__state"" + IL_007f: ldarg.0 + IL_0080: ldloc.3 + IL_0081: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0086: ldarg.0 + IL_0087: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_008c: ldloca.s V_3 + IL_008e: ldarg.0 + IL_008f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0094: leave IL_019a + IL_0099: ldarg.0 + IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_009f: stloc.3 + IL_00a0: ldarg.0 + IL_00a1: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_00a6: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_00ac: ldarg.0 + IL_00ad: ldc.i4.m1 + IL_00ae: dup + IL_00af: stloc.0 + IL_00b0: stfld ""int C.d__1.<>1__state"" + IL_00b5: ldloca.s V_3 + IL_00b7: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_00bc: brtrue.s IL_0048 + IL_00be: leave.s IL_00cc + } + catch object + { + IL_00c0: stloc.s V_5 + IL_00c2: ldarg.0 + IL_00c3: ldloc.s V_5 + IL_00c5: stfld ""object C.d__1.<>7__wrap2"" + IL_00ca: leave.s IL_00cc + } + IL_00cc: ldarg.0 + IL_00cd: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00d2: brfalse.s IL_013b + IL_00d4: ldarg.0 + IL_00d5: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00da: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_00df: stloc.s V_7 + IL_00e1: ldloca.s V_7 + IL_00e3: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_00e8: stloc.s V_6 + IL_00ea: ldloca.s V_6 + IL_00ec: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_00f1: brtrue.s IL_0134 + IL_00f3: ldarg.0 + IL_00f4: ldc.i4.1 + IL_00f5: dup + IL_00f6: stloc.0 + IL_00f7: stfld ""int C.d__1.<>1__state"" + IL_00fc: ldarg.0 + IL_00fd: ldloc.s V_6 + IL_00ff: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0104: ldarg.0 + IL_0105: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_010a: ldloca.s V_6 + IL_010c: ldarg.0 + IL_010d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0112: leave IL_019a + IL_0117: ldarg.0 + IL_0118: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_011d: stloc.s V_6 + IL_011f: ldarg.0 + IL_0120: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0125: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_012b: ldarg.0 + IL_012c: ldc.i4.m1 + IL_012d: dup + IL_012e: stloc.0 + IL_012f: stfld ""int C.d__1.<>1__state"" + IL_0134: ldloca.s V_6 + IL_0136: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_013b: ldarg.0 + IL_013c: ldfld ""object C.d__1.<>7__wrap2"" + IL_0141: stloc.s V_5 + IL_0143: ldloc.s V_5 + IL_0145: brfalse.s IL_015e + IL_0147: ldloc.s V_5 + IL_0149: isinst ""System.Exception"" + IL_014e: dup + IL_014f: brtrue.s IL_0154 + IL_0151: ldloc.s V_5 + IL_0153: throw + IL_0154: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0159: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_015e: ldarg.0 + IL_015f: ldnull + IL_0160: stfld ""object C.d__1.<>7__wrap2"" + IL_0165: ldarg.0 + IL_0166: ldnull + IL_0167: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_016c: leave.s IL_0187 + } + catch System.Exception + { + IL_016e: stloc.s V_8 + IL_0170: ldarg.0 + IL_0171: ldc.i4.s -2 + IL_0173: stfld ""int C.d__1.<>1__state"" + IL_0178: ldarg.0 + IL_0179: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_017e: ldloc.s V_8 + IL_0180: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0185: leave.s IL_019a + } + IL_0187: ldarg.0 + IL_0188: ldc.i4.s -2 + IL_018a: stfld ""int C.d__1.<>1__state"" + IL_018f: ldarg.0 + IL_0190: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0195: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_019a: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'default(T)') + Value: + IInvocationOperation (virtual System.Collections.Generic.IAsyncEnumerator IMyAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])) (OperationKind.Invocation, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 'default(T)') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IDefaultValueOperation (OperationKind.DefaultValue, Type: T) (Syntax: 'default(T)') + Arguments(1): + IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: cancellationToken) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'await forea ... }') + IDefaultValueOperation (OperationKind.DefaultValue, Type: System.Threading.CancellationToken, IsImplicit) (Syntax: 'await forea ... }') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IAwaitOperation (OperationKind.Await, Type: System.Boolean, IsImplicit) (Syntax: 'await forea ... }') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IAsyncEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'default(T)') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'default(T)') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator IMyAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator IMyAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Equal(1, op.Info.GetEnumeratorArguments.Length); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerableT_06(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +interface IMyAsyncEnumerable1 +{ + IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} + +interface IMyAsyncEnumerable2 +{ + IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} + +ref struct S : IMyAsyncEnumerable1, IMyAsyncEnumerable2 +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : " + (addStructConstraint ? "struct, " : "") + @"IMyAsyncEnumerable1, IMyAsyncEnumerable2, allows ref struct + { + await foreach (var i in default(T)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (39,33): warning CS0278: 'T' does not implement the 'collection' pattern. 'IMyAsyncEnumerable1.GetAsyncEnumerator(CancellationToken)' is ambiguous with 'IMyAsyncEnumerable2.GetAsyncEnumerator(CancellationToken)'. + // await foreach (var i in default(T)) + Diagnostic(ErrorCode.WRN_PatternIsAmbiguous, "default(T)").WithArguments("T", "collection", "IMyAsyncEnumerable1.GetAsyncEnumerator(System.Threading.CancellationToken)", "IMyAsyncEnumerable2.GetAsyncEnumerator(System.Threading.CancellationToken)").WithLocation(39, 33), + // (39,33): error CS8411: Asynchronous foreach statement cannot operate on variables of type 'T' because 'T' does not contain a suitable public instance or extension definition for 'GetAsyncEnumerator' + // await foreach (var i in default(T)) + Diagnostic(ErrorCode.ERR_AwaitForEachMissingMember, "default(T)").WithArguments("T", "GetAsyncEnumerator").WithLocation(39, 33) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.GetEnumeratorMethod); + Assert.Null(info.ElementType); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerableT_07(bool addStructConstraint) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +interface IMyAsyncEnumerable1 +{ + IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} + +interface IMyAsyncEnumerable2 +{ + IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} + +ref struct S : IMyAsyncEnumerable1, IMyAsyncEnumerable2, IAsyncEnumerable +{ + IAsyncEnumerator IMyAsyncEnumerable1.GetAsyncEnumerator(CancellationToken token) => throw null; + IAsyncEnumerator IMyAsyncEnumerable2.GetAsyncEnumerator(CancellationToken token) => throw null; + + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() where T : " + (addStructConstraint ? "struct, " : "") + @"IMyAsyncEnumerable1, IMyAsyncEnumerable2, IAsyncEnumerable, allows ref struct + { + await foreach (var i in default(T)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics( + // (42,33): warning CS0278: 'T' does not implement the 'collection' pattern. 'IMyAsyncEnumerable1.GetAsyncEnumerator(CancellationToken)' is ambiguous with 'IMyAsyncEnumerable2.GetAsyncEnumerator(CancellationToken)'. + // await foreach (var i in default(T)) + Diagnostic(ErrorCode.WRN_PatternIsAmbiguous, "default(T)").WithArguments("T", "collection", "IMyAsyncEnumerable1.GetAsyncEnumerator(System.Threading.CancellationToken)", "IMyAsyncEnumerable2.GetAsyncEnumerator(System.Threading.CancellationToken)").WithLocation(42, 33) + ); + + verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", +@" +{ + // Code size 411 (0x19b) + .maxstack 3 + .locals init (int V_0, + T V_1, + System.Threading.CancellationToken V_2, + System.Runtime.CompilerServices.ValueTaskAwaiter V_3, + System.Threading.Tasks.ValueTask V_4, + object V_5, + System.Runtime.CompilerServices.ValueTaskAwaiter V_6, + System.Threading.Tasks.ValueTask V_7, + System.Exception V_8) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__1.<>1__state"" + IL_0006: stloc.0 + .try + { + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0042 + IL_000a: ldloc.0 + IL_000b: ldc.i4.1 + IL_000c: beq IL_0117 + IL_0011: ldarg.0 + IL_0012: ldloca.s V_1 + IL_0014: dup + IL_0015: initobj ""T"" + IL_001b: ldloca.s V_2 + IL_001d: initobj ""System.Threading.CancellationToken"" + IL_0023: ldloc.2 + IL_0024: constrained. ""T"" + IL_002a: callvirt ""System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator(System.Threading.CancellationToken)"" + IL_002f: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_0034: ldarg.0 + IL_0035: ldnull + IL_0036: stfld ""object C.d__1.<>7__wrap2"" + IL_003b: ldarg.0 + IL_003c: ldc.i4.0 + IL_003d: stfld ""int C.d__1.<>7__wrap3"" + IL_0042: nop + .try + { + IL_0043: ldloc.0 + IL_0044: brfalse.s IL_0099 + IL_0046: br.s IL_0058 + IL_0048: ldarg.0 + IL_0049: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_004e: callvirt ""int System.Collections.Generic.IAsyncEnumerator.Current.get"" + IL_0053: call ""void System.Console.Write(int)"" + IL_0058: ldarg.0 + IL_0059: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_005e: callvirt ""System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()"" + IL_0063: stloc.s V_4 + IL_0065: ldloca.s V_4 + IL_0067: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_006c: stloc.3 + IL_006d: ldloca.s V_3 + IL_006f: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_0074: brtrue.s IL_00b5 + IL_0076: ldarg.0 + IL_0077: ldc.i4.0 + IL_0078: dup + IL_0079: stloc.0 + IL_007a: stfld ""int C.d__1.<>1__state"" + IL_007f: ldarg.0 + IL_0080: ldloc.3 + IL_0081: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_0086: ldarg.0 + IL_0087: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_008c: ldloca.s V_3 + IL_008e: ldarg.0 + IL_008f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0094: leave IL_019a + IL_0099: ldarg.0 + IL_009a: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_009f: stloc.3 + IL_00a0: ldarg.0 + IL_00a1: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__1"" + IL_00a6: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_00ac: ldarg.0 + IL_00ad: ldc.i4.m1 + IL_00ae: dup + IL_00af: stloc.0 + IL_00b0: stfld ""int C.d__1.<>1__state"" + IL_00b5: ldloca.s V_3 + IL_00b7: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_00bc: brtrue.s IL_0048 + IL_00be: leave.s IL_00cc + } + catch object + { + IL_00c0: stloc.s V_5 + IL_00c2: ldarg.0 + IL_00c3: ldloc.s V_5 + IL_00c5: stfld ""object C.d__1.<>7__wrap2"" + IL_00ca: leave.s IL_00cc + } + IL_00cc: ldarg.0 + IL_00cd: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00d2: brfalse.s IL_013b + IL_00d4: ldarg.0 + IL_00d5: ldfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_00da: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" + IL_00df: stloc.s V_7 + IL_00e1: ldloca.s V_7 + IL_00e3: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" + IL_00e8: stloc.s V_6 + IL_00ea: ldloca.s V_6 + IL_00ec: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" + IL_00f1: brtrue.s IL_0134 + IL_00f3: ldarg.0 + IL_00f4: ldc.i4.1 + IL_00f5: dup + IL_00f6: stloc.0 + IL_00f7: stfld ""int C.d__1.<>1__state"" + IL_00fc: ldarg.0 + IL_00fd: ldloc.s V_6 + IL_00ff: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0104: ldarg.0 + IL_0105: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_010a: ldloca.s V_6 + IL_010c: ldarg.0 + IL_010d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__1)"" + IL_0112: leave IL_019a + IL_0117: ldarg.0 + IL_0118: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_011d: stloc.s V_6 + IL_011f: ldarg.0 + IL_0120: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__1.<>u__2"" + IL_0125: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" + IL_012b: ldarg.0 + IL_012c: ldc.i4.m1 + IL_012d: dup + IL_012e: stloc.0 + IL_012f: stfld ""int C.d__1.<>1__state"" + IL_0134: ldloca.s V_6 + IL_0136: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" + IL_013b: ldarg.0 + IL_013c: ldfld ""object C.d__1.<>7__wrap2"" + IL_0141: stloc.s V_5 + IL_0143: ldloc.s V_5 + IL_0145: brfalse.s IL_015e + IL_0147: ldloc.s V_5 + IL_0149: isinst ""System.Exception"" + IL_014e: dup + IL_014f: brtrue.s IL_0154 + IL_0151: ldloc.s V_5 + IL_0153: throw + IL_0154: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" + IL_0159: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" + IL_015e: ldarg.0 + IL_015f: ldnull + IL_0160: stfld ""object C.d__1.<>7__wrap2"" + IL_0165: ldarg.0 + IL_0166: ldnull + IL_0167: stfld ""System.Collections.Generic.IAsyncEnumerator C.d__1.<>7__wrap1"" + IL_016c: leave.s IL_0187 + } + catch System.Exception + { + IL_016e: stloc.s V_8 + IL_0170: ldarg.0 + IL_0171: ldc.i4.s -2 + IL_0173: stfld ""int C.d__1.<>1__state"" + IL_0178: ldarg.0 + IL_0179: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_017e: ldloc.s V_8 + IL_0180: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_0185: leave.s IL_019a + } + IL_0187: ldarg.0 + IL_0188: ldc.i4.s -2 + IL_018a: stfld ""int C.d__1.<>1__state"" + IL_018f: ldarg.0 + IL_0190: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0195: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" + IL_019a: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'default(T)') + Value: + IInvocationOperation (virtual System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])) (OperationKind.Invocation, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 'default(T)') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IDefaultValueOperation (OperationKind.DefaultValue, Type: T) (Syntax: 'default(T)') + Arguments(1): + IArgumentOperation (ArgumentKind.DefaultValue, Matching Parameter: cancellationToken) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'default(T)') + IDefaultValueOperation (OperationKind.DefaultValue, Type: System.Threading.CancellationToken, IsImplicit) (Syntax: 'default(T)') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IAwaitOperation (OperationKind.Await, Type: System.Boolean, IsImplicit) (Syntax: 'await forea ... }') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.Collections.Generic.IAsyncEnumerator.MoveNextAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Int32 i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Int32 System.Collections.Generic.IAsyncEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Int32, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Int32 value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Int32) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + Block[B4] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'default(T)') + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'default(T)') + Expression: + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'default(T)') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IAsyncDisposable, IsImplicit) (Syntax: 'default(T)') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'default(T)') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Int32", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.Generic.IAsyncEnumerator System.Collections.Generic.IAsyncEnumerable.GetAsyncEnumerator([System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)])", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Equal(1, op.Info.GetEnumeratorArguments.Length); + AssertEx.Equal("System.Int32", op.Info.ElementType.ToTestDisplayString()); + } + + [ConditionalFact(typeof(NoUsedAssembliesValidation))] // https://github.com/dotnet/roslyn/issues/73563 + [WorkItem("https://github.com/dotnet/roslyn/issues/73563")] + public void AwaitForeach_IAsyncEnumerableT_LanguageVersion_01() + { + var src1 = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +public ref struct S : IAsyncEnumerable +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +using System.Threading.Tasks; + +class C +{ + static async Task Main() + { + await foreach (var i in new S()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitForeach_IAsyncEnumerableT_LanguageVersion_03() + { + var src1 = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +public ref struct S : IAsyncEnumerable +{ + IAsyncEnumerator IAsyncEnumerable.GetAsyncEnumerator(CancellationToken token) => throw null; +} + +public struct S2 : IAsyncEnumerable +{ + IAsyncEnumerator IAsyncEnumerable.GetAsyncEnumerator(CancellationToken token) => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await foreach (var i in new S()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + + // Even though semantic analysis didn't produce any errors in C# 12 compiler, an attempt to emit was failing with + // "Unable to determine specific cause of the failure" error. + comp2.VerifyEmitDiagnostics( + // (6,33): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var i in new S()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S()").WithArguments("ref struct interfaces").WithLocation(6, 33) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,23): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S : IAsyncEnumerable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "IAsyncEnumerable").WithArguments("ref struct interfaces").WithLocation(6, 23) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var src3 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await foreach (var i in new S2()) + { + } + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitForeach_IAsyncEnumerableT_LanguageVersion_04() + { + var src = @" +using System.Collections.Generic; +using System.Threading.Tasks; + +class C +{ + static async Task Test() where T : IAsyncEnumerable, allows ref struct + { + await foreach (var i in default(T)) + { + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (7,73): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static async Task Test() where T : IAsyncEnumerable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(7, 73) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitForeach_IAsyncEnumerableT_LanguageVersion_05() + { + var src1 = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +public interface IMyAsyncEnumerable +{ + IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +using System.Threading.Tasks; + +class C +{ + static async Task Test() where T : IMyAsyncEnumerable, allows ref struct + { + await foreach (var i in default(T)) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,75): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static async Task Test() where T : IMyAsyncEnumerable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(6, 75) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitForeach_Pattern() + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +ref struct S +{ + public IAsyncEnumerator GetAsyncEnumerator(CancellationToken token = default) + { + return Get123(); + } + + async static IAsyncEnumerator Get123() + { + await Task.Yield(); + yield return 123; + } +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerator_01(bool s1IsRefStruct) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IAsyncEnumerator +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (27,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(27, 15) + ); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerator_03(bool s1IsRefStruct) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IAsyncEnumerator +{ + public int Current => throw null; + public ValueTask MoveNextAsync() => throw null; + + int IAsyncEnumerator.Current => throw null; + + ValueTask System.IAsyncDisposable.DisposeAsync() => throw null; + + ValueTask IAsyncEnumerator.MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (30,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(30, 15) + ); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerator_05(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +interface IGetEnumerator where TEnumerator : IAsyncEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IAsyncEnumerator +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"IAsyncEnumerator, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (39,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(39, 15) + ); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerator_07(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Threading; +using System.Threading.Tasks; + +interface IMyAsyncEnumerator +{ + T Current {get;} + + ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : IMyAsyncEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IMyAsyncEnumerator +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"IMyAsyncEnumerator, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (45,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(45, 15) + ); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerator_08(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Threading; +using System.Threading.Tasks; + +interface IMyAsyncEnumerator1 +{ + T Current {get;} + + ValueTask MoveNextAsync(); +} + +interface IMyAsyncEnumerator2 +{ + T Current {get;} + + ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : IMyAsyncEnumerator1, IMyAsyncEnumerator2, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IMyAsyncEnumerator1, IMyAsyncEnumerator2 +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"IMyAsyncEnumerator1, IMyAsyncEnumerator2, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (52,33): error CS8412: Asynchronous foreach requires that the return type 'TEnumerator' of 'IGetEnumerator.GetAsyncEnumerator(CancellationToken)' must have a suitable public 'MoveNextAsync' method and public 'Current' property + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadGetAsyncEnumerator, "default(TEnumerable)").WithArguments("TEnumerator", "IGetEnumerator.GetAsyncEnumerator(System.Threading.CancellationToken)").WithLocation(52, 33) + ); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncEnumerator_09(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +interface IMyAsyncEnumerator1 +{ + T Current {get;} + + ValueTask MoveNextAsync(); +} + +interface IMyAsyncEnumerator2 +{ + T Current {get;} + + ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : IMyAsyncEnumerator1, IMyAsyncEnumerator2, IAsyncEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IMyAsyncEnumerator1, IMyAsyncEnumerator2, IAsyncEnumerator +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"IMyAsyncEnumerator1, IMyAsyncEnumerator2, IAsyncEnumerator, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (53,33): error CS8412: Asynchronous foreach requires that the return type 'TEnumerator' of 'IGetEnumerator.GetAsyncEnumerator(CancellationToken)' must have a suitable public 'MoveNextAsync' method and public 'Current' property + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadGetAsyncEnumerator, "default(TEnumerable)").WithArguments("TEnumerator", "IGetEnumerator.GetAsyncEnumerator(System.Threading.CancellationToken)").WithLocation(53, 33) + ); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_01(bool s1IsRefStruct) + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IAsyncDisposable +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (27,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(27, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Threading.Tasks.ValueTask S2.DisposeAsync()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("System.Threading.Tasks.ValueTask S2.DisposeAsync()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_02(bool s1IsRefStruct) + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IAsyncDisposable +{ + public int Current => throw null; + + ValueTask IAsyncDisposable.DisposeAsync() => throw null; + public ValueTask DisposeAsync() => throw null; + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (27,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(27, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Threading.Tasks.ValueTask S2.DisposeAsync()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("System.Threading.Tasks.ValueTask S2.DisposeAsync()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_03(bool s1IsRefStruct) + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : IAsyncDisposable +{ + public int Current => throw null; + + ValueTask IAsyncDisposable.DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (27,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(27, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_04(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +interface ICustomEnumerator +{ + public int Current {get;} + + public ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : ICustomEnumerator, IAsyncDisposable +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, IAsyncDisposable, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (46,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(46, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_06(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Threading; +using System.Threading.Tasks; + +interface ICustomEnumerator +{ + public int Current {get;} + + public ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +interface IMyAsyncDisposable +{ + ValueTask DisposeAsync(); +} + +ref struct S2 : ICustomEnumerator, IMyAsyncDisposable +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, IMyAsyncDisposable, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (50,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(50, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Threading.Tasks.ValueTask IMyAsyncDisposable.DisposeAsync()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.True(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + AssertEx.Equal("System.Threading.Tasks.ValueTask IMyAsyncDisposable.DisposeAsync()", op.Info.PatternDisposeMethod.ToTestDisplayString()); + Assert.True(op.Info.DisposeArguments.IsEmpty); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_07(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Threading; +using System.Threading.Tasks; + +interface ICustomEnumerator +{ + public int Current {get;} + + public ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +interface IMyAsyncDisposable1 +{ + ValueTask DisposeAsync(); +} + +interface IMyAsyncDisposable2 +{ + ValueTask DisposeAsync(); +} + +ref struct S2 : ICustomEnumerator, IMyAsyncDisposable1, IMyAsyncDisposable2 +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, IMyAsyncDisposable1, IMyAsyncDisposable2, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (55,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(55, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_08(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +interface ICustomEnumerator +{ + public int Current {get;} + + public ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +interface IMyAsyncDisposable1 +{ + ValueTask DisposeAsync(); +} + +interface IMyAsyncDisposable2 +{ + ValueTask DisposeAsync(); +} + +ref struct S2 : ICustomEnumerator, IMyAsyncDisposable1, IMyAsyncDisposable2, IAsyncDisposable +{ + ValueTask IMyAsyncDisposable1.DisposeAsync() => throw null; + ValueTask IMyAsyncDisposable2.DisposeAsync() => throw null; + + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, IMyAsyncDisposable1, IMyAsyncDisposable2, IAsyncDisposable, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (59,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(59, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + AssertEx.Equal("System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void AwaitForeach_IAsyncDisposable_09(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +interface ICustomEnumerator +{ + public int Current {get;} + + public ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +ref struct S2 : ICustomEnumerator, IAsyncDisposable +{ + public int Current => throw null; + + public ValueTask DisposeAsync() => throw null; + + public ValueTask MoveNextAsync() => throw null; +} + +class C +{ + static async Task Main() + { + await Test(); + } + + static async Task Test() + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"ICustomEnumerator, allows ref struct + { + await foreach (var i in default(TEnumerable)) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (46,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(46, 15) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.True(info.IsAsynchronous); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.True(op.Info.IsAsynchronous); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Fact] + public void AwaitForeach_IAsyncDisposable_LanguageVersion_01() + { + var src1 = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +public struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +public ref struct S2 : IAsyncDisposable +{ + public int Current => throw null; + public ValueTask DisposeAsync() => throw null; + public ValueTask MoveNextAsync() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +class C +{ + static async Task Main() + { + await foreach (var i in new S1()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (10,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(10, 15) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics( + // (10,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(10, 15) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics( + // (10,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(10, 15) + ); + } + + [Fact] + public void AwaitForeach_IAsyncDisposable_LanguageVersion_03() + { + var src1 = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +public struct S1 +{ + public S2 GetAsyncEnumerator(CancellationToken token = default) + { + return new S2(); + } +} + +public ref struct S2 : IAsyncDisposable +{ + public int Current => throw null; + ValueTask IAsyncDisposable.DisposeAsync() => throw null; + public ValueTask MoveNextAsync() => throw null; +} + +public struct S3 +{ + public S4 GetAsyncEnumerator(CancellationToken token = default) + { + return new S4(); + } +} + +public struct S4 : IAsyncDisposable +{ + public int Current => throw null; + ValueTask IAsyncDisposable.DisposeAsync() => throw null; + public ValueTask MoveNextAsync() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await foreach (var i in new S1()) {} + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,9): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // await foreach (var i in new S1()) {} + Diagnostic(ErrorCode.ERR_FeatureInPreview, "await foreach (var i in new S1()) {}").WithArguments("ref struct interfaces").WithLocation(6, 9), + // (6,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(6, 15) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (14,24): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S2 : IAsyncDisposable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "IAsyncDisposable").WithArguments("ref struct interfaces").WithLocation(14, 24), + // (40,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(40, 15) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics( + // (6,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(6, 15) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics( + // (6,15): error CS8344: foreach statement cannot operate on enumerators of type 'S2' in async or iterator methods because 'S2' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in new S1()) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("S2").WithLocation(6, 15) + ); + + var src3 = @" +class C +{ + static async System.Threading.Tasks.Task Main() + { + await foreach (var i in new S3()) {} + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void AwaitForeach_IAsyncDisposable_LanguageVersion_04() + { + var src = @" +using System; +using System.Threading; +using System.Threading.Tasks; + +interface ICustomEnumerator +{ + public int Current {get;} + + public ValueTask MoveNextAsync(); +} + +interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct +{ + TEnumerator GetAsyncEnumerator(CancellationToken token = default); +} + +class C +{ + static async Task Test() + where TEnumerable : IGetEnumerator, allows ref struct + where TEnumerator : ICustomEnumerator, IAsyncDisposable, allows ref struct + { + await foreach (var i in default(TEnumerable)) {} + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (13,85): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // interface IGetEnumerator where TEnumerator : ICustomEnumerator, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(13, 85), + // (21,65): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where TEnumerable : IGetEnumerator, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(21, 65), + // (22,73): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where TEnumerator : ICustomEnumerator, IAsyncDisposable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(22, 73), + // (24,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(24, 15) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics( + // (24,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(24, 15) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics( + // (24,15): error CS8344: foreach statement cannot operate on enumerators of type 'TEnumerator' in async or iterator methods because 'TEnumerator' is a ref struct or a type parameter that allows ref struct. + // await foreach (var i in default(TEnumerable)) {} + Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("TEnumerator").WithLocation(24, 15) + ); + } + + [Fact] + public void Foreach_IEnumerable_01() + { + var src = @" +using System.Collections; + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 56 (0x38) + .maxstack 2 + .locals init (System.Collections.IEnumerator V_0, + S V_1, + System.IDisposable V_2) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S"" + IL_0009: call ""System.Collections.IEnumerator S.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001c + IL_0011: ldloc.0 + IL_0012: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_0017: call ""void System.Console.Write(object)"" + IL_001c: ldloc.0 + IL_001d: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0022: brtrue.s IL_0011 + IL_0024: leave.s IL_0037 + } + finally + { + IL_0026: ldloc.0 + IL_0027: isinst ""System.IDisposable"" + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: brfalse.s IL_0036 + IL_0030: ldloc.2 + IL_0031: callvirt ""void System.IDisposable.Dispose()"" + IL_0036: endfinally + } + IL_0037: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation ( System.Collections.IEnumerator S.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object System.Collections.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + CaptureIds: [1] + Block[B4] - Block + Predecessors (0) + Statements (1) + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IConversionOperation (TryCast: True, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ExplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator S.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator S.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void Foreach_IEnumerable_02() + { + var src = @" +using System.Collections; + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } + + IEnumerator IEnumerable.GetEnumerator() => throw null; +} + +class C +{ + static void Main() + { + foreach (var i in new S()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 56 (0x38) + .maxstack 2 + .locals init (System.Collections.IEnumerator V_0, + S V_1, + System.IDisposable V_2) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S"" + IL_0009: call ""System.Collections.IEnumerator S.GetEnumerator()"" + IL_000e: stloc.0 + .try + { + IL_000f: br.s IL_001c + IL_0011: ldloc.0 + IL_0012: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_0017: call ""void System.Console.Write(object)"" + IL_001c: ldloc.0 + IL_001d: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0022: brtrue.s IL_0011 + IL_0024: leave.s IL_0037 + } + finally + { + IL_0026: ldloc.0 + IL_0027: isinst ""System.IDisposable"" + IL_002c: stloc.2 + IL_002d: ldloc.2 + IL_002e: brfalse.s IL_0036 + IL_0030: ldloc.2 + IL_0031: callvirt ""void System.IDisposable.Dispose()"" + IL_0036: endfinally + } + IL_0037: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation ( System.Collections.IEnumerator S.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object System.Collections.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + CaptureIds: [1] + Block[B4] - Block + Predecessors (0) + Statements (1) + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IConversionOperation (TryCast: True, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ExplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator S.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator S.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void Foreach_IEnumerable_03() + { + var src = @" +using System.Collections; + +ref struct S : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +struct S1 : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() + { + return Get456(); + } + + static IEnumerator Get456() + { + yield return 456; + } +} + +class C +{ + static void Main() + { + Test1(); + Test2(); + } + + static void Test1() + { + foreach (var i in new S()) + { + System.Console.Write(i); + } + } + + static void Test2() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123456" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test1", +@" +{ + // Code size 62 (0x3e) + .maxstack 2 + .locals init (System.Collections.IEnumerator V_0, + S V_1, + System.IDisposable V_2) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S"" + IL_0009: constrained. ""S"" + IL_000f: callvirt ""System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()"" + IL_0014: stloc.0 + .try + { + IL_0015: br.s IL_0022 + IL_0017: ldloc.0 + IL_0018: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(object)"" + IL_0022: ldloc.0 + IL_0023: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0028: brtrue.s IL_0017 + IL_002a: leave.s IL_003d + } + finally + { + IL_002c: ldloc.0 + IL_002d: isinst ""System.IDisposable"" + IL_0032: stloc.2 + IL_0033: ldloc.2 + IL_0034: brfalse.s IL_003c + IL_0036: ldloc.2 + IL_0037: callvirt ""void System.IDisposable.Dispose()"" + IL_003c: endfinally + } + IL_003d: ret + } + "); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test1").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IInvocationOperation (virtual System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S..ctor()) (OperationKind.ObjectCreation, Type: S) (Syntax: 'new S()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object System.Collections.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + CaptureIds: [1] + Block[B4] - Block + Predecessors (0) + Statements (1) + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S()') + Value: + IConversionOperation (TryCast: True, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ExplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 'new S()') + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'new S()') + Operand: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new S()') + Instance Receiver: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'new S()') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().First(); + AssertEx.Equal("new S()", foreachSyntax.Expression.ToString()); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerable_04(bool addStructConstraint) + { + var src = @" +using System.Collections; + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IEnumerable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 55 (0x37) + .maxstack 1 + .locals init (System.Collections.IEnumerator V_0, + System.IDisposable V_1) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_001b + IL_0010: ldloc.0 + IL_0011: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_0016: call ""void System.Console.Write(object)"" + IL_001b: ldloc.0 + IL_001c: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0021: brtrue.s IL_0010 + IL_0023: leave.s IL_0036 + } + finally + { + IL_0025: ldloc.0 + IL_0026: isinst ""System.IDisposable"" + IL_002b: stloc.1 + IL_002c: ldloc.1 + IL_002d: brfalse.s IL_0035 + IL_002f: ldloc.1 + IL_0030: callvirt ""void System.IDisposable.Dispose()"" + IL_0035: endfinally + } + IL_0036: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object System.Collections.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + CaptureIds: [1] + Block[B4] - Block + Predecessors (0) + Statements (1) + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IConversionOperation (TryCast: True, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ExplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerable_05(bool addStructConstraint) + { + var src = @" +using System.Collections; + +interface IMyEnumerable +{ + IEnumerator GetEnumerator(); +} + +ref struct S : IMyEnumerable +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IMyEnumerable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 55 (0x37) + .maxstack 1 + .locals init (System.Collections.IEnumerator V_0, + System.IDisposable V_1) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""System.Collections.IEnumerator IMyEnumerable.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_001b + IL_0010: ldloc.0 + IL_0011: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_0016: call ""void System.Console.Write(object)"" + IL_001b: ldloc.0 + IL_001c: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0021: brtrue.s IL_0010 + IL_0023: leave.s IL_0036 + } + finally + { + IL_0025: ldloc.0 + IL_0026: isinst ""System.IDisposable"" + IL_002b: stloc.1 + IL_002c: ldloc.1 + IL_002d: brfalse.s IL_0035 + IL_002f: ldloc.1 + IL_0030: callvirt ""void System.IDisposable.Dispose()"" + IL_0035: endfinally + } + IL_0036: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual System.Collections.IEnumerator IMyEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object System.Collections.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + CaptureIds: [1] + Block[B4] - Block + Predecessors (0) + Statements (1) + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IConversionOperation (TryCast: True, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ExplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator IMyEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator IMyEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerable_06(bool addStructConstraint) + { + var src = @" +using System.Collections; + +interface IMyEnumerable1 +{ + IEnumerator GetEnumerator(); +} + +interface IMyEnumerable2 +{ + IEnumerator GetEnumerator(); +} + +ref struct S : IMyEnumerable1, IMyEnumerable2 +{ + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IMyEnumerable1, IMyEnumerable2, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (36,27): warning CS0278: 'T' does not implement the 'collection' pattern. 'IMyEnumerable1.GetEnumerator()' is ambiguous with 'IMyEnumerable2.GetEnumerator()'. + // foreach (var i in t) + Diagnostic(ErrorCode.WRN_PatternIsAmbiguous, "t").WithArguments("T", "collection", "IMyEnumerable1.GetEnumerator()", "IMyEnumerable2.GetEnumerator()").WithLocation(36, 27), + // (36,27): error CS1579: foreach statement cannot operate on variables of type 'T' because 'T' does not contain a public instance or extension definition for 'GetEnumerator' + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_ForEachMissingMember, "t").WithArguments("T", "GetEnumerator").WithLocation(36, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.GetEnumeratorMethod); + Assert.Null(info.ElementType); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerable_07(bool addStructConstraint) + { + var src = @" +using System.Collections; + +interface IMyEnumerable1 +{ + IEnumerator GetEnumerator(); +} + +interface IMyEnumerable2 +{ + IEnumerator GetEnumerator(); +} + +ref struct S : IMyEnumerable1, IMyEnumerable2, IEnumerable +{ + IEnumerator IMyEnumerable1.GetEnumerator() => throw null; + IEnumerator IMyEnumerable2.GetEnumerator() => throw null; + + public IEnumerator GetEnumerator() + { + return Get123(); + } + + static IEnumerator Get123() + { + yield return 123; + } +} + +class C +{ + static void Main() + { + Test(new S()); + } + + static void Test(T t) where T : " + (addStructConstraint ? "struct, " : "") + @"IMyEnumerable1, IMyEnumerable2, IEnumerable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics( + // (39,27): warning CS0278: 'T' does not implement the 'collection' pattern. 'IMyEnumerable1.GetEnumerator()' is ambiguous with 'IMyEnumerable2.GetEnumerator()'. + // foreach (var i in t) + Diagnostic(ErrorCode.WRN_PatternIsAmbiguous, "t").WithArguments("T", "collection", "IMyEnumerable1.GetEnumerator()", "IMyEnumerable2.GetEnumerator()").WithLocation(39, 27) + ); + + verifier.VerifyIL("C.Test(T)", +@" +{ + // Code size 55 (0x37) + .maxstack 1 + .locals init (System.Collections.IEnumerator V_0, + System.IDisposable V_1) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""T"" + IL_0008: callvirt ""System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_001b + IL_0010: ldloc.0 + IL_0011: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_0016: call ""void System.Console.Write(object)"" + IL_001b: ldloc.0 + IL_001c: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_0021: brtrue.s IL_0010 + IL_0023: leave.s IL_0036 + } + finally + { + IL_0025: ldloc.0 + IL_0026: isinst ""System.IDisposable"" + IL_002b: stloc.1 + IL_002c: ldloc.1 + IL_002d: brfalse.s IL_0035 + IL_002f: ldloc.1 + IL_0030: callvirt ""void System.IDisposable.Dispose()"" + IL_0035: endfinally + } + IL_0036: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IInvocationOperation (virtual System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()) (OperationKind.Invocation, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B2] + Entering: {R2} {R3} + .try {R2, R3} + { + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B7] + IInvocationOperation (virtual System.Boolean System.Collections.IEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Arguments(0) + Finalizing: {R5} + Leaving: {R3} {R2} {R1} + Next (Regular) Block[B3] + Entering: {R4} + .locals {R4} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object System.Collections.IEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R4} + } + } + .finally {R5} + { + CaptureIds: [1] + Block[B4] - Block + Predecessors (0) + Statements (1) + IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 't') + Value: + IConversionOperation (TryCast: True, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ExplicitReference) + Operand: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.IEnumerator, IsImplicit) (Syntax: 't') + Jump if True (Regular) to Block[B6] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 't') + Operand: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Next (Regular) Block[B5] + Block[B5] - Block + Predecessors: [B4] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 't') + Instance Receiver: + IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 't') + Arguments(0) + Next (Regular) Block[B6] + Block[B6] - Block + Predecessors: [B4] [B5] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } +} +Block[B7] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", info.GetEnumeratorMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()", op.Info.GetEnumeratorMethod.ToTestDisplayString()); + Assert.Empty(op.Info.GetEnumeratorArguments); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + } + + [Fact] + public void Foreach_IEnumerable_LanguageVersion_01() + { + var src1 = @" +using System.Collections; + +public ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + foreach (var i in new S()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerable_LanguageVersion_03() + { + var src1 = @" +using System.Collections; + +public ref struct S : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() => throw null; +} + +public struct S1 : IEnumerable +{ + IEnumerator IEnumerable.GetEnumerator() => throw null; +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Main() + { + foreach (var i in new S()) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (6,27): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // foreach (var i in new S()) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "new S()").WithArguments("ref struct interfaces").WithLocation(6, 27) + ); + + comp2 = CreateCompilation(src1 + src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (4,23): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S : IEnumerable + Diagnostic(ErrorCode.ERR_FeatureInPreview, "IEnumerable").WithArguments("ref struct interfaces").WithLocation(4, 23) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var src3 = @" +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + } + } +} +"; + var comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(src3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerable_LanguageVersion_04() + { + var src = @" +using System.Collections; + +class C +{ + static void Test(T t) where T : IEnumerable, allows ref struct + { + foreach (var i in t) + { + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp.VerifyEmitDiagnostics( + // (6,60): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static void Test(T t) where T : IEnumerable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(6, 60) + ); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void Foreach_IEnumerable_LanguageVersion_05() + { + var src1 = @" +using System.Collections; + +public interface IMyEnumerable +{ + IEnumerator GetEnumerator(); +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var src2 = @" +class C +{ + static void Test(T t) where T : IMyEnumerable, allows ref struct + { + foreach (var i in t) + { + } + } +} +"; + var comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (4,62): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static void Test(T t) where T : IMyEnumerable, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(4, 62) + ); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(src2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerator_01(bool s1IsRefStruct) + { + var src = @" +using System.Collections; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public object Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 39 (0x27) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""object S2.Current.get"" + IL_0018: call ""void System.Console.Write(object)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B4] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Leaving: {R1} + Next (Regular) Block[B3] + Entering: {R2} + .locals {R2} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object S2.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R2} + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Object S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerator_02(bool s1IsRefStruct) + { + var src = @" +using System.Collections; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public object Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + + object System.Collections.IEnumerator.Current => throw null; + bool System.Collections.IEnumerator.MoveNext() => throw null; +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 39 (0x27) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""object S2.Current.get"" + IL_0018: call ""void System.Console.Write(object)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B4] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Leaving: {R1} + Next (Regular) Block[B3] + Entering: {R2} + .locals {R2} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object S2.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R2} + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Object S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerator_03(bool s1IsRefStruct, bool currentIsPublic, bool moveNextIsPublic) + { + if (currentIsPublic && moveNextIsPublic) + { + return; + } + + var src = @" +using System.Collections; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + + " + (currentIsPublic ? "public object " : "object IEnumerator.") + @"Current => 123; + + " + (moveNextIsPublic ? "public bool " : "bool System.Collections.IEnumerator.") + @"MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + + public void Reset() { } +} + +class C +{ + static void Main() + { +#line 100 + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + if (!currentIsPublic) + { + comp.VerifyDiagnostics( + // (100,27): error CS0117: 'S2' does not contain a definition for 'Current' + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_NoSuchMember, "new S1()").WithArguments("S2", "Current").WithLocation(100, 27), + // (100,27): error CS0202: foreach requires that the return type 'S2' of 'S1.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "new S1()").WithArguments("S2", "S1.GetEnumerator()").WithLocation(100, 27) + ); + } + else + { + Assert.False(moveNextIsPublic); + + comp.VerifyDiagnostics( + // (100,27): error CS0117: 'S2' does not contain a definition for 'MoveNext' + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_NoSuchMember, "new S1()").WithArguments("S2", "MoveNext").WithLocation(100, 27), + // (100,27): error CS0202: foreach requires that the return type 'S2' of 'S1.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in new S1()) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "new S1()").WithArguments("S2", "S1.GetEnumerator()").WithLocation(100, 27) + ); + } + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] +Block[B1] - Block + Predecessors: [B0] + Statements (1) + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(1): + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1, IsInvalid) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Next (Regular) Block[B2] +Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B4] + IInvalidOperation (OperationKind.Invalid, Type: System.Boolean, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(1): + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(0) + Next (Regular) Block[B3] + Entering: {R1} +.locals {R1} +{ + Locals: [var i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: var, IsImplicit) (Syntax: 'var') + Right: + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(1): + IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'new S1()') + Children(0) + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvalidOperation (OperationKind.Invalid, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Children(2): + IOperation: (OperationKind.None, Type: System.Console) (Syntax: 'System.Console') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: var) (Syntax: 'i') + Next (Regular) Block[B2] + Leaving: {R1} +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.ElementType); + Assert.Null(info.MoveNextMethod); + Assert.Null(info.CurrentProperty); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerator_04(bool s1IsRefStruct, bool addExplicitImplementationOfCurrentAndMoveNext) + { + var src = @" +using System.Collections; + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator +{ + bool stop; + public object Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } +" + +(addExplicitImplementationOfCurrentAndMoveNext ? +@" + object IEnumerator.Current => throw null; + bool System.Collections.IEnumerator.MoveNext() => throw null; +" +: +"") + +@" +} + +class C +{ + static void Main() + { + foreach (var i in new S1()) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.Main", +@" +{ + // Code size 39 (0x27) + .maxstack 2 + .locals init (S2 V_0, + S1 V_1) + IL_0000: ldloca.s V_1 + IL_0002: dup + IL_0003: initobj ""S1"" + IL_0009: call ""S2 S1.GetEnumerator()"" + IL_000e: stloc.0 + IL_000f: br.s IL_001d + IL_0011: ldloca.s V_0 + IL_0013: call ""object S2.Current.get"" + IL_0018: call ""void System.Console.Write(object)"" + IL_001d: ldloca.s V_0 + IL_001f: call ""bool S2.MoveNext()"" + IL_0024: brtrue.s IL_0011 + IL_0026: ret +} +"); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Main").Single(); + + VerifyFlowGraph(comp, node, """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + CaptureIds: [0] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'new S1()') + Value: + IInvocationOperation ( S2 S1.GetEnumerator()) (OperationKind.Invocation, Type: S2, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: S1, IsImplicit) (Syntax: 'new S1()') + Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + (Identity) + Operand: + IObjectCreationOperation (Constructor: S1..ctor()) (OperationKind.ObjectCreation, Type: S1) (Syntax: 'new S1()') + Arguments(0) + Initializer: + null + Arguments(0) + Next (Regular) Block[B2] + Block[B2] - Block + Predecessors: [B1] [B3] + Statements (0) + Jump if False (Regular) to Block[B4] + IInvocationOperation ( System.Boolean S2.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 'new S1()') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + Arguments(0) + Leaving: {R1} + Next (Regular) Block[B3] + Entering: {R2} + .locals {R2} + { + Locals: [System.Object i] + Block[B3] - Block + Predecessors: [B2] + Statements (2) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var') + Left: + ILocalReferenceOperation: i (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Right: + IPropertyReferenceOperation: System.Object S2.Current { get; } (OperationKind.PropertyReference, Type: System.Object, IsImplicit) (Syntax: 'var') + Instance Receiver: + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S2, IsImplicit) (Syntax: 'new S1()') + IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'System.Console.Write(i);') + Expression: + IInvocationOperation (void System.Console.Write(System.Object? value)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'System.Console.Write(i)') + Instance Receiver: + null + Arguments(1): + IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument, Type: null) (Syntax: 'i') + ILocalReferenceOperation: i (OperationKind.LocalReference, Type: System.Object) (Syntax: 'i') + InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) + Next (Regular) Block[B2] + Leaving: {R2} + } +} +Block[B4] - Exit + Predecessors: [B2] + Statements (0) +"""); + + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object S2.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + Assert.Null(info.DisposeMethod); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean S2.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Object S2.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.False(op.Info.NeedsDispose); + Assert.False(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerator_05(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Collections; + +interface IGetEnumerator where TEnumerator : IEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IEnumerator, System.IDisposable +{ + bool stop; + public object Current => 123; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"IEnumerator, System.IDisposable, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"123D" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify with { ILVerifyMessage = "[GetEnumerator]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }" } : + Verification.Skipped).VerifyDiagnostics(); + + if (addStructConstraintToTEnumerator) + { + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 66 (0x42) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(object)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0041 + } + finally + { + IL_0033: ldloca.s V_0 + IL_0035: constrained. ""TEnumerator"" + IL_003b: callvirt ""void System.IDisposable.Dispose()"" + IL_0040: endfinally + } + IL_0041: ret +} +"); + } + else + { + verifier.VerifyIL("C.Test(TEnumerable)", +@" +{ + // Code size 74 (0x4a) + .maxstack 1 + .locals init (TEnumerator V_0) + IL_0000: ldarga.s V_0 + IL_0002: constrained. ""TEnumerable"" + IL_0008: callvirt ""TEnumerator IGetEnumerator.GetEnumerator()"" + IL_000d: stloc.0 + .try + { + IL_000e: br.s IL_0022 + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""TEnumerator"" + IL_0018: callvirt ""object System.Collections.IEnumerator.Current.get"" + IL_001d: call ""void System.Console.Write(object)"" + IL_0022: ldloca.s V_0 + IL_0024: constrained. ""TEnumerator"" + IL_002a: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" + IL_002f: brtrue.s IL_0010 + IL_0031: leave.s IL_0049 + } + finally + { + IL_0033: ldloc.0 + IL_0034: box ""TEnumerator"" + IL_0039: brfalse.s IL_0048 + IL_003b: ldloca.s V_0 + IL_003d: constrained. ""TEnumerator"" + IL_0043: callvirt ""void System.IDisposable.Dispose()"" + IL_0048: endfinally + } + IL_0049: ret +} +"); + } + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + AssertEx.Equal("System.Object", info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", info.MoveNextMethod.ToTestDisplayString()); + AssertEx.Equal("System.Object System.Collections.IEnumerator.Current { get; }", info.CurrentProperty.ToTestDisplayString()); + AssertEx.Equal("void System.IDisposable.Dispose()", info.DisposeMethod.ToTestDisplayString()); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.False(op.Info.IsAsynchronous); + AssertEx.Equal("System.Object", op.Info.ElementType.ToTestDisplayString()); + AssertEx.Equal("System.Boolean System.Collections.IEnumerator.MoveNext()", op.Info.MoveNextMethod.ToTestDisplayString()); + Assert.Empty(op.Info.MoveNextArguments); + AssertEx.Equal("System.Object System.Collections.IEnumerator.Current { get; }", op.Info.CurrentProperty.ToTestDisplayString()); + Assert.True(op.Info.CurrentArguments.IsDefault); + Assert.True(op.Info.NeedsDispose); + Assert.True(op.Info.KnownToImplementIDisposable); + Assert.Null(op.Info.PatternDisposeMethod); + Assert.True(op.Info.DisposeArguments.IsDefault); + } + + [Theory] + [CombinatorialData] + public void Foreach_IEnumerator_09(bool s1IsRefStruct, bool addStructConstraintToTEnumerable, bool addStructConstraintToTEnumerator) + { + var src = @" +using System.Collections; + +interface IMyEnumerator1 +{ + T Current {get;} + bool MoveNext(); +} + +interface IMyEnumerator2 +{ + T Current {get;} + bool MoveNext(); +} + +interface IGetEnumerator where TEnumerator : IMyEnumerator1, IMyEnumerator2, IEnumerator, allows ref struct +{ + TEnumerator GetEnumerator(); +} + +" + (s1IsRefStruct ? "ref " : "") + @"struct S1 : IGetEnumerator +{ + public S2 GetEnumerator() + { + return new S2(); + } +} + +ref struct S2 : IMyEnumerator1, IMyEnumerator2, IEnumerator +{ + bool stop; + public int Current => 123; + object System.Collections.IEnumerator.Current => Current; + public bool MoveNext() + { + if (!stop) + { + stop = true; + return true; + } + + return false; + } + public void Reset() { } + public void Dispose() + { + System.Console.Write('D'); + } +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(TEnumerable t) + where TEnumerable : " + (addStructConstraintToTEnumerable ? "struct, " : "") + @"IGetEnumerator, allows ref struct + where TEnumerator : " + (addStructConstraintToTEnumerator ? "struct, " : "") + @"IMyEnumerator1, IMyEnumerator2, IEnumerator, allows ref struct + { + foreach (var i in t) + { + System.Console.Write(i); + } + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (62,27): error CS0202: foreach requires that the return type 'TEnumerator' of 'IGetEnumerator.GetEnumerator()' must have a suitable public 'MoveNext' method and public 'Current' property + // foreach (var i in t) + Diagnostic(ErrorCode.ERR_BadGetEnumerator, "t").WithArguments("TEnumerator", "IGetEnumerator.GetEnumerator()").WithLocation(62, 27) + ); + + var tree = comp.SyntaxTrees.Single(); + var node = tree.GetRoot().DescendantNodes().OfType().Where(m => m.Identifier.ValueText == "Test").Single(); + var model = comp.GetSemanticModel(tree); + var foreachSyntax = tree.GetRoot().DescendantNodes().OfType().Single(); + var info = model.GetForEachStatementInfo(foreachSyntax); + + Assert.False(info.IsAsynchronous); + Assert.Null(info.ElementType); + Assert.Null(info.MoveNextMethod); + Assert.Null(info.CurrentProperty); + + var op = (Operations.ForEachLoopOperation)model.GetOperation(foreachSyntax); + Assert.Null(op.Info); + } + + [Fact] + public void ConstraintsCheck_01() + { + var src = @" +ref struct S1 +{ +} + +class C +{ + static void Main() + { + Test(new S1()); + } + + static void Test(T x) + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (10,9): error CS9244: The type 'S1' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.Test(T)' + // Test(new S1()); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Test").WithArguments("C.Test(T)", "T", "S1").WithLocation(10, 9) + ); + } + + [Fact] + public void ConstraintsCheck_02() + { + var src1 = @" +public class Helper +{ +#line 100 + public static void Test(T x) where T : allows ref struct + { + System.Console.Write(""Called""); + } +} +"; + var src2 = @" +ref struct S1 +{ +} + +class C +{ + static void Main() + { +#line 200 + Helper.Test(new S1()); + } +} +"; + var comp = CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (100,54): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static void Test(T x) where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(100, 54) + ); + + var comp1Ref = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).ToMetadataReference(); + + comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + CreateCompilation(src2, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(src2, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (200,9): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // Helper.Test(new S1()); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Helper.Test").WithArguments("ref struct interfaces").WithLocation(200, 9) + ); + + CreateCompilation([src1, src2], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyDiagnostics( + // (100,54): error CS9240: Target runtime doesn't support by-ref-like generics. + // public static void Test(T x) where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(100, 54) + ); + + var src3 = @" +struct S1 +{ +} + +class C +{ + static void Main() + { +#line 200 + Helper.Test(new S1()); + } +} +"; + + comp = CreateCompilation([src1, src3], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + CreateCompilation([src1, src3], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation([src1, src3], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (100,54): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static void Test(T x) where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(100, 54) + ); + + comp = CreateCompilation(src3, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + CreateCompilation(src3, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(src3, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + CreateCompilation([src1, src3], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyDiagnostics( + // (100,54): error CS9240: Target runtime doesn't support by-ref-like generics. + // public static void Test(T x) where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(100, 54) + ); + + comp1Ref = CreateCompilation(src1, targetFramework: TargetFramework.DesktopLatestExtended).ToMetadataReference(); + + CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyDiagnostics( + // (200,9): error CS9240: Target runtime doesn't support by-ref-like generics. + // Helper.Test(new S1()); + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "Helper.Test").WithLocation(200, 9) + ); + + CreateCompilation(src3, references: [comp1Ref], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyEmitDiagnostics(); + } + + [Fact] + public void ConstraintsCheck_03() + { + var src = @" +ref struct S1 +{ +} + +class C +{ + static void Test1(T x) where T : allows ref struct + { + Test2(x); + Test2(x); + } + + static void Test2(T x) + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,9): error CS9244: The type 'T' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.Test2(T)' + // Test2(x); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Test2").WithArguments("C.Test2(T)", "T", "T").WithLocation(10, 9), + // (11,9): error CS9244: The type 'T' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.Test2(T)' + // Test2(x); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Test2").WithArguments("C.Test2(T)", "T", "T").WithLocation(11, 9) + ); + } + + [Fact] + public void ConstraintsCheck_04() + { + var src = @" +ref struct S1 +{ +} + +class C +{ + static void Main() + { + Test2((byte)2); + Test3((int)3); + Test3(new S1()); + Test4((long)4); + } + + static void Test1(T x) where T : allows ref struct + { + System.Console.WriteLine(""Called {0}"", typeof(T)); + } + + static void Test2(T x) + { + Test1(x); + Test1(x); + } + + static void Test3(T x) where T : allows ref struct + { + Test1(x); + Test1(x); + } + + static void Test4(T x) + { + Test2(x); + Test2(x); + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" +Called System.Byte +Called System.Byte +Called System.Int32 +Called System.Int32 +Called S1 +Called S1 +Called System.Int64 +Called System.Int64 +Called System.Int64 +Called System.Int64", verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void ConstraintsCheck_05() + { + var src = @" +ref struct S1 +{ +} + +class C + where T : allows ref struct + where S : T +{ + static void Main() + { + _ = typeof(C); + _ = typeof(C); + _ = typeof(C); + _ = typeof(C); + _ = typeof(C); + _ = typeof(C); + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (12,26): error CS9244: The type 'S1' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'S' in the generic type or method 'C' + // _ = typeof(C); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "S1").WithArguments("C", "S", "S1").WithLocation(12, 26), + // (16,25): error CS9244: The type 'T' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'S' in the generic type or method 'C' + // _ = typeof(C); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "T").WithArguments("C", "S", "T").WithLocation(16, 25) + ); + } + + [Fact] + public void ConstraintsCheck_06() + { + var src = @" +#nullable enable + +class C +{ + static void Test1(T? x) where T : allows ref struct + { + } + + static void Test2(T? x) where T : struct, allows ref struct + { + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,29): error CS9244: The type 'T' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' + // static void Test2(T? x) where T : struct, allows ref struct + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "x").WithArguments("System.Nullable", "T", "T").WithLocation(10, 29) + ); + } + + [Fact] + public void ConstraintsCheck_07() + { + var src1 = @" +#line 100 +public class Helper where T : allows ref struct +{ + public static void Test(T x) + { + System.Console.Write(""Called""); + } +} +"; + var src2 = @" +ref struct S1 +{ +} + +class C +{ + static void Main() + { +#line 200 + Helper.Test(new S1()); + } +} +"; + var comp = CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation([src1, src2], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (100,41): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public class Helper where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(100, 41) + ); + + var comp1Ref = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).ToMetadataReference(); + + comp = CreateCompilation(src2, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + CreateCompilation(src2, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(src2, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (200,16): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // Helper.Test(new S1()); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "S1").WithArguments("ref struct interfaces").WithLocation(200, 16) + ); + + CreateCompilation([src1, src2], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyDiagnostics( + // (100,41): error CS9240: Target runtime doesn't support by-ref-like generics. + // public class Helper where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(100, 41) + ); + + var src3 = @" +struct S1 +{ +} + +class C +{ + static void Main() + { +#line 200 + Helper.Test(new S1()); + } +} +"; + + comp = CreateCompilation([src1, src3], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + CreateCompilation([src1, src3], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation([src1, src3], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (100,41): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public class Helper where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(100, 41) + ); + + comp = CreateCompilation(src3, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify(comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"Called" : null, verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + CreateCompilation(src3, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(src3, references: [comp1Ref], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + CreateCompilation([src1, src3], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyDiagnostics( + // (100,41): error CS9240: Target runtime doesn't support by-ref-like generics. + // public class Helper where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(100, 41) + ); + + comp1Ref = CreateCompilation(src1, targetFramework: TargetFramework.DesktopLatestExtended).ToMetadataReference(); + + CreateCompilation(src2, references: [comp1Ref], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyDiagnostics( + // (200,16): error CS9240: Target runtime doesn't support by-ref-like generics. + // Helper.Test(new S1()); + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "S1").WithLocation(200, 16) + ); + + CreateCompilation(src3, references: [comp1Ref], targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.ReleaseExe).VerifyEmitDiagnostics(); + } + + [Fact] + public void IdentityConversion_01() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static T Test1(T h1) + { + return h1; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + Helper1.Test1(new Program()); + Helper1.Test1(null); + System.Console.Write(""Done""); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Done" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +} +"); + } + + [Fact] + public void IdentityConversion_02() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static T Test1(T h1) + { + return (T)h1; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + Helper1.Test1(new Program()); + Helper1.Test1(null); + System.Console.Write(""Done""); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Done" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +} +"); + } + + [Fact] + public void IdentityConversion_03() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + public static T Test1(T h1) + { + return h1; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + System.Console.Write(""Done""); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Done" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +} +"); + } + + [Fact] + public void IdentityConversion_04() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + public static T Test1(T h1) + { + return (T)h1; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + System.Console.Write(""Done""); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Done" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 2 (0x2) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: ret +} +"); + } + + [Fact] + public void IllegalBoxing_01() + { + var src = @" +public class Helper +{ + public static object Test1(T x) where T : allows ref struct + { + return x; + } + + public static object Test2(T x) where T : allows ref struct + { + return (object)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (6,16): error CS0029: Cannot implicitly convert type 'T' to 'object' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "object").WithLocation(6, 16), + // (11,16): error CS0030: Cannot convert type 'T' to 'object' + // return (object)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object)x").WithArguments("T", "object").WithLocation(11, 16) + ); + } + + [Fact] + public void IllegalBoxing_02() + { + var src = @" +public interface I1 +{ +} + +public class Helper +{ + public static I1 Test1(T x) where T : I1, allows ref struct + { + return x; + } + + public static I1 Test2(T x) where T : I1, allows ref struct + { + return (I1)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,16): error CS0029: Cannot implicitly convert type 'T' to 'I1' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "I1").WithLocation(10, 16), + // (15,16): error CS0030: Cannot convert type 'T' to 'I1' + // return (I1)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(I1)x").WithArguments("T", "I1").WithLocation(15, 16) + ); + } + + [Fact] + public void IllegalBoxing_03() + { + var src = @" +public interface I1 +{ +} + +public class Helper +{ + static U Test1(T x) + where T : U, allows ref struct + { + return x; + } + static U Test2(T x) + where T : U, allows ref struct + { + return (U)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (11,16): error CS0029: Cannot implicitly convert type 'T' to 'U' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "U").WithLocation(11, 16), + // (16,16): error CS0030: Cannot convert type 'T' to 'U' + // return (U)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(U)x").WithArguments("T", "U").WithLocation(16, 16) + ); + } + + [Fact] + public void IllegalBoxing_04() + { + var src = @" +ref struct S +{ +} + +public class Helper +{ + static object Test1(T x) + where T : struct, allows ref struct + { + return x; + } + + static object Test2(S x) + { + return x; + } + + static object Test3(T x) + where T : struct, allows ref struct + { + return (object)x; + } + + static object Test4(S x) + { + return (object)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (11,16): error CS0029: Cannot implicitly convert type 'T' to 'object' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "object").WithLocation(11, 16), + // (16,16): error CS0029: Cannot implicitly convert type 'S' to 'object' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("S", "object").WithLocation(16, 16), + // (22,16): error CS0030: Cannot convert type 'T' to 'object' + // return (object)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object)x").WithArguments("T", "object").WithLocation(22, 16), + // (27,16): error CS0030: Cannot convert type 'S' to 'object' + // return (object)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object)x").WithArguments("S", "object").WithLocation(27, 16) + ); + } + + [Fact] + public void IllegalBoxing_05() + { + var src = @" +interface I1 {} + +ref struct S : I1 +{ +} + +public class Helper +{ + static I1 Test1(T x) + where T : I1, allows ref struct + { + return x; + } + + static I1 Test2(S x) + { + return x; + } + + static I1 Test3(T x) + where T : I1, allows ref struct + { + return (I1)x; + } + + static I1 Test4(S x) + { + return (I1)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (13,16): error CS0029: Cannot implicitly convert type 'T' to 'I1' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "I1").WithLocation(13, 16), + // (18,16): error CS0029: Cannot implicitly convert type 'S' to 'I1' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("S", "I1").WithLocation(18, 16), + // (24,16): error CS0030: Cannot convert type 'T' to 'I1' + // return (I1)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(I1)x").WithArguments("T", "I1").WithLocation(24, 16), + // (29,16): error CS0030: Cannot convert type 'S' to 'I1' + // return (I1)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(I1)x").WithArguments("S", "I1").WithLocation(29, 16) + ); + } + + [Fact] + public void Unboxing_01() + { + var src = @" +public interface I1 +{ +} + +ref struct S : I1 +{ +} + +public class Helper +{ + static S Test1(I1 x) + { + return x; + } + + static S Test2(I1 x) + { + return (S)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (14,16): error CS0029: Cannot implicitly convert type 'I1' to 'S' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("I1", "S").WithLocation(14, 16), + // (19,16): error CS0030: Cannot convert type 'I1' to 'S' + // return (S)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(S)x").WithArguments("I1", "S").WithLocation(19, 16) + ); + } + + [Fact] + public void Unboxing_02() + { + var src = @" +public interface I1 +{ +} + +ref struct S : I1 +{ +} + +public class Helper +{ + static S Test1(T x) + where T : I1, allows ref struct + { + return x; + } + static S Test2(T x) + where T : I1, allows ref struct + { + return (S)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (15,16): error CS0029: Cannot implicitly convert type 'T' to 'S' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "S").WithLocation(15, 16), + // (20,16): error CS0030: Cannot convert type 'T' to 'S' + // return (S)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(S)x").WithArguments("T", "S").WithLocation(20, 16) + ); + } + + [Fact] + public void Unboxing_03() + { + var src = @" +public interface I1 +{ +} + +public class Helper +{ + static U Test1(T x) + where T : allows ref struct + where U : T + { +#line 100 + return x; + } + static U Test2(T x) + where T : allows ref struct + where U : T + { +#line 200 + return (U)x; + // Not a legal IL according to https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md + // IL_0000: ldarg.0 + // IL_0001: box ""T"" + // IL_0006: unbox.any ""U"" + // IL_000b: ret + } + + static U Test3(T x) + where T : allows ref struct + where U : class, T + { +#line 300 + return x; + } + static U Test4(T x) + where T : allows ref struct + where U : class, T + { +#line 400 + return (U)x; + // Not a legal IL according to https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md + // IL_0000: ldarg.0 + // IL_0001: box ""T"" + // IL_0006: unbox.any ""U"" + // IL_000b: ret + } + + static T Test5(U y) + where T : allows ref struct + where U : T + { +#line 500 + return y; + } + static T Test6(U y) + where T : allows ref struct + where U : T + { +#line 600 + return (T)y; + // Not a legal IL according to https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md + // IL_0000: ldarg.0 + // IL_0001: box ""U"" + // IL_0006: unbox.any ""T"" + // IL_000b: ret + } + + static T Test7(U y) + where T : allows ref struct + where U : class, T + { +#line 700 + return y; + } + static T Test8(U y) + where T : allows ref struct + where U : class, T + { +#line 800 + return (T)y; + // Not a legal IL according to https://github.com/dotnet/runtime/blob/main/docs/design/features/byreflike-generics.md + // IL_0000: ldarg.0 + // IL_0001: box ""U"" + // IL_0006: unbox.any ""T"" + // IL_000b: ret + } + static U Test9(T x) + where T : class + where U : T, allows ref struct + { +#line 900 + return x; + } + static U Test10(T x) + where T : class + where U : T, allows ref struct + { +#line 1000 + return (U)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (100,16): error CS0029: Cannot implicitly convert type 'T' to 'U' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "U").WithLocation(100, 16), + // (200,16): error CS0030: Cannot convert type 'T' to 'U' + // return (U)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(U)x").WithArguments("T", "U").WithLocation(200, 16), + // (300,16): error CS0029: Cannot implicitly convert type 'T' to 'U' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "U").WithLocation(300, 16), + // (400,16): error CS0030: Cannot convert type 'T' to 'U' + // return (U)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(U)x").WithArguments("T", "U").WithLocation(400, 16), + // (500,16): error CS0029: Cannot implicitly convert type 'U' to 'T' + // return y; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "y").WithArguments("U", "T").WithLocation(500, 16), + // (600,16): error CS0030: Cannot convert type 'U' to 'T' + // return (T)y; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(T)y").WithArguments("U", "T").WithLocation(600, 16), + // (700,16): error CS0029: Cannot implicitly convert type 'U' to 'T' + // return y; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "y").WithArguments("U", "T").WithLocation(700, 16), + // (800,16): error CS0030: Cannot convert type 'U' to 'T' + // return (T)y; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(T)y").WithArguments("U", "T").WithLocation(800, 16), + // (900,16): error CS0029: Cannot implicitly convert type 'T' to 'U' + // return x; + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "U").WithLocation(900, 16), + // (1000,16): error CS0030: Cannot convert type 'T' to 'U' + // return (U)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(U)x").WithArguments("T", "U").WithLocation(1000, 16) + ); + } + + [Fact] + public void Unboxing_04() + { + var src = @" +ref struct S +{ +} + +public class Helper +{ + static T Test1(object x) + where T : allows ref struct + { + return (T)x; + } + + static S Test2(object x) + { + return (S)x; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (11,16): error CS0030: Cannot convert type 'object' to 'T' + // return (T)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(T)x").WithArguments("object", "T").WithLocation(11, 16), + // (16,16): error CS0030: Cannot convert type 'object' to 'S' + // return (S)x; + Diagnostic(ErrorCode.ERR_NoExplicitConv, "(S)x").WithArguments("object", "S").WithLocation(16, 16) + ); + } + + [Fact] + public void CallObjectMember() + { + var src = @" +public class Helper +{ + static string Test1(T x) + where T : allows ref struct + { + return x.ToString(); + } + + static string Test2(S y) + { + return y.ToString(); + } +} + +ref struct S +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,16): error CS0029: Cannot implicitly convert type 'T' to 'object' + // return x.ToString(); + Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("T", "object").WithLocation(7, 16), + // (12,16): error CS0029: Cannot implicitly convert type 'S' to 'System.ValueType' + // return y.ToString(); + Diagnostic(ErrorCode.ERR_NoImplicitConv, "y").WithArguments("S", "System.ValueType").WithLocation(12, 16) + ); + } + + [Fact] + public void AnonymousTypeMember_01() + { + var src = @" +public class Helper +{ + static void Test(T x) + where T : allows ref struct + { + var y = new { x }; + } +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,23): error CS0828: Cannot assign 'T' to anonymous type property + // var y = new { x }; + Diagnostic(ErrorCode.ERR_AnonymousTypePropertyAssignedBadValue, "x").WithArguments("T").WithLocation(7, 23) + ); + } + + [ConditionalFact(typeof(NoUsedAssembliesValidation))] // https://github.com/dotnet/roslyn/issues/73558: Follow up on used assemblies validation failure. Could be an artifact of https://github.com/dotnet/roslyn/issues/72945. + [WorkItem("https://github.com/dotnet/roslyn/issues/72945")] + [WorkItem("https://github.com/dotnet/roslyn/issues/73558")] + public void AnonymousTypeMember_02() + { + var src = @" +public class Helper +{ + static void Test1(MyEnumerable outer, MyEnumerable inner1, MyEnumerable inner2) + where T : I1, allows ref struct + { +#line 100 + var q = from x in outer join y in inner1 on x.P equals y.P + join z in inner2 on y.P equals z.P + select 1; + } + + static void Test2(MyEnumerable outer, MyEnumerable inner1, MyEnumerable inner2) + { +#line 200 + var q = from x in outer join y in inner1 on x.P equals y.P + join z in inner2 on y.P equals z.P + select 1; + } +} + +class MyEnumerable + where T : allows ref struct +{ + public MyEnumerable Join (MyEnumerable inner, MyFunc outerKeySelector, MyFunc innerKeySelector, MyFunc resultSelector) + where TInner : allows ref struct + where TKey : allows ref struct + where TResult : allows ref struct + => throw null; + + public MyEnumerable Select (MyFunc selector) + where TResult : allows ref struct + => throw null; +} + +delegate TResult MyFunc(T arg) + where T : allows ref struct + where TResult : allows ref struct; +delegate TResult MyFunc(T1 arg1, T2 arg2) + where T1 : allows ref struct + where T2 : allows ref struct + where TResult : allows ref struct; + +interface I1 +{ + int P {get;} +} + +ref struct S1 +{ + public int P {get;set;} +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // Errors are expected for both queries, but it is a pre-existing condition - https://github.com/dotnet/roslyn/issues/72945 + ); + } + + [Fact] + public void Makeref() + { + var src = @" +public class Helper +{ + static void Test1(T x) + where T : allows ref struct + { + System.TypedReference tr = __makeref(x); + } + + static void Test2(S y) + { + System.TypedReference tr = __makeref(y); + } +} + +ref struct S +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,36): error CS1601: Cannot make reference to variable of type 'T' + // System.TypedReference tr = __makeref(x); + Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "__makeref(x)").WithArguments("T").WithLocation(7, 36), + // (12,36): error CS1601: Cannot make reference to variable of type 'S' + // System.TypedReference tr = __makeref(y); + Diagnostic(ErrorCode.ERR_MethodArgCantBeRefAny, "__makeref(y)").WithArguments("S").WithLocation(12, 36) + ); + } + + [Fact] + public void ScopedTypeParameter_01() + { + var src = @" +public class Helper +{ + static void Test1(scoped T x) + where T : allows ref struct + { + } + + static void Test2(scoped S y) + { + } + + static void Test3(scoped T z) + { + } + + static void Test4() + { + var d = void (scoped T u) => {}; + d(default); + } +} + +ref struct S +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (13,26): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only. + // static void Test3(scoped T z) + Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T z").WithLocation(13, 26), + // (19,23): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only. + // var d = void (scoped T u) => {}; + Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped T u").WithLocation(19, 23) + ); + + var src2 = @" +public class Helper +{ + public static void Test1(scoped T x) + where T : allows ref struct + { + } +} +"; + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify( + comp2, symbolValidator: validate, sourceSymbolValidator: validate, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void validate(ModuleSymbol m) + { + var p = m.GlobalNamespace.GetMember("Helper.Test1").Parameters[0]; + AssertEx.Equal("scoped T x", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.ScopedValue, p.EffectiveScope); + } + } + + [Fact] + public void ScopedTypeParameter_02() + { + var src = @" +#pragma warning disable CS0219 // The variable 'x' is assigned but its value is never used + +public class Helper +{ + static void Test1() + where T : allows ref struct + { + scoped T x = default; + } + + static void Test2() + { + scoped S y = default; + } + + static void Test3() + { + scoped T z = default; + } +} + +ref struct S +{ +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (19,16): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only. + // scoped T z = default; + Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "T").WithLocation(19, 16) + ); + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + var declarator = tree.GetRoot().DescendantNodes().OfType().First(); + AssertEx.Equal("x = default", declarator.ToString()); + var local = model.GetDeclaredSymbol(declarator).GetSymbol(); + AssertEx.Equal("T x", local.ToTestDisplayString()); + Assert.Equal(ScopedKind.ScopedValue, local.Scope); + } + + [Fact] + public void LiftedUnaryOperator_InvalidTypeArgument01() + { + var code = @" +struct S1 + where T : struct, allows ref struct +{ + public static T operator+(S1 s1) => throw null; + + static void Test() + { + S1? s1 = default; + var s2 = +s1; + } +} +"; + + var comp = CreateCompilation(code, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (10,18): error CS0023: Operator '+' cannot be applied to operand of type 'S1?' + // var s2 = +s1; + Diagnostic(ErrorCode.ERR_BadUnaryOp, "+s1").WithArguments("+", "S1?").WithLocation(10, 18) + ); + } + + [Fact] + public void RefField() + { + var src = @" +#pragma warning disable CS0169 // The field is never used + +ref struct S1 +{ +} + +ref struct S2 + where T : allows ref struct +{ + ref S1 a; + ref T b; +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (11,5): error CS9050: A ref field cannot refer to a ref struct. + // ref S1 a; + Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref S1").WithLocation(11, 5), + // (12,5): error CS9050: A ref field cannot refer to a ref struct. + // ref T b; + Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref T").WithLocation(12, 5) + ); + } + + [Fact] + public void UnscopedRef_01() + { + var sourceA = +@" +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; + +public class Helper +{ + static void Test1([UnscopedRef] params T x) + where T : IEnumerable, IAdd, new(), allows ref struct + { + } + + static void Test2([UnscopedRef] params S y) + { + } + + static void Test3([UnscopedRef] params T z) + where T : IEnumerable, IAdd, new() + { + } +} + +interface IAdd +{ + void Add(int x); +} + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + public void Add(int x){} +} +"; + var comp = CreateCompilation(sourceA, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (16,27): error CS9063: UnscopedRefAttribute cannot be applied to this parameter because it is unscoped by default. + // static void Test3([UnscopedRef] params T z) + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedTarget, "UnscopedRef").WithLocation(16, 27) + ); + + var src2 = @" +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; + +public class Helper +{ + public static void Test1([UnscopedRef] params T x) + where T : IEnumerable, IAdd, new(), allows ref struct + { + } +} + +public interface IAdd +{ + void Add(int x); +} +"; + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify( + comp2, symbolValidator: validate, sourceSymbolValidator: validate, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void validate(ModuleSymbol m) + { + var p = m.GlobalNamespace.GetMember("Helper.Test1").Parameters[0]; + AssertEx.Equal("params T x", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.None, p.EffectiveScope); + } + } + + [Fact] + public void UnscopedRef_02() + { + var sourceA = +@" +using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; + +public class Helper +{ + static void Test1([UnscopedRef] params scoped T x) + where T : IEnumerable, IAdd, new(), allows ref struct + { + } + + static void Test2([UnscopedRef] params scoped S y) + { + } +} + +interface IAdd +{ + void Add(int x); +} + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + public void Add(int x){} +} +"; + var comp = CreateCompilation(sourceA, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,27): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier. + // static void Test1([UnscopedRef] params scoped T x) + Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(7, 27), + // (12,24): error CS9066: UnscopedRefAttribute cannot be applied to parameters that have a 'scoped' modifier. + // static void Test2([UnscopedRef] params scoped S y) + Diagnostic(ErrorCode.ERR_UnscopedScoped, "UnscopedRef").WithLocation(12, 24) + ); + + // https://github.com/dotnet/roslyn/issues/73557: Consider testing similar scenario without params + } + + [Fact] + public void ScopedByDefault_01() + { + var src = +@" +using System.Collections.Generic; + +class Helper +{ + public static void Test1(params T x) + where T : IEnumerable, IAdd, new(), allows ref struct + { + } + + public static void Test2(params S y) + { + } + + public static void Test3(params T z) + where T : IEnumerable, IAdd, new() + { + } +} + +interface IAdd +{ + void Add(int x); +} + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + public void Add(int x){} +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify( + comp, symbolValidator: validate, sourceSymbolValidator: validate, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + void validate(ModuleSymbol m) + { + var p = m.GlobalNamespace.GetMember("Helper.Test1").Parameters[0]; + AssertEx.Equal("params T x", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.ScopedValue, p.EffectiveScope); + + p = m.GlobalNamespace.GetMember("Helper.Test2").Parameters[0]; + AssertEx.Equal("params S y", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.ScopedValue, p.EffectiveScope); + + p = m.GlobalNamespace.GetMember("Helper.Test3").Parameters[0]; + AssertEx.Equal("params T z", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.None, p.EffectiveScope); + } + } + + [Fact] + public void ScopedByDefault_02() + { + var src = +@" +using System.Collections.Generic; + +class Helper +{ + public static void Test1() + where T : IEnumerable, IAdd, new(), allows ref struct + { + var l1 = (params T x) => {}; + } + + public static void Test2() + { + var l2 = (params S y) => {}; + } + + public static void Test3() + where T : IEnumerable, IAdd, new() + { + var l3 = (params T z) => {}; + } +} + +interface IAdd +{ + void Add(int x); +} + +ref struct S : IEnumerable +{ + public IEnumerator GetEnumerator() => throw null; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + public void Add(int x){} +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + CompileAndVerify( + comp, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + var lambdas = tree.GetRoot().DescendantNodes().OfType().ToArray(); + + var p = model.GetDeclaredSymbol(lambdas[0].ParameterList.Parameters[0]).GetSymbol(); + AssertEx.Equal("params T x", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.ScopedValue, p.EffectiveScope); + + p = model.GetDeclaredSymbol(lambdas[1].ParameterList.Parameters[0]).GetSymbol(); + AssertEx.Equal("params S y", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.ScopedValue, p.EffectiveScope); + + p = model.GetDeclaredSymbol(lambdas[2].ParameterList.Parameters[0]).GetSymbol(); + AssertEx.Equal("params T z", p.ToTestDisplayString()); + Assert.Equal(ScopedKind.None, p.EffectiveScope); + } + + [Fact] + public void SystemActivatorCreateInstance_01() + { + var sourceA = +@" +public class Helper +{ + static void Test1() + where T : new(), allows ref struct + { + _ = System.Activator.CreateInstance(); + } + + static void Test2() + { + _ = System.Activator.CreateInstance(); + } +} + +ref struct S +{ +} +"; + var comp = CreateCompilation(sourceA, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (7,30): error CS9244: The type 'T' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Activator.CreateInstance()' + // _ = System.Activator.CreateInstance(); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "CreateInstance").WithArguments("System.Activator.CreateInstance()", "T", "T").WithLocation(7, 30), + // (12,30): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Activator.CreateInstance()' + // _ = System.Activator.CreateInstance(); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "CreateInstance").WithArguments("System.Activator.CreateInstance()", "T", "S").WithLocation(12, 30) + ); + } + + [Fact] + public void SystemActivatorCreateInstance_02() + { + var sourceA = +@" +public class Helper +{ + static void Test1() + where T : new(), allows ref struct + { + _ = new T(); + } +} + +ref struct S +{ +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() => default; + } +} +"; + var comp = CreateCompilation(sourceA, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyEmitDiagnostics( + // (7,13): error CS9244: The type 'T' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Activator.CreateInstance()' + // _ = new T(); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "new T()").WithArguments("System.Activator.CreateInstance()", "T", "T").WithLocation(7, 13) + ); + } + + [Fact] + public void SystemActivatorCreateInstance_03() + { + // 'System.Activator.CreateInstance' will be changed to include 'allows ref struct' constraint, + // see https://github.com/dotnet/runtime/issues/65112. + + var src = @" +public class Helper +{ + public static T Test1() + where T : new(), allows ref struct + { + return new T(); + } +} + +ref struct S +{ +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} + +class Program +{ + static void Main() + { + Print(Helper.Test1()); + System.Console.Write(' '); + Print(Helper.Test1()); + } + + static void Print(T value) where T : allows ref struct + { + System.Console.Write(typeof(T)); + System.Console.Write(' '); + System.Console.Write(value == null); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "S False Program True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1()", +@" +{ + // Code size 6 (0x6) + .maxstack 1 + IL_0000: call ""T System.Activator.CreateInstance()"" + IL_0005: ret +} +"); + } + + [Fact] + public void Field() + { + var src = @" +#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value + +class C + where T : allows ref struct +{ + public T P1; + public S P2; +} + +ref struct S1 + where T : allows ref struct +{ + public static T P3; + public static S P4; +} + +ref struct S2 + where T : allows ref struct +{ + public T P5; + public S P6; +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,12): error CS8345: Field or auto-implemented property cannot be of type 'T' unless it is an instance member of a ref struct. + // public T P1; + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "T").WithArguments("T").WithLocation(7, 12), + // (8,12): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct. + // public S P2; + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(8, 12), + // (14,19): error CS8345: Field or auto-implemented property cannot be of type 'T' unless it is an instance member of a ref struct. + // public static T P3; + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "T").WithArguments("T").WithLocation(14, 19), + // (15,19): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct. + // public static S P4; + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(15, 19) + ); + } + + [Fact] + public void AutoProperty() + { + var src = @" +class C + where T : allows ref struct +{ + public T P1 {get; set;} + public S P2 {get; set;} +} + +ref struct S1 + where T : allows ref struct +{ + public static T P3 {get; set;} + public static S P4 {get; set;} +} + +ref struct S2 + where T : allows ref struct +{ + public T P5 {get; set;} + public S P6 {get; set;} +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (5,12): error CS8345: Field or auto-implemented property cannot be of type 'T' unless it is an instance member of a ref struct. + // public T P1 {get; set;} + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "T").WithArguments("T").WithLocation(5, 12), + // (6,12): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct. + // public S P2 {get; set;} + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(6, 12), + // (12,19): error CS8345: Field or auto-implemented property cannot be of type 'T' unless it is an instance member of a ref struct. + // public static T P3 {get; set;} + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "T").WithArguments("T").WithLocation(12, 19), + // (13,19): error CS8345: Field or auto-implemented property cannot be of type 'S' unless it is an instance member of a ref struct. + // public static S P4 {get; set;} + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "S").WithArguments("S").WithLocation(13, 19) + ); + } + + [Fact] + [WorkItem("https://github.com/dotnet/roslyn/issues/73556")] + public void InlineArrayElement_01() + { + var src1 = @" +[System.Runtime.CompilerServices.InlineArray(10)] +ref struct S1 + where T : allows ref struct +{ + T _f; +} + +[System.Runtime.CompilerServices.InlineArray(10)] +ref struct S2 +{ + S _f; +} + +ref struct S +{ +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + CompileAndVerify( + comp1, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (6,7): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // T _f; + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "_f").WithLocation(6, 7), + // (12,7): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // S _f; + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "_f").WithLocation(12, 7) + ); + + var src2 = @" +[System.Runtime.CompilerServices.InlineArray(10)] +struct S2 + where T2 : allows ref struct +{ + T2 _f; +} +"; + + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyDiagnostics( + // (6,5): error CS8345: Field or auto-implemented property cannot be of type 'T2' unless it is an instance member of a ref struct. + // T2 _f; + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "T2").WithArguments("T2").WithLocation(6, 5), + + // https://github.com/dotnet/roslyn/issues/73556: + // The warning below is somewhat misleading. 'S2' can be used as a type argument (it is not a ref struct) and 'T2' is a type argument. + // However, given the error above, this is probably not worth fixing. There is no way to declare a legal non-ref struct with a field + // of type 'T2'. + + // (6,8): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // T2 _f; + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "_f").WithLocation(6, 8) + ); + } + + [Fact] + public void InlineArrayElement_02() + { + var src = @" +[System.Runtime.CompilerServices.InlineArray(2)] +ref struct S1 + where T : allows ref struct +{ + T _f; +} + +class C +{ + static void Main() + { + var x = new S1(); + x[0] = 123; + } +} + +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (6,7): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // T _f; + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "_f").WithLocation(6, 7), + // (14,9): error CS0306: The type 'S1' may not be used as a type argument + // x[0] = 123; + Diagnostic(ErrorCode.ERR_BadTypeArgument, "x[0]").WithArguments("S1").WithLocation(14, 9) + ); + } + + [Fact] + public void InlineArrayElement_03() + { + var src = @" +[System.Runtime.CompilerServices.InlineArray(2)] +ref struct S1 + where T : allows ref struct +{ + T _f; +} + +class C +{ + static void Main() + { + var x = new S1(); + x[0] = 123; + } +} + +namespace System.Runtime.CompilerServices +{ + public class Unsafe + { + public static ref TTo As(ref TFrom input) where TFrom : allows ref struct => throw null; + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.DebugExe); + comp.VerifyEmitDiagnostics( + // (6,7): warning CS9184: 'Inline arrays' language feature is not supported for an inline array type that is not valid as a type argument, or has element type that is not valid as a type argument. + // T _f; + Diagnostic(ErrorCode.WRN_InlineArrayNotSupportedByLanguage, "_f").WithLocation(6, 7), + // (14,9): error CS0306: The type 'S1' may not be used as a type argument + // x[0] = 123; + Diagnostic(ErrorCode.ERR_BadTypeArgument, "x[0]").WithArguments("S1").WithLocation(14, 9) + ); + } + + [Fact] + public void AsyncParameter() + { + var src = @" +#pragma warning disable CS1998 // This async method lacks 'await' operators and will run synchronously. + +public class Helper +{ + static async void Test1(T x) + where T : allows ref struct + { + } + + static async void Test2(S y) + { + } +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (6,34): error CS4012: Parameters of type 'T' cannot be declared in async methods or async lambda expressions. + // static async void Test1(T x) + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "x").WithArguments("T").WithLocation(6, 34), + // (11,31): error CS4012: Parameters of type 'S' cannot be declared in async methods or async lambda expressions. + // static async void Test2(S y) + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "y").WithArguments("S").WithLocation(11, 31) + ); + } + + [Fact] + public void MissingScopedInOverride_01() + { + var src = @" +abstract class Base +{ + protected abstract T Test1(scoped T x) + where T : allows ref struct; + + protected abstract S Test2(scoped S y); +} + +abstract class Derived1 : Base +{ + protected abstract override T Test1(T x); + + protected abstract override S Test2(S y); +} + +abstract class Derived2 : Base +{ + protected abstract override T Test1(scoped T x); + + protected abstract override S Test2(scoped S y); +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (12,35): error CS8987: The 'scoped' modifier of parameter 'x' doesn't match overridden or implemented member. + // protected abstract override T Test1(T x); + Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "Test1").WithArguments("x").WithLocation(12, 35), + // (14,35): error CS8987: The 'scoped' modifier of parameter 'y' doesn't match overridden or implemented member. + // protected abstract override S Test2(S y); + Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "Test2").WithArguments("y").WithLocation(14, 35) + ); + + // https://github.com/dotnet/roslyn/issues/73555: Consider testing similar scenario with implicitly scoped parameter + } + + [Fact] + public void MissingScopedInOverride_02() + { + var src = @" +abstract class Base +{ + protected abstract void Test1(scoped T x, out T z) + where T : allows ref struct; + + protected abstract void Test2(scoped S y, out S z); +} + +abstract class Derived1 : Base +{ + protected abstract override void Test1(T x, out T z); + + protected abstract override void Test2(S y, out S z); +} + +abstract class Derived2 : Base +{ + protected abstract override void Test1(scoped T x, out T z); + + protected abstract override void Test2(scoped S y, out S z); +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (12,38): error CS8987: The 'scoped' modifier of parameter 'x' doesn't match overridden or implemented member. + // protected abstract override void Test1(T x, out T z); + Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "Test1").WithArguments("x").WithLocation(12, 38), + // (14,38): error CS8987: The 'scoped' modifier of parameter 'y' doesn't match overridden or implemented member. + // protected abstract override void Test2(S y, out S z); + Diagnostic(ErrorCode.ERR_ScopedMismatchInParameterOfOverrideOrImplementation, "Test2").WithArguments("y").WithLocation(14, 38) + ); + + // https://github.com/dotnet/roslyn/issues/73554: Consider testing ERR_ScopedMismatchInParameterOfPartial and ERR_ScopedMismatchInParameterOfTarget. + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/73553")] // Enable once we get support for 'byreflike' in IL. + [WorkItem("https://github.com/dotnet/roslyn/issues/73553")] + public void RefFieldTypeAllowsRefLike() + { + // ref struct R2 where T : allows ref struct + // { + // public ref T F; + // } + var sourceA = +@" +.class public sealed R2`1 extends [mscorlib]System.ValueType +{ + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = (01 00 00 00) + .field public !T& F +} +"; + var refA = CompileIL(sourceA); + + var sourceB = +@"class Program +{ + static void F(ref T r1) where T : allows ref struct + { + var r2 = new R2(); + r2.F = ref r1; + } +}"; + var comp = CreateCompilation(sourceB, references: new[] { refA }, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics( + // (6,12): error CS0570: 'R2.F' is not supported by the language + // r2.F = ref r1; + Diagnostic(ErrorCode.ERR_BindToBogus, "F").WithArguments("R2.F").WithLocation(6, 12) + ); + } + + [Fact] + public void RestrictedTypesInRecords() + { + var src = @" +record C( + T P1 + ) where T : allows ref struct; +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics( + // (3,5): error CS8345: Field or auto-implemented property cannot be of type 'T' unless it is an instance member of a ref struct. + // T P1 + Diagnostic(ErrorCode.ERR_FieldAutoPropCantBeByRefLike, "T").WithArguments("T").WithLocation(3, 5) + ); + } + + [Theory] + [CombinatorialData] + public void AnonymousDelegateType_01_ActionDisallowsRefStruct(bool s2IsRefStruct) + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(T x) where T : allows ref struct + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x, new S2()); + } +} + +class Helper where T : allows ref struct +{ + public static void Test1(T x, S2 y) + { + System.Console.Write(""Test1""); + System.Console.Write("" ""); + System.Console.Write(typeof(T)); + } +} + +ref struct S1 {} + +" + (s2IsRefStruct ? "ref " : "") + @"struct S2 {} + +namespace System +{ + public delegate void Action(T1 x, T2 y); +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"<>A`2[S1,S2] Test1 S1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped, + symbolValidator: (m) => + { + foreach (var tp in m.ContainingAssembly.GetTypeByMetadataName("<>A`2").TypeParameters) + { + Assert.True(tp.AllowsRefLikeType); + } + } + ).VerifyDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void AnonymousDelegateType_02_FuncDisallowsRefStruct(bool s2IsRefStruct) + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(T x) where T : allows ref struct + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x); + } +} + +class Helper where T : allows ref struct +{ + public static S2 Test1(T x) + { + System.Console.Write(""Test1""); + System.Console.Write("" ""); + System.Console.Write(typeof(T)); + return default; + } +} + +ref struct S1 {} + +" + (s2IsRefStruct ? "ref " : "") + @"struct S2 {} + +namespace System +{ + public delegate T2 Func(T1 x); +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"<>F`2[S1,S2] Test1 S1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr && !s2IsRefStruct ? Verification.Passes : Verification.Skipped, + symbolValidator: (m) => + { + foreach (var tp in m.ContainingAssembly.GetTypeByMetadataName("<>F`2").TypeParameters) + { + Assert.True(tp.AllowsRefLikeType); + } + } + ).VerifyDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void AnonymousDelegateType_03_ActionAllowsRefStruct(bool s2IsRefStruct) + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(T x) where T : allows ref struct + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x, new S2()); + } +} + +class Helper where T : allows ref struct +{ + public static void Test1(T x, S2 y) + { + System.Console.Write(""Test1""); + System.Console.Write("" ""); + System.Console.Write(typeof(T)); + } +} + +ref struct S1 {} + +" + (s2IsRefStruct ? "ref " : "") + @"struct S2 {} + +namespace System +{ + public delegate void Action(T1 x, T2 y) where T1 : allows ref struct where T2 : allows ref struct; +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"System.Action`2[S1,S2] Test1 S1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void AnonymousDelegateType_04_FuncAllowsRefStruct(bool s2IsRefStruct) + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(T x) where T : allows ref struct + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x); + } +} + +class Helper where T : allows ref struct +{ + public static S2 Test1(T x) + { + System.Console.Write(""Test1""); + System.Console.Write("" ""); + System.Console.Write(typeof(T)); + return default; + } +} + +ref struct S1 {} + +" + (s2IsRefStruct ? "ref " : "") + @"struct S2 {} + +namespace System +{ + public delegate T2 Func(T1 x) where T1 : allows ref struct where T2 : allows ref struct; +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"System.Func`2[S1,S2] Test1 S1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr && !s2IsRefStruct ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void AnonymousDelegateType_05_PartiallyGenericAnonymousDelegate() + { + var src = @" +unsafe class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(T x) where T : allows ref struct + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x, null); + } +} + +unsafe class Helper where T : allows ref struct +{ + public static void Test1(T x, void* y) + { + System.Console.Write(""Test1""); + System.Console.Write("" ""); + System.Console.Write(typeof(T)); + } +} + +ref struct S1 {} + +namespace System +{ + public delegate void Action(T1 x, T2 y) where T1 : allows ref struct where T2 : allows ref struct; +} +"; + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.UnsafeReleaseExe); + + CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"<>f__AnonymousDelegate0`1[S1] Test1 S1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped, + symbolValidator: (m) => + { + foreach (var tp in m.ContainingAssembly.GetTypeByMetadataName("<>f__AnonymousDelegate0`1").TypeParameters) + { + Assert.True(tp.AllowsRefLikeType); + } + } + ).VerifyDiagnostics(); + } + + [Fact] + public void AnonymousDelegateType_06_PartiallyGenericAnonymousDelegate_CannotAllowRefStruct() + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(T x) + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x, new S2()); + } +} + +class Helper +{ + public static void Test1(T x, S2 y) + { + System.Console.Write(""Test1""); + System.Console.Write("" ""); + System.Console.Write(typeof(T)); + } +} + +struct S1 {} + +ref struct S2 {} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe); + + CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"<>f__AnonymousDelegate0`1[S1] Test1 S1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped, + symbolValidator: (m) => + { + foreach (var tp in m.ContainingAssembly.GetTypeByMetadataName("<>f__AnonymousDelegate0`1").TypeParameters) + { + Assert.False(tp.AllowsRefLikeType); + } + } + ).VerifyDiagnostics(); + } + + [Fact] + public void AnonymousDelegateType_07_ActionDisallowsRefStruct_CannotAllowRefStruct() + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(S1 x) + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x, new S2()); + } +} + +class Helper +{ + public static void Test1(S1 x, S2 y) + { + System.Console.Write(""Test1""); + } +} + +ref struct S1 {} + +ref struct S2 {} + +namespace System +{ + public delegate void Action(T1 x, T2 y); +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"<>f__AnonymousDelegate0 Test1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped + ).VerifyDiagnostics(); + } + + [Fact] + public void AnonymousDelegateType_08_FuncDisallowsRefStruct_CannotAllowRefStruct() + { + var src = @" +class C +{ + static void Main() + { + Test1(new S1()); + } + + static void Test1(S1 x) + { + var d = Helper.Test1; + System.Console.Write(d.GetType()); + System.Console.Write("" ""); + d(x); + } +} + +class Helper +{ + public static S2 Test1(S1 x) + { + System.Console.Write(""Test1""); + return default; + } +} + +ref struct S1 {} + +ref struct S2 {} + +namespace System +{ + public delegate T2 Func(T1 x); +} +"; + var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? @"<>f__AnonymousDelegate0 Test1" : null, + verify: Verification.Skipped + ).VerifyDiagnostics(); + } + + [Fact] + public void ExpressionTree_01() + { + var src = @" +public class Helper +{ + static void Test1() + where T : allows ref struct + { + System.Linq.Expressions.Expression> e1 = (x) => System.Console.WriteLine(); + } + + static void Test2() + { + System.Linq.Expressions.Expression e2 = (y) => System.Console.WriteLine(); + } + + delegate void D1(T x) where T : allows ref struct; + delegate void D2(S x); +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,57): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'T'. + // System.Linq.Expressions.Expression> e1 = (x) => System.Console.WriteLine(); + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "x").WithArguments("T").WithLocation(7, 57), + // (12,54): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'S'. + // System.Linq.Expressions.Expression e2 = (y) => System.Console.WriteLine(); + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "y").WithArguments("S").WithLocation(12, 54) + ); + } + + [Fact] + public void ExpressionTree_02() + { + var src = @" +public class Helper1 + where T : allows ref struct +{ + static void Test1() + { + System.Linq.Expressions.Expression e1 = () => M1(); + } + + static T M1() => throw null; +} + +public class Helper2 +{ + static void Test2() + { + System.Linq.Expressions.Expression e2 = () => M2(); + } + + static S M2() => throw null; +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,70): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'T'. + // System.Linq.Expressions.Expression e1 = () => M1(); + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "M1()").WithArguments("T").WithLocation(7, 70), + // (17,70): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'S'. + // System.Linq.Expressions.Expression e2 = () => M2(); + Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "M2()").WithArguments("S").WithLocation(17, 70) + ); + } + + [Fact] + public void InArrayType_01() + { + var src = @" +public class Helper1 + where T : allows ref struct +{ + static T[] Test1() + => throw null; +} + +public class Helper2 +{ + static S[] Test2() + => throw null; +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (5,12): error CS0611: Array elements cannot be of type 'T' + // static T[] Test1() + Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "T").WithArguments("T").WithLocation(5, 12), + // (11,12): error CS0611: Array elements cannot be of type 'S' + // static S[] Test2() + Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "S").WithArguments("S").WithLocation(11, 12) + ); + } + + [Fact] + public void InArrayType_02() + { + var src = @" +public class Helper1 + where T : allows ref struct +{ + static void Test1() + { + _ = new T[] {}; + } +} + +public class Helper2 +{ + static void Test2() + { + _ = new S[] {}; + } +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,17): error CS0611: Array elements cannot be of type 'T' + // _ = new T[] {}; + Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "T").WithArguments("T").WithLocation(7, 17), + // (15,17): error CS0611: Array elements cannot be of type 'S' + // _ = new S[] {}; + Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "S").WithArguments("S").WithLocation(15, 17) + ); + } + + [Fact] + public void InArrayType_03() + { + var src = @" +public class Helper1 + where T : allows ref struct +{ + static void Test1(T x) + { + _ = new [] {x}; + } +} + +public class Helper2 +{ + static void Test2(S y) + { + _ = new [] {y}; + } +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0611: Array elements cannot be of type 'T' + // _ = new [] {x}; + Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "new [] {x}").WithArguments("T").WithLocation(7, 13), + // (15,13): error CS0611: Array elements cannot be of type 'S' + // _ = new [] {y}; + Diagnostic(ErrorCode.ERR_ArrayElementCantBeRefAny, "new [] {y}").WithArguments("S").WithLocation(15, 13) + ); + } + + [Fact] + public void DelegateReceiver_01() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + static System.Action Test1(T x) + => x.M; +} + +class Helper2 +{ + static System.Action Test2(S y) + => y.M; +} + +ref struct S +{ + public void M(){} +} + +interface I1 +{ + void M(); +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (6,14): error CS0123: No overload for 'M' matches delegate 'Action' + // => x.M; + Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Action").WithLocation(6, 14), + // (12,14): error CS0123: No overload for 'M' matches delegate 'Action' + // => y.M; + Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Action").WithLocation(12, 14) + ); + } + + [Fact] + public void DelegateReceiver_02() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + static void Test1(T x) + { + var d1 = x.M; + } +} + +class Helper2 +{ + static void Test2(S y) + { + var d2 = y.M; + } +} + +ref struct S +{ + public void M(){} +} + +interface I1 +{ + void M(); +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,20): error CS0123: No overload for 'M' matches delegate 'Action' + // var d1 = x.M; + Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Action").WithLocation(7, 20), + // (15,20): error CS0123: No overload for 'M' matches delegate 'Action' + // var d2 = y.M; + Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "System.Action").WithLocation(15, 20) + ); + } + + [Fact] + public void DelegateReceiver_03() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + static void Test1(T x) + { + var d1 = x.M; + } +} + +class Helper2 +{ + static void Test2(S y) + { + var d2 = y.M; + } +} + +ref struct S +{ + public void M(ref int x){} +} + +interface I1 +{ + void M(ref int x); +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,20): error CS0123: No overload for 'M' matches delegate '' + // var d1 = x.M; + Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "").WithLocation(7, 20), + // (15,20): error CS0123: No overload for 'M' matches delegate '' + // var d2 = y.M; + Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "M").WithArguments("M", "").WithLocation(15, 20) + ); + } + + [Fact] + public void ConditionalAccess_01() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + static void Test1(Helper1 h1) + { + var x = h1?.M1(); + } + + T M1() => default; +} + +class Helper2 +{ + static void Test2(Helper2 h2) + { + var x = h2?.M2(); + } + + S M2() => default; +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,20): error CS8978: 'T' cannot be made nullable. + // var x = h1?.M1(); + Diagnostic(ErrorCode.ERR_CannotBeMadeNullable, ".M1()").WithArguments("T").WithLocation(7, 20), + // (17,20): error CS8978: 'S' cannot be made nullable. + // var x = h2?.M2(); + Diagnostic(ErrorCode.ERR_CannotBeMadeNullable, ".M2()").WithArguments("S").WithLocation(17, 20) + ); + } + + [Fact] + public void ConditionalAccess_02() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + public static void Test1(Helper1 h1) + { + h1?.M1(); + } + + T M1() + { + System.Console.Write(""M1""); + return default; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(null); + System.Console.Write(""_""); + Helper1.Test1(new Helper1()); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "_M1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(Helper1)", +@" +{ + // Code size 11 (0xb) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_000a + IL_0003: ldarg.0 + IL_0004: call ""T Helper1.M1()"" + IL_0009: pop + IL_000a: ret +} +"); + } + + [Fact] + public void ConditionalAccess_03() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + public static void Test1(T h1) + { + System.Console.Write(h1?.M()); + } +} + +interface I1 +{ + int M(); +} + +ref struct S : I1 +{ + public int M() => 123; +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 48 (0x30) + .maxstack 1 + .locals init (int? V_0) + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_0013 + IL_0008: ldloca.s V_0 + IL_000a: initobj ""int?"" + IL_0010: ldloc.0 + IL_0011: br.s IL_0025 + IL_0013: ldarga.s V_0 + IL_0015: constrained. ""T"" + IL_001b: callvirt ""int I1.M()"" + IL_0020: newobj ""int?..ctor(int)"" + IL_0025: box ""int?"" + IL_002a: call ""void System.Console.Write(object)"" + IL_002f: ret +} +"); + } + + [Fact] + public void ConditionalAccess_04() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + public static void Test1(T h1) + { + System.Console.Write(h1?.M()); + } +} + +interface I1 +{ + dynamic M(); +} + +ref struct S : I1 +{ + public dynamic M() => 123; +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 129 (0x81) + .maxstack 9 + .locals init (T V_0, + T V_1) + IL_0000: ldsfld ""System.Runtime.CompilerServices.CallSite> Helper1.<>o__0.<>p__0"" + IL_0005: brtrue.s IL_0046 + IL_0007: ldc.i4 0x100 + IL_000c: ldstr ""Write"" + IL_0011: ldnull + IL_0012: ldtoken ""Helper1"" + IL_0017: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_001c: ldc.i4.2 + IL_001d: newarr ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"" + IL_0022: dup + IL_0023: ldc.i4.0 + IL_0024: ldc.i4.s 33 + IL_0026: ldnull + IL_0027: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_002c: stelem.ref + IL_002d: dup + IL_002e: ldc.i4.1 + IL_002f: ldc.i4.0 + IL_0030: ldnull + IL_0031: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0036: stelem.ref + IL_0037: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)"" + IL_003c: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" + IL_0041: stsfld ""System.Runtime.CompilerServices.CallSite> Helper1.<>o__0.<>p__0"" + IL_0046: ldsfld ""System.Runtime.CompilerServices.CallSite> Helper1.<>o__0.<>p__0"" + IL_004b: ldfld ""System.Action System.Runtime.CompilerServices.CallSite>.Target"" + IL_0050: ldsfld ""System.Runtime.CompilerServices.CallSite> Helper1.<>o__0.<>p__0"" + IL_0055: ldtoken ""System.Console"" + IL_005a: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_005f: ldarg.0 + IL_0060: stloc.0 + IL_0061: ldloc.0 + IL_0062: box ""T"" + IL_0067: brtrue.s IL_006c + IL_0069: ldnull + IL_006a: br.s IL_007b + IL_006c: ldloc.0 + IL_006d: stloc.1 + IL_006e: ldloca.s V_1 + IL_0070: constrained. ""T"" + IL_0076: callvirt ""dynamic I1.M()"" + IL_007b: callvirt ""void System.Action.Invoke(System.Runtime.CompilerServices.CallSite, System.Type, dynamic)"" + IL_0080: ret +} +"); + } + + [Fact] + public void ConditionalAccess_05() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + void Test(out T y) + { + T x = T.Create(stackalloc int[2]); + if (x?.M(out y) == true) + { + return; + } + + y = default; + } +} + +interface I1 where S : I1, allows ref struct +{ + bool M(out S x); + static abstract S Create(System.Span x); +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,15): error CS8350: This combination of arguments to 'I1.M(out T)' is disallowed because it may expose variables referenced by parameter 'this' outside of their declaration scope + // if (x?.M(out y) == true) + Diagnostic(ErrorCode.ERR_CallArgMixing, ".M(out y)").WithArguments("I1.M(out T)", "this").WithLocation(8, 15) + ); + } + + [Fact] + public void ConditionalAccess_06() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + void Test(T y) + { + T x = T.Create(stackalloc int[2]); + if (x?.M(y) == true) + { + return; + } + } +} + +interface I1 where S : I1, allows ref struct +{ + bool M(S x); + static abstract S Create(System.Span x); +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void DynamicAccess_01() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + static void Test1(dynamic h1) + { + h1.M1(); + } +} + +class Helper2 +{ + static void Test2(dynamic h2) + { + h2.M2(); + } +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,15): error CS0306: The type 'T' may not be used as a type argument + // h1.M1(); + Diagnostic(ErrorCode.ERR_BadTypeArgument, "T").WithArguments("T").WithLocation(7, 15), + // (15,15): error CS0306: The type 'S' may not be used as a type argument + // h2.M2(); + Diagnostic(ErrorCode.ERR_BadTypeArgument, "S").WithArguments("S").WithLocation(15, 15) + ); + } + + [Fact] + public void DynamicAccess_02() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + static void Test1(dynamic h1, T x) + { + h1.M1(x); + } +} + +class Helper2 +{ + static void Test2(dynamic h2, S y) + { + h2.M2(y); + } +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,15): error CS1978: Cannot use an expression of type 'T' as an argument to a dynamically dispatched operation. + // h1.M1(x); + Diagnostic(ErrorCode.ERR_BadDynamicMethodArg, "x").WithArguments("T").WithLocation(7, 15), + // (15,15): error CS1978: Cannot use an expression of type 'S' as an argument to a dynamically dispatched operation. + // h2.M2(y); + Diagnostic(ErrorCode.ERR_BadDynamicMethodArg, "y").WithArguments("S").WithLocation(15, 15) + ); + } + + [Fact] + public void DynamicAccess_03() + { + var src = @" +class Helper1 + where T : I1, allows ref struct +{ + static void Test1(dynamic h1, T x) + { + x.M(h1); + } +} + +class Helper2 +{ + static void Test2(dynamic h2, S y) + { + y.M(h2); + } +} + +interface I1 +{ + void M(int x); + void M(long x); +} + +ref struct S : I1 +{ + public void M(int x) => throw null; + public void M(long x) => throw null; +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,9): error CS9230: Cannot perform a dynamic invocation on an expression with type 'T'. + // x.M(h1); + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "x").WithArguments("T").WithLocation(7, 9), + // (15,9): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // y.M(h2); + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "y").WithArguments("S").WithLocation(15, 9) + ); + } + + [Fact] + public void IsOperator_01() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(I1 h1) + { + if (h1 is T) + { + System.Console.Write(1); + } + else + { + System.Console.Write(2); + } + } +} + +class Helper2 +{ + public static void Test2(I1 h2) + { + if (h2 is S) + { + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} + +struct S1 : I1 {} + +class Program : I1 +{ + static void Main() + { + Helper1.Test1(new S1()); + Helper1.Test1(new Program()); + Helper2.Test2(new S1()); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "214" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (22,13): warning CS0184: The given expression is never of the provided ('S') type + // if (h2 is S) + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "h2 is S").WithArguments("S").WithLocation(22, 13) + ); + + // According to + // https://github.com/dotnet/runtime/pull/101458#issuecomment-2074169181 and + // https://github.com/dotnet/runtime/pull/101458#issuecomment-2075815858 + // the following is a valid IL + verifier.VerifyIL("Helper1.Test1(I1)", +@" +{ + // Code size 22 (0x16) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: isinst ""T"" + IL_0006: brfalse.s IL_000f + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: ret + IL_000f: ldc.i4.2 + IL_0010: call ""void System.Console.Write(int)"" + IL_0015: ret +} +"); + + verifier.VerifyIL("Helper2.Test2(I1)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.4 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + } + + [Fact] + public void IsOperator_02() + { + var src1 = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is I1) + { + } + } +} + +interface I1 +{ +} +"; + var comp = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'T' and 'I1' + // if (h1 is I1) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 is I1").WithArguments("is", "T", "I1").WithLocation(7, 13) + ); + + var src2 = @" +class Helper2 +{ + public static void Test2(S h2) + { + if (h2 is I1) + { + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} + +class Program +{ + static void Main() + { + Helper2.Test2(new S()); + } +} +"; + + comp = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "4" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (6,13): warning CS0184: The given expression is never of the provided ('I1') type + // if (h2 is I1) + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "h2 is I1").WithArguments("I1").WithLocation(6, 13) + ); + + verifier.VerifyIL("Helper2.Test2(S)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.4 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + } + + [Fact] + public void IsOperator_03() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is T) + { + System.Console.Write(1); + } + else + { + System.Console.Write(2); + } + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + Helper1.Test1(new Program()); + Helper1.Test1(null); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "112" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 22 (0x16) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000f + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: ret + IL_000f: ldc.i4.2 + IL_0010: call ""void System.Console.Write(int)"" + IL_0015: ret +} +"); + } + + [Fact] + public void IsOperator_04() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is T) + { + System.Console.Write(1); + } + else + { + System.Console.Write(2); + } + } +} + +class Helper2 +{ + public static void Test2(S h2) + { + if (h2 is S) + { + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + Helper1.Test1(1); + Helper2.Test2(new S()); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "113" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (7,13): warning CS0183: The given expression is always of the provided ('T') type + // if (h1 is T) + Diagnostic(ErrorCode.WRN_IsAlwaysTrue, "h1 is T").WithArguments("T").WithLocation(7, 13), + // (22,13): warning CS0183: The given expression is always of the provided ('S') type + // if (h2 is S) + Diagnostic(ErrorCode.WRN_IsAlwaysTrue, "h2 is S").WithArguments("S").WithLocation(22, 13) + ); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.1 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + + verifier.VerifyIL("Helper2.Test2(S)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.3 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + } + + [Fact] + public void IsOperator_05() + { + var src1 = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is U) + { + } + } +} +"; + + var comp = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'T' and 'U' + // if (h1 is U) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 is U").WithArguments("is", "T", "U").WithLocation(7, 13) + ); + + var src2 = @" +class Helper2 +{ + public static void Test2(S h2) + { + if (h2 is U) + { + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} + +class Program +{ + static void Main() + { + Helper2.Test2(new S()); + } +} +"; + comp = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "4" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (6,13): warning CS0184: The given expression is never of the provided ('U') type + // if (h2 is U) + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "h2 is U").WithArguments("U").WithLocation(6, 13) + ); + + verifier.VerifyIL("Helper2.Test2(S)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.4 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + } + + [Fact] + public void IsOperator_06() + { + var src = @" +class Helper1 + where T : allows ref struct + where U : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is U) + { + } + } +} + +class Helper2 + where U : allows ref struct +{ + public static void Test2(S h2) + { + if (h2 is U) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,13): error CS0019: Operator 'is' cannot be applied to operands of type 'T' and 'U' + // if (h1 is U) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 is U").WithArguments("is", "T", "U").WithLocation(8, 13), + // (19,13): error CS0019: Operator 'is' cannot be applied to operands of type 'S' and 'U' + // if (h2 is U) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h2 is U").WithArguments("is", "S", "U").WithLocation(19, 13) + ); + } + + [Fact] + public void IsOperator_07() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + static void Test1(U h1) + { + if (h1 is T) + { + } + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'U' and 'T' + // if (h1 is T) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 is T").WithArguments("is", "U", "T").WithLocation(7, 13) + ); + + var src2 = @" +class Helper2 +{ + public static void Test2(U h2) + { + if (h2 is S) + { + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} + +class Program : I1 +{ + static void Main() + { + Helper2.Test2(new Program()); + } +} +"; + comp = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "4" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (6,13): warning CS0184: The given expression is never of the provided ('S') type + // if (h2 is S) + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "h2 is S").WithArguments("S").WithLocation(6, 13) + ); + + verifier.VerifyIL("Helper2.Test2(U)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.4 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + } + + [Fact] + public void IsOperator_08() + { + var src = @" +class Helper2 + where U : allows ref struct +{ + public static void Test2(U h2) + { + if (h2 is S) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'U' and 'S' + // if (h2 is S) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h2 is S").WithArguments("is", "U", "S").WithLocation(7, 13) + ); + } + + [Fact] + public void IsOperator_09() + { + var src = @" +class Helper2 +{ + public static void Test2(S1 h2) + { + if (h2 is S2) + { + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S1 +{ +} + +ref struct S2 +{ +} + +class Program +{ + static void Main() + { + Helper2.Test2(new S1()); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "4" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics( + // (6,13): warning CS0184: The given expression is never of the provided ('S2') type + // if (h2 is S2) + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "h2 is S2").WithArguments("S2").WithLocation(6, 13) + ); + + verifier.VerifyIL("Helper2.Test2(S1)", +@" +{ + // Code size 7 (0x7) + .maxstack 1 + IL_0000: ldc.i4.4 + IL_0001: call ""void System.Console.Write(int)"" + IL_0006: ret +} +"); + } + + [Fact] + public void IsOperator_10() + { + var src = @" +class Helper1 + where T : allows ref struct + where U : T, allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is U) + { + } + } + public static void Test2(U h2) + { + if (h2 is T) + { + } + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,13): error CS0019: Operator 'is' cannot be applied to operands of type 'T' and 'U' + // if (h1 is U) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 is U").WithArguments("is", "T", "U").WithLocation(8, 13), + // (14,13): error CS0019: Operator 'is' cannot be applied to operands of type 'U' and 'T' + // if (h2 is T) + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h2 is T").WithArguments("is", "U", "T").WithLocation(14, 13) + ); + } + + [Fact] + public void IsPattern_01() + { + var src1 = @" +class Helper1 + where T : I1, allows ref struct +{ + public static void Test1(I1 h1) + { + if (h1 is T t) + { + t.M(); + } + else + { + System.Console.Write(2); + } + } +} +ref struct S : I1 +{ + public void M() + { + System.Console.Write(3); + } +} + +interface I1 +{ + void M(); +} + +class Program : I1 +{ + static void Main() + { + Helper1.Test1(new Program()); + Helper1.Test1(new Program()); + } + + public void M() + { + System.Console.Write(1); + } +} +"; + + var comp1 = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp1, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "21" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped); + + // According to + // https://github.com/dotnet/runtime/pull/101458#issuecomment-2074169181 and + // https://github.com/dotnet/runtime/pull/101458#issuecomment-2075815858 + // the following is a valid IL + verifier.VerifyIL("Helper1.Test1(I1)", +@" +{ + // Code size 41 (0x29) + .maxstack 1 + .locals init (T V_0) //t + IL_0000: ldarg.0 + IL_0001: isinst ""T"" + IL_0006: brfalse.s IL_0022 + IL_0008: ldarg.0 + IL_0009: isinst ""T"" + IL_000e: unbox.any ""T"" + IL_0013: stloc.0 + IL_0014: ldloca.s V_0 + IL_0016: constrained. ""T"" + IL_001c: callvirt ""void I1.M()"" + IL_0021: ret + IL_0022: ldc.i4.2 + IL_0023: call ""void System.Console.Write(int)"" + IL_0028: ret +} +"); + + var src2 = @" +class Helper2 +{ + static void Test2(I1 h2) + { + if (h2 is S s) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp2 = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyDiagnostics( + // (6,19): error CS8121: An expression of type 'I1' cannot be handled by a pattern of type 'S'. + // if (h2 is S s) + Diagnostic(ErrorCode.ERR_PatternWrongType, "S").WithArguments("I1", "S").WithLocation(6, 19) + ); + } + + [Fact] + public void IsPattern_02() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + static void Test1(T h1) + { + if (h1 is I1 t) + { + } + } +} + +class Helper2 +{ + static void Test2(S h2) + { + if (h2 is I1 s) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,19): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'I1'. + // if (h1 is I1 t) + Diagnostic(ErrorCode.ERR_PatternWrongType, "I1").WithArguments("T", "I1").WithLocation(7, 19), + // (17,19): error CS8121: An expression of type 'S' cannot be handled by a pattern of type 'I1'. + // if (h2 is I1 s) + Diagnostic(ErrorCode.ERR_PatternWrongType, "I1").WithArguments("S", "I1").WithLocation(17, 19) + ); + } + + [Fact] + public void IsPattern_03() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is T t) + { + Program.M(t); + System.Console.Write(1); + } + else + { + System.Console.Write(2); + } + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + Helper1.Test1(new Program()); + Helper1.Test1(null); + } + + public static void M(T t) where T : allows ref struct {} +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "112" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 30 (0x1e) + .maxstack 1 + .locals init (T V_0) //t + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_0017 + IL_0008: ldarg.0 + IL_0009: stloc.0 + IL_000a: ldloc.0 + IL_000b: call ""void Program.M(T)"" + IL_0010: ldc.i4.1 + IL_0011: call ""void System.Console.Write(int)"" + IL_0016: ret + IL_0017: ldc.i4.2 + IL_0018: call ""void System.Console.Write(int)"" + IL_001d: ret +} +"); + } + + [Fact] + public void IsPattern_04() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is T t) + { + Program.M(t); + System.Console.Write(1); + } + else + { + System.Console.Write(2); + } + } +} + +class Helper2 +{ + public static void Test2(S h2) + { + if (h2 is S s) + { + Program.M(s); + System.Console.Write(3); + } + else + { + System.Console.Write(4); + } + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + Helper1.Test1(new S()); + Helper1.Test1(1); + Helper2.Test2(new S()); + } + + public static void M(T t) where T : allows ref struct {} +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "113" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped). + VerifyDiagnostics(); + + verifier.VerifyIL("Helper1.Test1(T)", +@" +{ + // Code size 15 (0xf) + .maxstack 1 + .locals init (T V_0) //t + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: call ""void Program.M(T)"" + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: ret +} +"); + + verifier.VerifyIL("Helper2.Test2(S)", +@" +{ + // Code size 15 (0xf) + .maxstack 1 + .locals init (S V_0) //s + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: call ""void Program.M(S)"" + IL_0008: ldc.i4.3 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: ret +} +"); + } + + [Fact] + public void IsPattern_05() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is U u) + { + } + } +} + +class Helper2 +{ + public static void Test2(S h2) + { + if (h2 is U u) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,19): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'U'. + // if (h1 is U u) + Diagnostic(ErrorCode.ERR_PatternWrongType, "U").WithArguments("T", "U").WithLocation(7, 19), + // (17,19): error CS8121: An expression of type 'S' cannot be handled by a pattern of type 'U'. + // if (h2 is U u) + Diagnostic(ErrorCode.ERR_PatternWrongType, "U").WithArguments("S", "U").WithLocation(17, 19) + ); + } + + [Fact] + public void IsPattern_06() + { + var src = @" +class Helper1 + where T : allows ref struct + where U : allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is U u) + { + } + } +} + +class Helper2 + where U : allows ref struct +{ + public static void Test2(S h2) + { + if (h2 is U u) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,19): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'U'. + // if (h1 is U u) + Diagnostic(ErrorCode.ERR_PatternWrongType, "U").WithArguments("T", "U").WithLocation(8, 19), + // (19,19): error CS8121: An expression of type 'S' cannot be handled by a pattern of type 'U'. + // if (h2 is U u) + Diagnostic(ErrorCode.ERR_PatternWrongType, "U").WithArguments("S", "U").WithLocation(19, 19) + ); + } + + [Fact] + public void IsPattern_07() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + static void Test1(U h1) + { + if (h1 is T t) + { + } + } +} + +class Helper2 +{ + public static void Test2(U h2) + { + if (h2 is S s) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,19): error CS8121: An expression of type 'U' cannot be handled by a pattern of type 'T'. + // if (h1 is T t) + Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("U", "T").WithLocation(7, 19), + // (17,19): error CS8121: An expression of type 'U' cannot be handled by a pattern of type 'S'. + // if (h2 is S s) + Diagnostic(ErrorCode.ERR_PatternWrongType, "S").WithArguments("U", "S").WithLocation(17, 19) + ); + } + + [Fact] + public void IsPattern_08() + { + var src = @" +class Helper2 + where U : allows ref struct +{ + public static void Test2(U h2) + { + if (h2 is S s) + { + } + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,19): error CS8121: An expression of type 'U' cannot be handled by a pattern of type 'S'. + // if (h2 is S s) + Diagnostic(ErrorCode.ERR_PatternWrongType, "S").WithArguments("U", "S").WithLocation(7, 19) + ); + } + + [Fact] + public void IsPattern_09() + { + var src = @" +class Helper2 +{ + public static void Test2(S1 h2) + { + if (h2 is S2 s2) + { + } + } +} + +ref struct S1 +{ +} + +ref struct S2 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (6,19): error CS8121: An expression of type 'S1' cannot be handled by a pattern of type 'S2'. + // if (h2 is S2 s2) + Diagnostic(ErrorCode.ERR_PatternWrongType, "S2").WithArguments("S1", "S2").WithLocation(6, 19) + ); + } + + [Fact] + public void IsPattern_10() + { + var src = @" +class Helper1 + where T : allows ref struct + where U : T, allows ref struct +{ + public static void Test1(T h1) + { + if (h1 is U u) + { + } + } + public static void Test2(U h2) + { + if (h2 is T t) + { + } + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,19): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'U'. + // if (h1 is U u) + Diagnostic(ErrorCode.ERR_PatternWrongType, "U").WithArguments("T", "U").WithLocation(8, 19), + // (14,19): error CS8121: An expression of type 'U' cannot be handled by a pattern of type 'T'. + // if (h2 is T t) + Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("U", "T").WithLocation(14, 19) + ); + } + + [Fact] + public void AsOperator_01() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(I1 h1) + { + _ = h1 as T; + } +} + +class Helper2 +{ + public static void Test2(I1 h2) + { + _ = h2 as S; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} + +struct S1 : I1 {} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0413: The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as T; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as T").WithArguments("T").WithLocation(7, 13), + // (15,13): error CS0077: The as operator must be used with a reference type or nullable type ('S' is a non-nullable value type) + // _ = h2 as S; + Diagnostic(ErrorCode.ERR_AsMustHaveReferenceType, "h2 as S").WithArguments("S").WithLocation(15, 13) + ); + } + + [Fact] + public void AsOperator_02() + { + var src1 = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + _ = h1 as I1; + } +} + +class Helper2 +{ + public static void Test2(S h2) + { + _ = h2 as I1; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + var comp = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0019: Operator 'as' cannot be applied to operands of type 'T' and 'I1' + // _ = h1 as I1; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 as I1").WithArguments("as", "T", "I1").WithLocation(7, 13), + // (15,13): error CS0039: Cannot convert type 'S' to 'I1' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion + // _ = h2 as I1; + Diagnostic(ErrorCode.ERR_NoExplicitBuiltinConv, "h2 as I1").WithArguments("S", "I1").WithLocation(15, 13) + ); + } + + [Fact] + public void AsOperator_03() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + _ = h1 as T; + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0413: The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as T; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as T").WithArguments("T").WithLocation(7, 13) + ); + } + + [Fact] + public void AsOperator_04() + { + var src = @" +class Helper1 + where T : struct, allows ref struct +{ + public static void Test1(T h1) + { + _ = h1 as T; + } +} + +class Helper2 +{ + public static void Test2(S h2) + { + _ = h2 as S; + } +} + +ref struct S +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0413: The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as T; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as T").WithArguments("T").WithLocation(7, 13), + // (15,13): error CS0077: The as operator must be used with a reference type or nullable type ('S' is a non-nullable value type) + // _ = h2 as S; + Diagnostic(ErrorCode.ERR_AsMustHaveReferenceType, "h2 as S").WithArguments("S").WithLocation(15, 13) + ); + } + + [Fact] + public void AsOperator_05() + { + var src1 = @" +class Helper1 + where T : allows ref struct +{ + public static void Test1(T h1) + { + _ = h1 as U; + } +} + +class Helper2 +{ + public static void Test2(S h2) + { + _ = h2 as U; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0413: The type parameter 'U' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as U; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as U").WithArguments("U").WithLocation(7, 13), + // (15,13): error CS0413: The type parameter 'U' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h2 as U; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h2 as U").WithArguments("U").WithLocation(15, 13) + ); + + var src2 = @" +class Helper1 + where T : allows ref struct + where U : class +{ + public static void Test1(T h1) + { + _ = h1 as U; + } +} + +class Helper2 + where U : class +{ + public static void Test2(S h2) + { + _ = h2 as U; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + comp = CreateCompilation(src2, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,13): error CS0019: Operator 'as' cannot be applied to operands of type 'T' and 'U' + // _ = h1 as U; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h1 as U").WithArguments("as", "T", "U").WithLocation(8, 13), + // (17,13): error CS0019: Operator 'as' cannot be applied to operands of type 'S' and 'U' + // _ = h2 as U; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "h2 as U").WithArguments("as", "S", "U").WithLocation(17, 13) + ); + } + + [Fact] + public void AsOperator_06() + { + var src = @" +class Helper1 + where T : allows ref struct + where U : allows ref struct +{ + public static void Test1(T h1) + { + _ = h1 as U; + } +} + +class Helper2 + where U : allows ref struct +{ + public static void Test2(S h2) + { + _ = h2 as U; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,13): error CS0413: The type parameter 'U' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as U; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as U").WithArguments("U").WithLocation(8, 13), + // (17,13): error CS0413: The type parameter 'U' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h2 as U; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h2 as U").WithArguments("U").WithLocation(17, 13) + ); + } + + [Fact] + public void AsOperator_07() + { + var src = @" +class Helper1 + where T : allows ref struct +{ + static void Test1(U h1) + { + _ = h1 as T; + } +} + +class Helper2 +{ + public static void Test2(U h2) + { + _ = h2 as S; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0413: The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as T; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as T").WithArguments("T").WithLocation(7, 13), + // (15,13): error CS0077: The as operator must be used with a reference type or nullable type ('S' is a non-nullable value type) + // _ = h2 as S; + Diagnostic(ErrorCode.ERR_AsMustHaveReferenceType, "h2 as S").WithArguments("S").WithLocation(15, 13) + ); + } + + [Fact] + public void AsOperator_08() + { + var src = @" +class Helper2 + where U : allows ref struct +{ + public static void Test2(U h2) + { + _ = h2 as S; + } +} + +ref struct S : I1 +{ +} + +interface I1 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,13): error CS0077: The as operator must be used with a reference type or nullable type ('S' is a non-nullable value type) + // _ = h2 as S; + Diagnostic(ErrorCode.ERR_AsMustHaveReferenceType, "h2 as S").WithArguments("S").WithLocation(7, 13) + ); + } + + [Fact] + public void AsOperator_09() + { + var src = @" +class Helper2 +{ + public static void Test2(S1 h2) + { + _ = h2 as S2; + } +} + +ref struct S1 +{ +} + +ref struct S2 +{ +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (6,13): error CS0077: The as operator must be used with a reference type or nullable type ('S2' is a non-nullable value type) + // _ = h2 as S2; + Diagnostic(ErrorCode.ERR_AsMustHaveReferenceType, "h2 as S2").WithArguments("S2").WithLocation(6, 13) + ); + } + + [Fact] + public void AsOperator_10() + { + var src = @" +class Helper1 + where T : allows ref struct + where U : T, allows ref struct +{ + public static void Test1(T h1) + { + _ = h1 as U; + } + public static void Test2(U h2) + { + _ = h2 as T; + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (8,13): error CS0413: The type parameter 'U' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h1 as U; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h1 as U").WithArguments("U").WithLocation(8, 13), + // (12,13): error CS0413: The type parameter 'T' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint + // _ = h2 as T; + Diagnostic(ErrorCode.ERR_AsWithTypeVar, "h2 as T").WithArguments("T").WithLocation(12, 13) + ); + } + + [Fact] + public void IllegalCapturing_01() + { + var source = @" +ref struct R1 +{ +} + +ref struct R2(R1 r1, T t) + where T : allows ref struct +{ + R1 M1() => r1; + T M2() => t; +} +"; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyEmitDiagnostics( + // (9,16): error CS9110: Cannot use primary constructor parameter 'r1' that has ref-like type inside an instance member + // R1 M1() => r1; + Diagnostic(ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefLike, "r1").WithArguments("r1").WithLocation(9, 16), + // (10,15): error CS9110: Cannot use primary constructor parameter 't' that has ref-like type inside an instance member + // T M2() => t; + Diagnostic(ErrorCode.ERR_UnsupportedPrimaryConstructorParameterCapturingRefLike, "t").WithArguments("t").WithLocation(10, 15) + ); + } + + [Fact] + public void IllegalCapturing_02() + { + var source = @" +ref struct R1 +{ +} + +class C +{ + void M(R1 r1, T t) + where T : allows ref struct + { + var d1 = () => r1; + var d2 = () => t; + } +} +"; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyEmitDiagnostics( + // (11,24): error CS9108: Cannot use parameter 'r1' that has ref-like type inside an anonymous method, lambda expression, query expression, or local function + // var d1 = () => r1; + Diagnostic(ErrorCode.ERR_AnonDelegateCantUseRefLike, "r1").WithArguments("r1").WithLocation(11, 24), + // (12,24): error CS9108: Cannot use parameter 't' that has ref-like type inside an anonymous method, lambda expression, query expression, or local function + // var d2 = () => t; + Diagnostic(ErrorCode.ERR_AnonDelegateCantUseRefLike, "t").WithArguments("t").WithLocation(12, 24) + ); + } + + [Fact] + public void IllegalCapturing_03() + { + var source = @" +ref struct R1 +{ +} + +class C +{ + void M(R1 r1, T t) + where T : allows ref struct + { + R1 r2 = r1; + T t2 = t; + + var d1 = () => r2; + var d2 = () => t2; + } +} +"; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyEmitDiagnostics( + // (14,24): error CS8175: Cannot use ref local 'r2' inside an anonymous method, lambda expression, or query expression + // var d1 = () => r2; + Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "r2").WithArguments("r2").WithLocation(14, 24), + // (15,24): error CS8175: Cannot use ref local 't2' inside an anonymous method, lambda expression, or query expression + // var d2 = () => t2; + Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "t2").WithArguments("t2").WithLocation(15, 24) + ); + } + + [Fact] + public void PassingSpansToParameters_Errors() + { + var src = @" +using System; +class C +{ + static void Main() + { + Span s1 = stackalloc int[1]; + M1(s1); + } + + static void M1(T s1) where T : allows ref struct + { + var obj = new C(); + T s2 = M3(stackalloc int[2]); + + M2(ref s1, out s2); // one + M2(ref s2, out s1); // two + + M2(ref s1, out s2); // three + M2(ref s2, out s1); // four + + M2(y: out s2, x: ref s1); // five + M2(y: out s1, x: ref s2); // six + + M2(ref s1, out s1); // okay + M2(ref s2, out s2); // okay + } + + static void M2(scoped ref T x, out T y) + where T : allows ref struct + { + y = default; + } + + static T M3(Span x) where T : allows ref struct => default; +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (17,9): error CS8350: This combination of arguments to 'C.M2(scoped ref T, out T)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope + // M2(ref s2, out s1); // two + Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s2, out s1)").WithArguments("C.M2(scoped ref T, out T)", "x").WithLocation(17, 9), + // (17,16): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope + // M2(ref s2, out s1); // two + Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(17, 16), + // (20,9): error CS8350: This combination of arguments to 'C.M2(scoped ref T, out T)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope + // M2(ref s2, out s1); // four + Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(ref s2, out s1)").WithArguments("C.M2(scoped ref T, out T)", "x").WithLocation(20, 9), + // (20,16): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope + // M2(ref s2, out s1); // four + Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(20, 16), + // (23,9): error CS8350: This combination of arguments to 'C.M2(scoped ref T, out T)' is disallowed because it may expose variables referenced by parameter 'x' outside of their declaration scope + // M2(y: out s1, x: ref s2); // six + Diagnostic(ErrorCode.ERR_CallArgMixing, "M2(y: out s1, x: ref s2)").WithArguments("C.M2(scoped ref T, out T)", "x").WithLocation(23, 9), + // (23,30): error CS8352: Cannot use variable 's2' in this context because it may expose referenced variables outside of their declaration scope + // M2(y: out s1, x: ref s2); // six + Diagnostic(ErrorCode.ERR_EscapeVariable, "s2").WithArguments("s2").WithLocation(23, 30) + ); + } + + [Fact] + public void RefLikeReturnEscape1() + { + var text = @" + using System; + + class Program where T : allows ref struct + { + static void Main() + { + } + + static ref int Test1(T arg) + { + throw null; + } + + static T MayWrap(Span arg) + { + return default; + } + + static ref int Test3() + { + Span local = stackalloc int[1]; + var sp = MayWrap(local); + return ref Test1(sp); + } + } +"; + CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).VerifyDiagnostics( + // (24,30): error CS8352: Cannot use variable 'sp' in this context because it may expose referenced variables outside of their declaration scope + // return ref Test1(sp); + Diagnostic(ErrorCode.ERR_EscapeVariable, "sp").WithArguments("sp").WithLocation(24, 30), + // (24,24): error CS8347: Cannot use a result of 'Program.Test1(T)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope + // return ref Test1(sp); + Diagnostic(ErrorCode.ERR_EscapeCall, "Test1(sp)").WithArguments("Program.Test1(T)", "arg").WithLocation(24, 24) + ); + } + + [Fact] + public void RefLikeEscapeMixingCall() + { + var text = @" + using System; + class Program where T : allows ref struct + { + static void Main() + { + } + + void Test1() + { + T rOuter = default; + + Span inner = stackalloc int[1]; + T rInner = MayWrap(ref inner); + + // valid + MayAssign(ref rOuter, ref rOuter); + + // error + MayAssign(ref rOuter, ref rInner); + + // error + MayAssign(ref inner, ref rOuter); + } + + static void MayAssign(ref Span arg1, ref T arg2) + { + arg2 = MayWrap(ref arg1); + } + + static void MayAssign(ref T arg1, ref T arg2) + { + arg1 = arg2; + } + + static T MayWrap(ref Span arg) + { + return default; + } + } +"; + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (20,39): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope + // MayAssign(ref rOuter, ref rInner); + Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 39), + // (20,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref T, ref T)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope + // MayAssign(ref rOuter, ref rInner); + Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref rOuter, ref rInner)").WithArguments("Program.MayAssign(ref T, ref T)", "arg2").WithLocation(20, 13), + // (23,27): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // MayAssign(ref inner, ref rOuter); + Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 27), + // (23,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref Span, ref T)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope + // MayAssign(ref inner, ref rOuter); + Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref inner, ref rOuter)").WithArguments("Program.MayAssign(ref System.Span, ref T)", "arg1").WithLocation(23, 13), + // (28,32): error CS9077: Cannot return a parameter by reference 'arg1' through a ref parameter; it can only be returned in a return statement + // arg2 = MayWrap(ref arg1); + Diagnostic(ErrorCode.ERR_RefReturnOnlyParameter, "arg1").WithArguments("arg1").WithLocation(28, 32), + // (28,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope + // arg2 = MayWrap(ref arg1); + Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref arg1)").WithArguments("Program.MayWrap(ref System.Span)", "arg").WithLocation(28, 20) + ); + + comp = CreateCompilation(text, targetFramework: TargetFramework.Net60, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (3,39): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // class Program where T : allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(3, 39), + // (3,39): error CS9240: Target runtime doesn't support by-ref-like generics. + // class Program where T : allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(3, 39), + // (20,39): error CS8352: Cannot use variable 'rInner' in this context because it may expose referenced variables outside of their declaration scope + // MayAssign(ref rOuter, ref rInner); + Diagnostic(ErrorCode.ERR_EscapeVariable, "rInner").WithArguments("rInner").WithLocation(20, 39), + // (20,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref T, ref T)' is disallowed because it may expose variables referenced by parameter 'arg2' outside of their declaration scope + // MayAssign(ref rOuter, ref rInner); + Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref rOuter, ref rInner)").WithArguments("Program.MayAssign(ref T, ref T)", "arg2").WithLocation(20, 13), + // (23,27): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // MayAssign(ref inner, ref rOuter); + Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(23, 27), + // (23,13): error CS8350: This combination of arguments to 'Program.MayAssign(ref Span, ref T)' is disallowed because it may expose variables referenced by parameter 'arg1' outside of their declaration scope + // MayAssign(ref inner, ref rOuter); + Diagnostic(ErrorCode.ERR_CallArgMixing, "MayAssign(ref inner, ref rOuter)").WithArguments("Program.MayAssign(ref System.Span, ref T)", "arg1").WithLocation(23, 13) + ); + } + + [Fact] + public void RefSafeToEscape_05() + { + var source = +@" +class Program where T : allows ref struct +{ + static ref T F0(T r0) + { + scoped ref T l0 = ref r0; + return ref l0; // 1 + } + static ref T F1(scoped T r1) + { + scoped ref T l1 = ref r1; // 2 + return ref l1; // 3 + } + static ref T F2(ref T r2) + { + scoped ref T l2 = ref r2; + return ref l2; // 4 + } + static ref T F3(scoped ref T r3) + { + scoped ref T l3 = ref r3; + return ref l3; // 5 + } +}"; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (7,20): error CS8157: Cannot return 'l0' by reference because it was initialized to a value that cannot be returned by reference + // return ref l0; // 1 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l0").WithArguments("l0").WithLocation(7, 20), + // (11,31): error CS8352: Cannot use variable 'scoped T r1' in this context because it may expose referenced variables outside of their declaration scope + // scoped ref T l1 = ref r1; // 2 + Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("scoped T r1").WithLocation(11, 31), + // (12,20): error CS8157: Cannot return 'l1' by reference because it was initialized to a value that cannot be returned by reference + // return ref l1; // 3 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l1").WithArguments("l1").WithLocation(12, 20), + // (17,20): error CS8157: Cannot return 'l2' by reference because it was initialized to a value that cannot be returned by reference + // return ref l2; // 4 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l2").WithArguments("l2").WithLocation(17, 20), + // (22,20): error CS8157: Cannot return 'l3' by reference because it was initialized to a value that cannot be returned by reference + // return ref l3; // 5 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "l3").WithArguments("l3").WithLocation(22, 20) + ); + } + + [Fact] + public void RefToRefStructParameter_02() + { + var source = +@" +class Program where R : allows ref struct +{ + static ref R F1() + { + int i = 42; + var r1 = GetR(ref i); + return ref ReturnRef(ref r1); + } + static ref R F2(ref int i) + { + var r2 = GetR(ref i); + return ref ReturnRef(ref r2); + } + + static ref R ReturnRef(scoped ref R r) => throw null; + + static R GetR(ref int x) => throw null; +}"; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics(); + } + + [Fact] + public void ReturnRefToByValueParameter_01() + { + var source = +@" +using System.Diagnostics.CodeAnalysis; + +class Program where S : allows ref struct +{ + static ref S F1([UnscopedRef] ref S x1) + { + return ref x1; + } + static ref S F2(S x2) + { + ref var y2 = ref F1(ref x2); + return ref y2; // 1 + } +}"; + + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics( + // (13,20): error CS8157: Cannot return 'y2' by reference because it was initialized to a value that cannot be returned by reference + // return ref y2; // 1 + Diagnostic(ErrorCode.ERR_RefReturnNonreturnableLocal, "y2").WithArguments("y2").WithLocation(13, 20) + ); + } + + [Fact] + public void ReturnRefToRefStruct_RefEscape_01() + { + var source = """ + public class Repro where RefStruct : allows ref struct + { + private static ref RefStruct M1(ref RefStruct s1, ref RefStruct s2) + { + bool b = false; + return ref b ? ref s1 : ref s2; + } + + private static ref RefStruct M2(ref RefStruct s1) + { + RefStruct s2 = default; + // RSTE of s1 is ReturnOnly + // RSTE of s2 is CurrentMethod + return ref M1(ref s1, ref s2); // 1 + } + + private static ref RefStruct M3(ref RefStruct s1) + { + return ref M1(ref s1, ref s1); + } + } + """; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (14,20): error CS8347: Cannot use a result of 'Repro.M1(ref RefStruct, ref RefStruct)' in this context because it may expose variables referenced by parameter 's2' outside of their declaration scope + // return ref M1(ref s1, ref s2); // 1 + Diagnostic(ErrorCode.ERR_EscapeCall, "M1(ref s1, ref s2)").WithArguments("Repro.M1(ref RefStruct, ref RefStruct)", "s2").WithLocation(14, 20), + // (14,35): error CS8168: Cannot return local 's2' by reference because it is not a ref local + // return ref M1(ref s1, ref s2); // 1 + Diagnostic(ErrorCode.ERR_RefReturnLocal, "s2").WithArguments("s2").WithLocation(14, 35) + ); + } + + [Fact] + public void RefStructProperty_01() + { + var source = +@" +class C + where Rint : allows ref struct + where Robject : allows ref struct +{ + Robject this[Rint r] => default; + static Robject F1(C c) + { + int i = 1; + var r1 = GetRint(ref i); + return c[r1]; // 1 + } + static Robject F2(C c) + { + var r2 = GetRint(); + return c[r2]; + } + static Rint GetRint(ref int x) => throw null; + static Rint GetRint() => throw null; +}"; + + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyDiagnostics( + // (11,16): error CS8347: Cannot use a result of 'C.this[Rint]' in this context because it may expose variables referenced by parameter 'r' outside of their declaration scope + // return c[r1]; // 1 + Diagnostic(ErrorCode.ERR_EscapeCall, "c[r1]").WithArguments("C.this[Rint]", "r").WithLocation(11, 16), + // (11,18): error CS8352: Cannot use variable 'r1' in this context because it may expose referenced variables outside of their declaration scope + // return c[r1]; // 1 + Diagnostic(ErrorCode.ERR_EscapeVariable, "r1").WithArguments("r1").WithLocation(11, 18) + ); + } + + [Fact] + public void MethodArgumentsMustMatch_08() + { + var source = +@" +using static Helper; +class Helper +{ + public static void F0(__arglist) { } +} + +class Program + where R : allows ref struct +{ + static void F1() + { + var x = GetR(); + int i = 1; + var y = GetR(ref i); + F0(__arglist(ref x)); // 1 + F0(__arglist(ref y)); + F0(__arglist(ref x, ref x)); // 2 + F0(__arglist(ref x, ref y)); // 3 + F0(__arglist(ref y, ref x)); // 4 + F0(__arglist(ref y, ref y)); + } + static R GetR(ref int x) => throw null; + static R GetR() => throw null; +}"; + + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics( + // (19,9): error CS8350: This combination of arguments to 'Helper.F0(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope + // F0(__arglist(ref x, ref y)); // 3 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(__arglist(ref x, ref y))").WithArguments("Helper.F0(__arglist)", "__arglist").WithLocation(19, 9), + // (19,33): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope + // F0(__arglist(ref x, ref y)); // 3 + Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(19, 33), + // (20,9): error CS8350: This combination of arguments to 'Helper.F0(__arglist)' is disallowed because it may expose variables referenced by parameter '__arglist' outside of their declaration scope + // F0(__arglist(ref y, ref x)); // 4 + Diagnostic(ErrorCode.ERR_CallArgMixing, "F0(__arglist(ref y, ref x))").WithArguments("Helper.F0(__arglist)", "__arglist").WithLocation(20, 9), + // (20,26): error CS8352: Cannot use variable 'y' in this context because it may expose referenced variables outside of their declaration scope + // F0(__arglist(ref y, ref x)); // 4 + Diagnostic(ErrorCode.ERR_EscapeVariable, "y").WithArguments("y").WithLocation(20, 26) + ); + } + + [Fact] + public void IsPatternMatchingDoesNotCopyEscapeScopes_05() + { + CreateCompilation(@" +using System; +public interface IR where R : IR, allows ref struct +{ + public R RProp {get;} + public S SProp {get;} + public abstract static implicit operator R(Span span); +} +public struct S where R : IR, allows ref struct +{ + public R RProp => throw null; + public S SProp => throw null; +} +public class C where R : IR, allows ref struct +{ + public void M1(ref R r, ref S s) + { + R outer = stackalloc int[100]; + if (outer is { RProp.RProp: var rr0 }) r = rr0; // error + if (outer is { SProp.RProp: var sr0 }) r = sr0; // OK + if (outer is { SProp.SProp: var ss0 }) s = ss0; // OK + if (outer is { RProp.SProp: var rs0 }) s = rs0; // OK + if (outer is { RProp: { RProp: var rr1 }}) r = rr1; // error + if (outer is { SProp: { RProp: var sr1 }}) r = sr1; // OK + if (outer is { SProp: { SProp: var ss1 }}) s = ss1; // OK + if (outer is { RProp: { SProp: var rs1 }}) s = rs1; // OK + } +}", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).VerifyDiagnostics( + // (19,52): error CS8352: Cannot use variable 'rr0' in this context because it may expose referenced variables outside of their declaration scope + // if (outer is { RProp.RProp: var rr0 }) r = rr0; // error + Diagnostic(ErrorCode.ERR_EscapeVariable, "rr0").WithArguments("rr0").WithLocation(19, 52), + // (23,56): error CS8352: Cannot use variable 'rr1' in this context because it may expose referenced variables outside of their declaration scope + // if (outer is { RProp: { RProp: var rr1 }}) r = rr1; // error + Diagnostic(ErrorCode.ERR_EscapeVariable, "rr1").WithArguments("rr1").WithLocation(23, 56) + ); + } + + [Fact] + public void CasePatternMatchingDoesNotCopyEscapeScopes_02() + { + CreateCompilation(@" +using System; +public interface IR where R : IR, allows ref struct +{ + public R Prop {get;} + public void Deconstruct(out R X, out R Y); + public abstract static implicit operator R(Span span); +} +public class C where R : struct, IR, allows ref struct +{ + public R M1() + { + R outer = stackalloc int[100]; + switch (outer) + { + case { Prop: var x }: return x; // error 1 + } + } + public R M2() + { + R outer = stackalloc int[100]; + switch (outer) + { + case { Prop: R x }: return x; // error 2 + } + } + public R M3() + { + R outer = stackalloc int[100]; + switch (outer) + { + case (var x, var y): return x; // error 3 + } + } + public R M4() + { + R outer = stackalloc int[100]; + switch (outer) + { + case (R x, R y): return x; // error 4 + } + } + public R M5() + { + R outer = stackalloc int[100]; + switch (outer) + { + case var (x, y): return x; // error 5 + } + } + public R M6() + { + R outer = stackalloc int[100]; + switch (outer) + { + case { } x: return x; // error 6 + } + } + public R M7() + { + R outer = stackalloc int[100]; + switch (outer) + { + case (_, _) x: return x; // error 7 + } + } +} +", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).VerifyDiagnostics( + // (16,42): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case { Prop: var x }: return x; // error 1 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(16, 42), + // (24,40): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case { Prop: R x }: return x; // error 2 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(24, 40), + // (32,41): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case (var x, var y): return x; // error 3 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(32, 41), + // (40,37): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case (R x, R y): return x; // error 4 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(40, 37), + // (48,37): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case var (x, y): return x; // error 5 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(48, 37), + // (56,32): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case { } x: return x; // error 6 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(56, 32), + // (64,35): error CS8352: Cannot use variable 'x' in this context because it may expose referenced variables outside of their declaration scope + // case (_, _) x: return x; // error 7 + Diagnostic(ErrorCode.ERR_EscapeVariable, "x").WithArguments("x").WithLocation(64, 35) + ); + } + + [Fact] + public void RefLikeScopeEscapeThis() + { + var text = @" + using System; + class Program where S1 : IS1, allows ref struct + { + static void Main() + { + Span outer = default; + + S1 x = MayWrap(ref outer); + + { + Span inner = stackalloc int[1]; + + // valid + x = S1.NotSlice(1); + + // valid + x = MayWrap(ref outer).Slice(1); + + // error + x = MayWrap(ref inner).Slice(1); + } + } + + static S1 MayWrap(ref Span arg) + { + return default; + } + } + + interface IS1 where S1 : IS1, allows ref struct + { + public abstract static S1 NotSlice(int x); + + public S1 Slice(int x); + } +"; + var comp = CreateCompilation(text, targetFramework: TargetFramework.Net60, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // (3,50): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // class Program where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(3, 50), + // (3,50): error CS9240: Target runtime doesn't support by-ref-like generics. + // class Program where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(3, 50), + // (31,50): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // interface IS1 where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(31, 50), + // (31,50): error CS9240: Target runtime doesn't support by-ref-like generics. + // interface IS1 where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(31, 50), + // (33,35): error CS8703: The modifier 'abstract' is not valid for this item in C# 10.0. Please use language version '11.0' or greater. + // public abstract static S1 NotSlice(int x); + Diagnostic(ErrorCode.ERR_InvalidModifierForLanguageVersion, "NotSlice").WithArguments("abstract", "10.0", "11.0").WithLocation(33, 35), + // (15,21): error CS8936: Feature 'static abstract members in interfaces' is not available in C# 10.0. Please use language version 11.0 or greater. + // x = S1.NotSlice(1); + Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "S1").WithArguments("static abstract members in interfaces", "11.0").WithLocation(15, 21), + // (21,33): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // x = MayWrap(ref inner).Slice(1); + Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(21, 33), + // (21,21): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope + // x = MayWrap(ref inner).Slice(1); + Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span)", "arg").WithLocation(21, 21) + ); + } + + [Fact] + public void RefLikeScopeEscapeThisRef() + { + var text = @" +using System; +class Program where S1 : IS1, allows ref struct +{ + static void Main() + { + Span outer = default; + + ref S1 x = ref MayWrap(ref outer)[0]; + + { + Span inner = stackalloc int[1]; + + // valid + x[0] = MayWrap(ref outer).Slice(1)[0]; + + // error, technically rules for this case can be relaxed, + // but ref-like typed ref-returning properties are nearly impossible to implement in a useful way + // + x[0] = MayWrap(ref inner).Slice(1)[0]; + + // error, technically rules for this case can be relaxed, + // but ref-like typed ref-returning properties are nearly impossible to implement in a useful way + // + x[x] = MayWrap(ref inner).Slice(1)[0]; + + // error + x.ReturnsRefArg(ref x) = MayWrap(ref inner).Slice(1)[0]; + } + } + + static S1 MayWrap(ref Span arg) + { + return default; + } +} + +interface IS1 where S1 : IS1, allows ref struct +{ + public ref S1 this[int i] {get;} + + public ref S1 this[S1 i] {get;} + + public ref S1 ReturnsRefArg(ref S1 arg); + + public S1 Slice(int x); +} +"; + var comp = CreateCompilation(new[] { text, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net60, parseOptions: TestOptions.Regular10); + comp.VerifyDiagnostics( + // 0.cs(38,46): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // interface IS1 where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(38, 46), + // 0.cs(38,46): error CS9240: Target runtime doesn't support by-ref-like generics. + // interface IS1 where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(38, 46), + // 0.cs(3,46): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // class Program where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(3, 46), + // 0.cs(3,46): error CS9240: Target runtime doesn't support by-ref-like generics. + // class Program where S1 : IS1, allows ref struct + Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportByRefLikeGenerics, "ref struct").WithLocation(3, 46), + // 0.cs(20,32): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // x[0] = MayWrap(ref inner).Slice(1)[0]; + Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(20, 32), + // 0.cs(20,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope + // x[0] = MayWrap(ref inner).Slice(1)[0]; + Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span)", "arg").WithLocation(20, 20), + // 0.cs(25,32): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // x[x] = MayWrap(ref inner).Slice(1)[0]; + Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(25, 32), + // 0.cs(25,20): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope + // x[x] = MayWrap(ref inner).Slice(1)[0]; + Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span)", "arg").WithLocation(25, 20), + // 0.cs(28,50): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // x.ReturnsRefArg(ref x) = MayWrap(ref inner).Slice(1)[0]; + Diagnostic(ErrorCode.ERR_EscapeVariable, "inner").WithArguments("inner").WithLocation(28, 50), + // 0.cs(28,38): error CS8347: Cannot use a result of 'Program.MayWrap(ref Span)' in this context because it may expose variables referenced by parameter 'arg' outside of their declaration scope + // x.ReturnsRefArg(ref x) = MayWrap(ref inner).Slice(1)[0]; + Diagnostic(ErrorCode.ERR_EscapeCall, "MayWrap(ref inner)").WithArguments("Program.MayWrap(ref System.Span)", "arg").WithLocation(28, 38) + ); + } + + [Fact] + public void RefAssignValueScopeMismatch_05() + { + var source = +@" +class Program where S : allows ref struct +{ + static S F() + { + S s1 = default; + scoped ref S r1 = ref s1; + int i = 0; + S s2 = GetS(ref i); + ref S r2 = ref s2; + r2 = ref r1; // 1 + r2 = s2; + return s1; + } + + static S GetS(ref int i) => throw null; +} +"; + var comp = CreateCompilation(source, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp.VerifyEmitDiagnostics( + // (11,9): error CS9096: Cannot ref-assign 'r1' to 'r2' because 'r1' has a wider value escape scope than 'r2' allowing assignment through 'r2' of values with narrower escapes scopes than 'r1'. + // r2 = ref r1; // 1 + Diagnostic(ErrorCode.ERR_RefAssignValEscapeWider, "r2 = ref r1").WithArguments("r2", "r1").WithLocation(11, 9) + ); + } + + [Fact] + public void RefLikeObjInitializers1() + { + var text = @" + using System; + + class Program where S2 : IS2, new(), allows ref struct + { + static void Main() + { + } + + static S2 Test1() + { + S1 outer = default; + S1 inner = stackalloc int[1]; + + var x1 = new S2() { Field1 = outer, Field2 = inner }; + + // error + return x1; + } + + static S2 Test2() + { + S1 outer = default; + S1 inner = stackalloc int[1]; + + var x2 = new S2() { Field1 = inner, Field2 = outer }; + + // error + return x2; + } + + static S2 Test3() + { + S1 outer = default; + S1 inner = stackalloc int[1]; + + var x3 = new S2() { Field1 = outer, Field2 = outer }; + + // ok + return x3; + } + } + + public ref struct S1 + { + public static implicit operator S1(Span o) => default; + } + + public interface IS2 + { + public S1 Field1 {get;set;} + public S1 Field2 {get;set;} + } + + namespace System + { + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } + } +"; + CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).VerifyEmitDiagnostics( + // (18,20): error CS8352: Cannot use variable 'x1' in this context because it may expose referenced variables outside of their declaration scope + // return x1; + Diagnostic(ErrorCode.ERR_EscapeVariable, "x1").WithArguments("x1").WithLocation(18, 20), + // (29,20): error CS8352: Cannot use variable 'x2' in this context because it may expose referenced variables outside of their declaration scope + // return x2; + Diagnostic(ErrorCode.ERR_EscapeVariable, "x2").WithArguments("x2").WithLocation(29, 20) + ); + } + + [Fact] + public void RefLikeObjInitializersIndexer1() + { + var text = @" +using System; + +class Program where S2 : IS2, new(), allows ref struct +{ + static void Main() + { + } + + static S2 Test1() + { + S1 outer = default; + S1 inner = stackalloc int[1]; + + var x1 = new S2() { [inner] = outer, Field2 = outer }; + + // error + return x1; + } + + static S2 Test2() + { + S1 outer = default; + S1 inner = stackalloc int[1]; + + S2 result; + + // error + result = new S2() { [outer] = inner, Field2 = outer }; + + return result; + } + + static S2 Test3() + { + S1 outer = default; + S1 inner = stackalloc int[1]; + + var x3 = new S2() { [outer] = outer, Field2 = outer }; + + // ok + return x3; + } +} + +public ref struct S1 +{ + public static implicit operator S1(Span o) => default; +} + +public interface IS2 +{ + public S1 this[S1 i] {get;set;} + public S1 Field2 {get;set;} +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics).VerifyEmitDiagnostics( + // (18,16): error CS8352: Cannot use variable 'x1' in this context because it may expose referenced variables outside of their declaration scope + // return x1; + Diagnostic(ErrorCode.ERR_EscapeVariable, "x1").WithArguments("x1").WithLocation(18, 16), + // (29,29): error CS8352: Cannot use variable 'inner' in this context because it may expose referenced variables outside of their declaration scope + // result = new S2() { [outer] = inner, Field2 = outer }; + Diagnostic(ErrorCode.ERR_EscapeVariable, "[outer] = inner").WithArguments("inner").WithLocation(29, 29) + ); + } + + [Fact] + public void NullCheck_01() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : allows ref struct + { + return value == null; + } + + public static bool Test2(T value) + where T : allows ref struct + { + return null == value; + } + + public static bool Test3(T value) + where T : allows ref struct + { + return value != null; + } + + public static bool Test4(T value) + where T : allows ref struct + { + return null != value; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + System.Console.Write(Helper.Test1(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new Program())); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "False False True True True True False False False False True True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test2(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test3(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test4(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + } + + [Fact] + public void NullCheck_02() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : allows ref struct + { + return value is null; + } + + public static bool Test3(T value) + where T : allows ref struct + { + return value is not null; + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + System.Console.Write(Helper.Test1(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new Program())); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "False True True False False True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test3(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + } + + [Fact] + public void NullCheck_03() + { + var src = @" +public class Helper +{ + public static bool Test1(T value, object o) + where T : allows ref struct + { + return value == o; + } + + public static bool Test2(T value, object o) + where T : allows ref struct + { + return o == value; + } + + public static bool Test3(T value, object o) + where T : allows ref struct + { + return value != o; + } + + public static bool Test4(T value, object o) + where T : allows ref struct + { + return o != value; + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (7,16): error CS0019: Operator '==' cannot be applied to operands of type 'T' and 'object' + // return value == o; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "value == o").WithArguments("==", "T", "object").WithLocation(7, 16), + // (13,16): error CS0019: Operator '==' cannot be applied to operands of type 'object' and 'T' + // return o == value; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "o == value").WithArguments("==", "object", "T").WithLocation(13, 16), + // (19,16): error CS0019: Operator '!=' cannot be applied to operands of type 'T' and 'object' + // return value != o; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "value != o").WithArguments("!=", "T", "object").WithLocation(19, 16), + // (25,16): error CS0019: Operator '!=' cannot be applied to operands of type 'object' and 'T' + // return o != value; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "o != value").WithArguments("!=", "object", "T").WithLocation(25, 16) + ); + } + + [Fact] + public void NullCheck_04() + { + var src = @" +public class Helper +{ + const object o = null; + + public static bool Test1(T value) + where T : allows ref struct + { + return value == o; + } + + public static bool Test2(T value) + where T : allows ref struct + { + return o == value; + } + + public static bool Test3(T value) + where T : allows ref struct + { + return value != o; + } + + public static bool Test4(T value) + where T : allows ref struct + { + return o != value; + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (9,16): error CS0019: Operator '==' cannot be applied to operands of type 'T' and 'object' + // return value == o; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "value == o").WithArguments("==", "T", "object").WithLocation(9, 16), + // (15,16): error CS0019: Operator '==' cannot be applied to operands of type 'object' and 'T' + // return o == value; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "o == value").WithArguments("==", "object", "T").WithLocation(15, 16), + // (21,16): error CS0019: Operator '!=' cannot be applied to operands of type 'T' and 'object' + // return value != o; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "value != o").WithArguments("!=", "T", "object").WithLocation(21, 16), + // (27,16): error CS0019: Operator '!=' cannot be applied to operands of type 'object' and 'T' + // return o != value; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "o != value").WithArguments("!=", "object", "T").WithLocation(27, 16) + ); + } + + [Fact] + public void NullCheck_05() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : allows ref struct + { + if (value == null) + { + return true; + } + else + { + return false; + } + } + + public static bool Test2(T value) + where T : allows ref struct + { + if (null == value) + { + return true; + } + else + { + return false; + } + } + + public static bool Test3(T value) + where T : allows ref struct + { + if (value != null) + { + return true; + } + else + { + return false; + } + } + + public static bool Test4(T value) + where T : allows ref struct + { + if (null != value) + { + return true; + } + else + { + return false; + } + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + System.Console.Write(Helper.Test1(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new Program())); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "False False True True True True False False False False True True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test2(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test3(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test4(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + } + + [Fact] + public void NullCheck_06() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : struct, allows ref struct + { + return value == null; + } + + public static bool Test2(T value) + where T : struct, allows ref struct + { + return null == value; + } + + public static bool Test3(T value) + where T : struct, allows ref struct + { + return value != null; + } + + public static bool Test4(T value) + where T : struct, allows ref struct + { + return null != value; + } +} + +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (7,16): error CS0019: Operator '==' cannot be applied to operands of type 'T' and '' + // return value == null; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "value == null").WithArguments("==", "T", "").WithLocation(7, 16), + // (13,16): error CS0019: Operator '==' cannot be applied to operands of type '' and 'T' + // return null == value; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "null == value").WithArguments("==", "", "T").WithLocation(13, 16), + // (19,16): error CS0019: Operator '!=' cannot be applied to operands of type 'T' and '' + // return value != null; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "value != null").WithArguments("!=", "T", "").WithLocation(19, 16), + // (25,16): error CS0019: Operator '!=' cannot be applied to operands of type '' and 'T' + // return null != value; + Diagnostic(ErrorCode.ERR_BadBinaryOps, "null != value").WithArguments("!=", "", "T").WithLocation(25, 16) + ); + } + + [Fact] + public void NullCheck_07() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : allows ref struct + { + return !(value != null); + } + + public static bool Test2(T value) + where T : allows ref struct + { + return !(null != value); + } + + public static bool Test3(T value) + where T : allows ref struct + { + return !(value == null); + } + + public static bool Test4(T value) + where T : allows ref struct + { + return !(null == value); + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + System.Console.Write(Helper.Test1(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new Program())); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "False False True True True True False False False False True True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test2(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test3(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test4(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + } + + [Fact] + public void NullCheck_08() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : allows ref struct + { + return !(value is not null); + } + + public static bool Test3(T value) + where T : allows ref struct + { + return !(value is null); + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + System.Console.Write(Helper.Test1(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new Program())); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "False True True False False True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test3(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + } + + [Fact] + public void NullCheck_09() + { + var src = @" +public class Helper +{ + public static bool Test1(T value) + where T : allows ref struct + { + if (!(value != null)) + { + return true; + } + else + { + return false; + } + } + + public static bool Test2(T value) + where T : allows ref struct + { + if (!(null != value)) + { + return true; + } + else + { + return false; + } + } + + public static bool Test3(T value) + where T : allows ref struct + { + if (!(value == null)) + { + return true; + } + else + { + return false; + } + } + + public static bool Test4(T value) + where T : allows ref struct + { + if (!(null == value)) + { + return true; + } + else + { + return false; + } + } +} + +ref struct S +{ +} + +class Program +{ + static void Main() + { + System.Console.Write(Helper.Test1(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new S())); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(null)); + System.Console.Write(' '); + System.Console.Write(Helper.Test1(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test2(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test3(new Program())); + System.Console.Write(' '); + System.Console.Write(Helper.Test4(new Program())); + } +} +"; + + var comp = CreateCompilation(src, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "False False True True True True False False False False True True" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("Helper.Test1(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test2(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brtrue.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test3(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + + verifier.VerifyIL("Helper.Test4(T)", +@" +{ + // Code size 12 (0xc) + .maxstack 1 + IL_0000: ldarg.0 + IL_0001: box ""T"" + IL_0006: brfalse.s IL_000a + IL_0008: ldc.i4.1 + IL_0009: ret + IL_000a: ldc.i4.0 + IL_000b: ret +} +"); + } + + [Fact] + public void NullCoalescingAssignment_01() + { + var text = @" +class Program +{ + static void Test() + where T : I1, allows ref struct + { + var x = new C(); + System.Console.Write(x.PT.P); + x._pT.P++; + System.Console.Write("" ""); + System.Console.Write(x.PT.P); + } + + static void Main() + { + Test(); + System.Console.Write("" ""); + Test(); + System.Console.Write("" ""); + Test(); + } +} + +ref struct C + where T : I1, allows ref struct +{ + public T _pT; + public T PT + { + get + { + return _pT ??= T.Create(); + } + } +} + +public ref struct S1 : I1 +{ + public int P {get;set;} + public static S1 Create() => throw null; +} + +public struct S2 : I1 +{ + public int P {get;set;} + public static S2 Create() => throw null; +} + +public class C3 : I1 +{ + public int P {get;set;} + public static C3 Create() => new C3(); +} + +public interface I1 + where T : I1, allows ref struct +{ + public int P {get;set;} + + abstract static T Create(); +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "0 1 0 1 0 1" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify.WithILVerifyMessage( +@"[get_PT]: Call not allowed on abstract methods. { Offset = 0x16 } +[get_PT]: Missing callvirt following constrained prefix. { Offset = 0x16 }") : + Verification.Skipped).VerifyDiagnostics(); + + verifier.VerifyIL("C.PT.get", @" +{ + // Code size 38 (0x26) + .maxstack 3 + .locals init (T V_0, + T V_1) + IL_0000: ldarg.0 + IL_0001: ldfld ""T C._pT"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: box ""T"" + IL_000d: brtrue.s IL_0024 + IL_000f: ldarg.0 + IL_0010: constrained. ""T"" + IL_0016: call ""T I1.Create()"" + IL_001b: dup + IL_001c: stloc.1 + IL_001d: stfld ""T C._pT"" + IL_0022: ldloc.1 + IL_0023: ret + IL_0024: ldloc.0 + IL_0025: ret +} +"); + } + + [Fact] + public void NullCoalescingAssignment_02() + { + var text = @" +ref struct C + where T : struct, I1, allows ref struct +{ + public T _pT; + public T PT + { + get + { + return _pT ??= T.Create(); + } + } +} + +public interface I1 + where T : I1, allows ref struct +{ + public int P {get;set;} + + abstract static T Create(); +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (10,20): error CS0019: Operator '??=' cannot be applied to operands of type 'T' and 'T' + // return _pT ??= T.Create(); + Diagnostic(ErrorCode.ERR_BadBinaryOps, "_pT ??= T.Create()").WithArguments("??=", "T", "T").WithLocation(10, 20) + ); + } + + [Fact] + public void NullCoalescingAssignment_03() + { + var comp = CreateCompilation(@" +using System; +class C +{ + void M() where T : allows ref struct + { + T s1 = GetT(stackalloc int[1]); + T s2 = GetT(new Span()); + + s2 = (s2 ??= GetT(new Span())); + s2 = (s1 ??= s2); + } + + T GetT(Span s) where T : allows ref struct => default; +} +", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (11,15): error CS8352: Cannot use variable 's1' in this context because it may expose referenced variables outside of their declaration scope + // s2 = (s1 ??= s2); + Diagnostic(ErrorCode.ERR_EscapeVariable, "s1 ??= s2").WithArguments("s1").WithLocation(11, 15) + ); + } + + [Fact] + public void NullCoalescingAssignment_04() + { + var comp = CreateCompilation(@" +class C +{ + static T F() where T : allows ref struct + { + scoped T s1 = default; + T s2 = default; + s2 ??= s1; + return s2; + } +} +", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void NullCoalescingAssignment_05() + { + var comp = CreateCompilation(@" +class C +{ + static T F() where T : allows ref struct + { + T s1 = default; + T s2 = default; + s2 ??= s1; + return s2; + } +} +", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyEmitDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void ObjectCreation_01(bool addStructConstraint) + { + var text = @" +class Program +{ + static T Test() + where T : " + (addStructConstraint ? "struct, I1" : "I1, new()") + @", allows ref struct + { + return new T() { P = 123 }; + } + + static void Main() + { + System.Console.Write(Test().P); + } +} + +public ref struct S : I1 +{ + public int P {get;set;} +} + +public interface I1 +{ + public int P {get;set;} +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void ObjectCreation_02(bool addStructConstraint) + { + var text = @" +class Program +{ + static T Test() + where T : " + (addStructConstraint ? "struct, I1" : "I1, new()") + @", allows ref struct + { + return new T() { C = { P = 123 } }; + } + + static void Main() + { + System.Console.Write(Test().C.P); + } +} + +public class C +{ + public int P {get;set;} +} + +public ref struct S : I1 +{ + private C _c; + public C C + { + get + { + return _c ??= new C(); + } + } +} + +public interface I1 +{ + public C C {get;} +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void ObjectCreation_03() + { + var text = @" +class Program +{ + static C Test() + where T : I1, allows ref struct + { + return new C() { PT = { P = 123 } }; + } + + static void Main() + { + System.Console.Write(Test().PT.P); + System.Console.Write("" ""); + System.Console.Write(Test().PT.P); + System.Console.Write("" ""); + System.Console.Write(Test().PT.P); + } +} + +ref struct C + where T : I1, allows ref struct +{ + private T _pT; + public T PT + { + get + { + return _pT ??= T.Create(); + } + } +} + +public ref struct S1 : I1 +{ + public int P {get;set;} + public static S1 Create() => throw null; +} + +public struct S2 : I1 +{ + public int P {get;set;} + public static S2 Create() => throw null; +} + +public class C3 : I1 +{ + public int P {get;set;} + public static C3 Create() => new C3(); +} + +public interface I1 + where T : I1, allows ref struct +{ + public int P {get;set;} + abstract static T Create(); +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "0 0 123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify.WithILVerifyMessage( +@"[Test]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x20 } +[get_PT]: Call not allowed on abstract methods. { Offset = 0x16 } +[get_PT]: Missing callvirt following constrained prefix. { Offset = 0x16 }") : + Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void ObjectCreation_04() + { + var text = @" +class Program +{ + static C Test() + where T : struct, I1, allows ref struct + { + return new C() { PT = { P = 123 } }; + } + + static void Main() + { + System.Console.Write(Test().PT.P); + } +} + +ref struct C + where T : struct, I1, allows ref struct +{ + public T PT {get;set;} +} + +public ref struct S : I1 +{ + public int P {get;set;} +} + +public interface I1 +{ + public int P {get;set;} +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + comp.VerifyDiagnostics( + // (7,29): error CS1918: Members of property 'C.PT' of type 'T' cannot be assigned with an object initializer because it is of a value type + // return new C() { PT = { P = 123 } }; + Diagnostic(ErrorCode.ERR_ValueTypePropertyInObjectInitializer, "PT").WithArguments("C.PT", "T").WithLocation(7, 29) + ); + } + + [Theory] + [CombinatorialData] + public void ObjectCreation_05(bool addStructConstraint) + { + var text = @" +class Program +{ + static T Test() + where T : " + (addStructConstraint ? "struct, I1" : "I1, new()") + @", allows ref struct + { + return new T() { 100, 20, 3 }; + } + + static void Main() + { + System.Console.Write(Test().P); + System.Console.Write("" ""); + System.Console.Write((new S() { 200, 40, 6 }).P); + System.Console.Write("" ""); + System.Console.Write((new S2() { 300, 60, 9 }).P); + } +} + +public ref struct S : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; +} + +public struct S2 : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; +} + +public interface I1 : System.Collections.IEnumerable +{ + public void Add(int x); +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123 246 369" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void ObjectCreation_06(bool addStructConstraint) + { + var text = @" +class Program +{ + static T Test() + where T : " + (addStructConstraint ? "struct, I1" : "I1, new()") + @", allows ref struct + { + return new T() { C = { 100, 20, 3 } }; + } + + static void Main() + { + System.Console.Write(Test().C.P); + } +} + +public class C : System.Collections.IEnumerable +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; +} + +public ref struct S : I1 +{ + private C _c; + public C C + { + get + { + return _c ??= new C(); + } + } +} + +public interface I1 +{ + public C C {get;} +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void ObjectCreation_07() + { + var text = @" +class Program +{ + static C Test() + where T : I1, allows ref struct + { + return new C() { PT = { 100, 20, 3 } }; + } + + static void Main() + { + System.Console.Write(Test().PT.P); + System.Console.Write("" ""); + System.Console.Write(Test().PT.P); + System.Console.Write("" ""); + System.Console.Write(Test().PT.P); + } +} + +ref struct C + where T : I1, allows ref struct +{ + private T _pT; + public T PT + { + get + { + return _pT ??= T.Create(); + } + } +} + +public ref struct S1 : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; + public static S1 Create() => default; +} + +public struct S2 : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; + public static S2 Create() => default; +} + +public class C3 : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; + public static C3 Create() => new C3(); +} + +public interface I1 : System.Collections.IEnumerable + where T : I1, allows ref struct +{ + public void Add(int x); + abstract static T Create(); +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "0 0 123" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? + Verification.FailsILVerify.WithILVerifyMessage( +@"[Test]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x4d } +[get_PT]: Call not allowed on abstract methods. { Offset = 0x16 } +[get_PT]: Missing callvirt following constrained prefix. { Offset = 0x16 } +[Create]: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator. { Offset = 0x9 }") : + Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void ObjectCreation_08() + { + var text = @" +class Program +{ + static C Test() + where T : struct, I1, allows ref struct + { + return new C() { PT = { 100, 20, 3 } }; + } +} + +ref struct C + where T : struct, I1, allows ref struct +{ + public T PT {get;set;} +} + +public interface I1 : System.Collections.IEnumerable +{ + public void Add(int x); +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + comp.VerifyDiagnostics( + // (7,29): error CS1918: Members of property 'C.PT' of type 'T' cannot be assigned with an object initializer because it is of a value type + // return new C() { PT = { P = 123 } }; + Diagnostic(ErrorCode.ERR_ValueTypePropertyInObjectInitializer, "PT").WithArguments("C.PT", "T").WithLocation(7, 29) + ); + } + + [Fact] + public void ObjectCreation_LanguageVersion_05() + { + var text1 = @" +public ref struct S : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; +} + +public struct S2 : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; +} + +public interface I1 : System.Collections.IEnumerable +{ + public void Add(int x); +} +"; + var comp1 = CreateCompilation(text1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var text2 = @" +class Program +{ + static T Test() + where T : I1, new(), allows ref struct + { + return new T() { 100, 20, 3 }; + } + + static void Main() + { + System.Console.Write((new S() { 200, 40, 6 }).P); + } +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + + var comp2 = CreateCompilation(text2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (5,37): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : I1, new(), allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(5, 37), + // (12,39): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // System.Console.Write((new S() { 200, 40, 6 }).P); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "{ 200, 40, 6 }").WithArguments("ref struct interfaces").WithLocation(12, 39), + // (20,62): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static T CreateInstance() where T : allows ref struct => default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(20, 62) + ); + + comp2 = CreateCompilation(text2 + text1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (5,37): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : I1, new(), allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(5, 37), + // (20,62): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static T CreateInstance() where T : allows ref struct => default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(20, 62), + // (24,23): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public ref struct S : I1 + Diagnostic(ErrorCode.ERR_FeatureInPreview, "I1").WithArguments("ref struct interfaces").WithLocation(24, 23) + ); + + comp2 = CreateCompilation(text2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(text2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + + var text3 = @" +class Program +{ + static void Main() + { + System.Console.Write((new S2() { 200, 40, 6 }).P); + } +} +"; + var comp3 = CreateCompilation(text3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(text3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp3.VerifyEmitDiagnostics(); + + comp3 = CreateCompilation(text3, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp3.VerifyEmitDiagnostics(); + } + + [Fact] + public void ObjectCreation_LanguageVersion_07() + { + var text1 = @" +public ref struct C + where T : I1, allows ref struct +{ + public T PT => throw null; +} + +public interface I1 : System.Collections.IEnumerable + where T : I1, allows ref struct +{ + public void Add(int x); + abstract static T Create(); +} +"; + var comp1 = CreateCompilation(text1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var text2 = @" +class Program +{ + static C Test() + where T : I1, allows ref struct + { + return new C() { PT = { 100, 20, 3 } }; + } +} +"; + + var comp2 = CreateCompilation(text2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (4,17): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static C Test() + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Test").WithArguments("ref struct interfaces").WithLocation(4, 17), + // (4,22): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // static C Test() + Diagnostic(ErrorCode.ERR_FeatureInPreview, "T").WithArguments("ref struct interfaces").WithLocation(4, 22), + // (5,33): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : I1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(5, 33), + // (7,22): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // return new C() { PT = { 100, 20, 3 } }; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "T").WithArguments("ref struct interfaces").WithLocation(7, 22) + ); + + comp2 = CreateCompilation(text2 + text1, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.Regular12); + comp2.VerifyEmitDiagnostics( + // (5,33): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : I1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(5, 33), + // (12,29): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : I1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(12, 29), + // (18,29): error CS8652: The feature 'ref struct interfaces' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // where T : I1, allows ref struct + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ref struct").WithArguments("ref struct interfaces").WithLocation(18, 29) + ); + + comp2 = CreateCompilation(text2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, parseOptions: TestOptions.RegularNext); + comp2.VerifyEmitDiagnostics(); + + comp2 = CreateCompilation(text2, references: [comp1.ToMetadataReference()], targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + comp2.VerifyEmitDiagnostics(); + } + + [Theory] + [CombinatorialData] + public void CollectionExpressions_01(bool addStructConstraint) + { + var text = @" +class Program +{ + static T Test() + where T : " + (addStructConstraint ? "struct, I1" : "I1, new()") + @", allows ref struct + { + return [ 100, 20, 3 ]; + } + + static void Main() + { + System.Console.Write(Test().P); + System.Console.Write("" ""); + System.Console.Write(((S)([ 200, 40, 6 ])).P); + } +} + +public ref struct S : I1 +{ + public int P {get;set;} + public void Add(int x) => P += x; + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; +} + +public interface I1 : System.Collections.IEnumerable +{ + public void Add(int x); +} + +namespace System +{ + public class Activator + { + public static T CreateInstance() where T : allows ref struct => default; + } +} +"; + + var comp = CreateCompilation(text, targetFramework: s_targetFrameworkSupportingByRefLikeGenerics, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify( + comp, + expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "123 246" : null, + verify: ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped).VerifyDiagnostics(); + } + + [Fact] + public void NoPiaEmbedding() + { + string pia = @" +using System; +using System.Runtime.InteropServices; + +[assembly: ImportedFromTypeLib(""GeneralPIA.dll"")] +[assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] + +[ComImport()] +[Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58278"")] +public interface ITest29 +{ + void M21() where T1 : allows ref struct; +} +"; + + var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, assemblyName: "Pia", targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + string consumer = @" +class UsePia +{ + public static void Main() + { + } +} + +interface UsePia5 : ITest29 +{ +} +"; + + var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseExe, + references: [piaCompilation.ToMetadataReference(embedInteropTypes: true)], + targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + var compilation2 = CreateCompilation(consumer, options: TestOptions.ReleaseExe, + references: [piaCompilation.EmitToImageReference(embedInteropTypes: true)], + targetFramework: s_targetFrameworkSupportingByRefLikeGenerics); + + System.Action metadataValidator = + delegate (ModuleSymbol module) + { + ((PEModuleSymbol)module).Module.PretendThereArentNoPiaLocalTypes(); + + var itest29 = (PENamedTypeSymbol)module.GlobalNamespace.GetTypeMembers("ITest29").Single(); + Assert.Equal(TypeKind.Interface, itest29.TypeKind); + + var m21 = (PEMethodSymbol)itest29.GetMembers("M21").Single(); + + var t1 = m21.TypeParameters[0]; + Assert.Equal("T1", t1.Name); + Assert.True(t1.AllowsRefLikeType); + AssertEx.Equal("void ITest29.M21() where T1 : allows ref struct", m21.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)); + }; + + CompileAndVerify(compilation1, symbolValidator: metadataValidator, verify: Verification.Skipped).VerifyDiagnostics(); + + CompileAndVerify(compilation2, symbolValidator: metadataValidator, verify: Verification.Skipped).VerifyDiagnostics(); + } + } +} diff --git a/src/Compilers/CSharp/Test/Emit3/RefUnsafeInIteratorAndAsyncTests.cs b/src/Compilers/CSharp/Test/Emit3/RefUnsafeInIteratorAndAsyncTests.cs new file mode 100644 index 0000000000000..3149ecea55f1d --- /dev/null +++ b/src/Compilers/CSharp/Test/Emit3/RefUnsafeInIteratorAndAsyncTests.cs @@ -0,0 +1,1308 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests; + +public class RefUnsafeInIteratorAndAsyncTests : CSharpTestBase +{ + private static string? IfSpans(string expectedOutput) + => ExecutionConditionUtil.IsDesktop ? null : expectedOutput; + + [Fact] + public void LangVersion_RefLocalInAsync() + { + var source = """ + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + ref int y = ref x; + ref readonly int z = ref y; + await Task.Yield(); + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 17), + // (7,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly int z = ref y; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "z").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 26)); + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(source).VerifyEmitDiagnostics(); + } + + [Fact] + public void LangVersion_RefLocalInIterator() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + ref int y = ref x; + ref readonly int z = ref y; + yield return x; + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 17), + // (7,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly int z = ref y; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "z").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 26)); + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(source).VerifyEmitDiagnostics(); + } + + [Fact] + public void LangVersion_RefLocalInIterator_IEnumerator() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerator M(int x) + { + ref int y = ref x; + ref readonly int z = ref y; + yield return x; + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 17), + // (7,26): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly int z = ref y; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "z").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 26)); + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(source).VerifyEmitDiagnostics(); + } + + [Fact] + public void LangVersion_RefStructInAsync() + { + var source = """ + #pragma warning disable CS0219 // variable unused + using System.Threading.Tasks; + class C + { + async Task M() + { + R y = default; + scoped R z = default; + await Task.Yield(); + } + } + ref struct R { } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // R y = default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "R").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 9), + // (8,16): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // scoped R z = default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "R").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 16)); + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(source).VerifyEmitDiagnostics(); + } + + [Fact] + public void LangVersion_RefStructInIterator() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M(R r) + { + M(r); + yield return -1; + } + } + ref struct R { } + """; + + var expectedDiagnostics = new[] + { + // (6,11): error CS4007: Instance of type 'R' cannot be preserved across 'await' or 'yield' boundary. + // M(r); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "r").WithArguments("R").WithLocation(6, 11) + }; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void LangVersion_RestrictedInAsync() + { + var source = """ + #pragma warning disable CS0219 // variable unused + using System.Threading.Tasks; + class C + { + async Task M() + { + System.TypedReference t = default; + await Task.Yield(); + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // System.TypedReference t = default; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "System.TypedReference").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 9)); + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(source).VerifyEmitDiagnostics(); + } + + [Fact] + public void LangVersion_RestrictedInIterator() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M(System.TypedReference t) + { + t.GetHashCode(); + yield return -1; + } + } + """; + + var expectedDiagnostics = new[] + { + // (6,9): error CS4007: Instance of type 'System.TypedReference' cannot be preserved across 'await' or 'yield' boundary. + // t.GetHashCode(); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "t").WithArguments("System.TypedReference").WithLocation(6, 9) + }; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Await_RefLocal_Across() + { + var source = """ + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + ref int y = ref x; + await Task.Yield(); + System.Console.Write(y); + } + } + """; + CreateCompilation(source).VerifyEmitDiagnostics( + // (8,30): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(8, 30)); + } + + [Fact] + public void Await_RefLocal_Across_Unsafe_01() + { + var source = """ + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + unsafe + { + ref int y = ref x; + await Task.Yield(); + System.Console.Write(y); + } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (8,21): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 21), + // (9,13): error CS4004: Cannot await in an unsafe context + // await Task.Yield(); + Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Yield()").WithLocation(9, 13)); + + var expectedDiagnostics = new[] + { + // (9,13): error CS4004: Cannot await in an unsafe context + // await Task.Yield(); + Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Yield()").WithLocation(9, 13) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Await_RefLocal_Across_Unsafe_02() + { + var source = """ + using System.Threading.Tasks; + unsafe class C + { + async Task M(int x) + { + ref int y = ref x; + await Task.Yield(); + System.Console.Write(y); + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 17), + // (7,9): error CS4004: Cannot await in an unsafe context + // await Task.Yield(); + Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Yield()").WithLocation(7, 9)); + + var expectedDiagnostics = new[] + { + // (7,9): error CS4004: Cannot await in an unsafe context + // await Task.Yield(); + Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Yield()").WithLocation(7, 9) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Await_RefLocal_Across_Unsafe_03() + { + var source = """ + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + ref int y = ref x; + await Task.Yield(); + unsafe + { + System.Console.Write(y); + } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 17)); + + var expectedDiagnostics = new[] + { + // (10,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(10, 34) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Await_RefLocal_Across_Reassign() + { + var source = """ + using System.Threading.Tasks; + class C + { + static Task Main() => M(123, 456); + static async Task M(int x, int z) + { + ref int y = ref x; + await Task.Yield(); + y = ref z; + System.Console.Write(y); + } + } + """; + CompileAndVerify(source, expectedOutput: "456").VerifyDiagnostics(); + } + + [Fact] + public void Await_RefLocal_Between() + { + var source = """ + using System.Threading.Tasks; + class C + { + static Task Main() => M(123); + static async Task M(int x) + { + ref int y = ref x; + System.Console.Write(y); + await Task.Yield(); + } + } + """; + CompileAndVerify(source, expectedOutput: "123").VerifyDiagnostics(); + } + + [Fact] + public void Await_RefStruct_Across() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + Span y = new(ref x); + await Task.Yield(); + Console.Write(y.ToString()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (9,23): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.ToString()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(9, 23)); + } + + [Fact] + public void Await_RefStruct_Across_Unsafe() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + Span y = new(ref x); + await Task.Yield(); + unsafe { Console.Write(y.ToString()); } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (7,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // Span y = new(ref x); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Span").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 9)); + + var expectedDiagnostics = new[] + { + // (9,32): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // unsafe { Console.Write(y.ToString()); } + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(9, 32) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Await_RefStruct_Across_Reassign() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static Task Main() => M(123, 456); + static async Task M(int x, int z) + { + Span y = new(ref x); + await Task.Yield(); + y = new(ref z); + Console.Write(y[0]); + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("456"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void Await_RefStruct_Between() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static Task Main() => M(123); + static async Task M(int x) + { + Span y = new(ref x); + Console.Write(y[0]); + await Task.Yield(); + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("123"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void Await_Restricted_Across() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + async Task M() + { + TypedReference y = default; + await Task.Yield(); + Console.Write(y.GetHashCode()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (9,23): error CS4007: Instance of type 'System.TypedReference' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.GetHashCode()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.TypedReference").WithLocation(9, 23)); + } + + [Fact] + public void Await_Restricted_Across_Reassign() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + TypedReference y = default; + await Task.Yield(); + y = default; + Console.Write(y.GetHashCode()); + } + } + """; + CompileAndVerify(source, expectedOutput: "0").VerifyDiagnostics(); + } + + [Fact] + public void Await_Restricted_Between() + { + var source = """ + using System; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + TypedReference y = default; + Console.Write(y.GetHashCode()); + await Task.Yield(); + } + } + """; + CompileAndVerify(source, expectedOutput: "0").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefLocal_Across() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + ref int y = ref x; + yield return 1; + System.Console.Write(y); + } + } + """; + CreateCompilation(source).VerifyEmitDiagnostics( + // (8,30): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(8, 30)); + } + + [Fact] + public void YieldReturn_RefLocal_Across_Unsafe() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + ref int y = ref x; + yield return 1; + unsafe { System.Console.Write(y); } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 17), + // (8,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe { System.Console.Write(y); } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 9)); + + var expectedDiagnostics = new[] + { + // (8,39): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // unsafe { System.Console.Write(y); } + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(8, 39) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void YieldReturn_RefLocal_Across_Indexer() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable this[int x] + { + get + { + ref int y = ref x; + yield return 1; + System.Console.Write(y); + } + } + } + """; + CreateCompilation(source).VerifyEmitDiagnostics( + // (10,34): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(10, 34)); + } + + [Fact] + public void YieldReturn_RefLocal_Across_NestedBlock() + { + var source = """ + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + ref int y = ref x; + if (x != 0) { yield return 1; } + System.Console.Write(y); + } + } + """; + CreateCompilation(source).VerifyEmitDiagnostics( + // (8,30): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(8, 30)); + } + + [Fact] + public void YieldReturn_RefLocal_Across_Async() + { + var source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + async IAsyncEnumerable M(int x) + { + ref int y = ref x; + yield return 1; await Task.Yield(); + System.Console.Write(y); + } + } + """ + AsyncStreamsTypes; + CreateCompilationWithTasksExtensions(source).VerifyEmitDiagnostics( + // (9,30): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // System.Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(9, 30)); + } + + [Fact] + public void YieldReturn_RefLocal_Across_Reassign() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in M(123, 456)) + { + Console.Write(i + " "); + } + } + static IEnumerable M(int x, int z) + { + ref int y = ref x; + yield return -1; + y = ref z; + Console.Write(y); + } + } + """; + CompileAndVerify(source, expectedOutput: "-1 456").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefLocal_Across_Reassign_Indexer() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in new C()[123, 456]) + { + Console.Write(i + " "); + } + } + IEnumerable this[int x, int z] + { + get + { + ref int y = ref x; + yield return -1; + y = ref z; + Console.Write(y); + } + } + } + """; + CompileAndVerify(source, expectedOutput: "-1 456").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefLocal_Across_Reassign_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var i in M(123, 456)) + { + Console.Write(i + " "); + } + } + static async IAsyncEnumerable M(int x, int z) + { + ref int y = ref x; + yield return -1; await Task.Yield(); + y = ref z; + Console.Write(y); + } + } + """ + AsyncStreamsTypes; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "-1 456").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefLocal_Between() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in M(123)) + { + Console.Write(i + " "); + } + } + static IEnumerable M(int x) + { + ref int y = ref x; + Console.Write(y); + yield return -1; + } + } + """; + CompileAndVerify(source, expectedOutput: "123-1").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefLocal_Between_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var i in M(123)) + { + Console.Write(i + " "); + } + } + static async IAsyncEnumerable M(int x) + { + ref int y = ref x; + Console.Write(y); + yield return -1; await Task.Yield(); + } + } + """ + AsyncStreamsTypes; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "123-1").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefStruct_Across() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + Span y = new(ref x); + yield return -1; + Console.Write(y.ToString()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (9,23): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.ToString()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(9, 23)); + } + + [Fact] + public void YieldReturn_RefStruct_Across_Unsafe() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + Span y = new(ref x); + yield return -1; + unsafe { Console.Write(y.ToString()); } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (9,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe { Console.Write(y.ToString()); } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 9)); + + var expectedDiagnostics = new[] + { + // (9,32): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // unsafe { Console.Write(y.ToString()); } + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(9, 32) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void YieldReturn_RefStruct_Across_Indexer() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + IEnumerable this[int x] + { + get + { + Span y = new(ref x); + yield return -1; + Console.Write(y.ToString()); + } + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (11,27): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.ToString()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(11, 27)); + } + + [Fact] + public void YieldReturn_RefStruct_Across_NestedBlock() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + IEnumerable M(int x) + { + Span y = new(ref x); + if (x != 0) { yield return -1; } + Console.Write(y.ToString()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (9,23): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.ToString()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(9, 23)); + } + + [Fact] + public void YieldReturn_RefStruct_Across_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + async IAsyncEnumerable M(int x) + { + Span y = new(ref x); + yield return -1; await Task.Yield(); + Console.Write(y.ToString()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (10,23): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.ToString()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(10, 23)); + } + + [Fact] + public void YieldReturn_RefStruct_Across_Reassign() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in M(123, 456)) + { + Console.Write(i + " "); + } + } + static IEnumerable M(int x, int z) + { + Span y = new(ref x); + yield return -1; + y = new(ref z); + Console.Write(y[0]); + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("-1 456"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefStruct_Across_Reassign_Indexer() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in new C()[123, 456]) + { + Console.Write(i + " "); + } + } + IEnumerable this[int x, int z] + { + get + { + Span y = new(ref x); + yield return -1; + y = new(ref z); + Console.Write(y[0]); + } + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("-1 456"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefStruct_Across_Reassign_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var i in M(123, 456)) + { + Console.Write(i + " "); + } + } + static async IAsyncEnumerable M(int x, int z) + { + Span y = new(ref x); + yield return -1; await Task.Yield(); + y = new(ref z); + Console.Write(y[0]); + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("-1 456"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_RefStruct_Between() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in M(123)) + { + Console.Write(i + " "); + } + } + static IEnumerable M(int x) + { + Span y = new(ref x); + Console.Write(y[0]); + yield return -1; + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("123-1"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_Restricted_Across() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + IEnumerable M() + { + TypedReference y = default; + yield return -1; + Console.Write(y.GetHashCode()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (9,23): error CS4007: Instance of type 'System.TypedReference' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.GetHashCode()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.TypedReference").WithLocation(9, 23)); + } + + [Fact] + public void YieldReturn_Restricted_Across_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + async IAsyncEnumerable M() + { + TypedReference y = default; + yield return -1; await Task.Yield(); + Console.Write(y.GetHashCode()); + } + } + """; + CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (10,23): error CS4007: Instance of type 'System.TypedReference' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y.GetHashCode()); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.TypedReference").WithLocation(10, 23)); + } + + [Fact] + public void YieldReturn_Restricted_Across_Reassign() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in M()) + { + Console.Write(i + " "); + } + } + static IEnumerable M() + { + TypedReference y = default; + yield return -1; + y = default; + Console.Write(y.GetHashCode()); + } + } + """; + CompileAndVerify(source, expectedOutput: "-1 0").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_Restricted_Across_Reassign_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var i in M()) + { + Console.Write(i + " "); + } + } + static async IAsyncEnumerable M() + { + TypedReference y = default; + yield return -1; await Task.Yield(); + y = default; + Console.Write(y.GetHashCode()); + } + } + """ + AsyncStreamsTypes; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "-1 0").VerifyDiagnostics(); + } + + [Fact] + public void YieldReturn_Restricted_Between() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var i in M()) + { + Console.Write(i + " "); + } + } + static IEnumerable M() + { + TypedReference y = default; + Console.Write(y.GetHashCode()); + yield return -1; + } + } + """; + CompileAndVerify(source, expectedOutput: "0-1").VerifyDiagnostics(); + } + + [Fact] + public void YieldBreak_RefLocal_Across() + { + var source = """ + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var a in M(10)) { throw null; } + foreach (var b in M(123)) { throw null; } + } + static IEnumerable M(int x) + { + ref int y = ref x; + if (x < 100) yield break; + System.Console.Write(y); + } + } + """; + CompileAndVerify(source, expectedOutput: "123").VerifyDiagnostics(); + } + + [Fact] + public void YieldBreak_RefLocal_Across_Async() + { + var source = """ + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var a in M(10)) { throw null; } + await foreach (var b in M(123)) { throw null; } + } + static async IAsyncEnumerable M(int x) + { + ref int y = ref x; + if (x < 100) { await Task.Yield(); yield break; } + System.Console.Write(y); + } + } + """ + AsyncStreamsTypes; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "123").VerifyDiagnostics(); + } + + [Fact] + public void YieldBreak_RefStruct_Across() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var a in M(10)) { throw null; } + foreach (var b in M(123)) { throw null; } + } + static IEnumerable M(int x) + { + Span y = new(ref x); + if (x < 100) yield break; + Console.Write(y[0]); + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("123"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void YieldBreak_RefStruct_Across_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var a in M(10)) { throw null; } + await foreach (var b in M(123)) { throw null; } + } + static async IAsyncEnumerable M(int x) + { + Span y = new(ref x); + if (x < 100) { await Task.Yield(); yield break; } + Console.Write(y[0]); + } + } + """; + CompileAndVerify(source, expectedOutput: IfSpans("123"), verify: Verification.FailsPEVerify, targetFramework: TargetFramework.Net70).VerifyDiagnostics(); + } + + [Fact] + public void YieldBreak_Restricted_Across() + { + var source = """ + using System; + using System.Collections.Generic; + class C + { + static void Main() + { + foreach (var a in M(10)) { throw null; } + foreach (var b in M(123)) { throw null; } + } + static IEnumerable M(int x) + { + TypedReference t = default; + if (x < 100) yield break; + Console.Write(x + t.GetHashCode()); + } + } + """; + CompileAndVerify(source, expectedOutput: "123").VerifyDiagnostics(); + } + + [Fact] + public void YieldBreak_Restricted_Across_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + class C + { + static async Task Main() + { + await foreach (var a in M(10)) { throw null; } + await foreach (var b in M(123)) { throw null; } + } + static async IAsyncEnumerable M(int x) + { + TypedReference t = default; + if (x < 100) { await Task.Yield(); yield break; } + Console.Write(x + t.GetHashCode()); + } + } + """ + AsyncStreamsTypes; + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseExe); + CompileAndVerify(comp, expectedOutput: "123").VerifyDiagnostics(); + } +} diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs index 796e66b99d0d3..11a9f7482ab8f 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.cs @@ -2570,11 +2570,7 @@ public void Dispose() {} Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'e') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'e') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (Boxing) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: Enumerator, IsImplicit) (Syntax: 'e') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: Enumerator, IsImplicit) (Syntax: 'e') Arguments(0) Next (StructuredExceptionHandling) Block[null] @@ -5182,7 +5178,7 @@ static class Extensions Statements (1) IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new Program()') Expression: - IInvocationOperation ( System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new Program()') + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new Program()') Instance Receiver: IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new Program()') Arguments(0) @@ -5314,7 +5310,7 @@ static class Extensions Statements (1) IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'new Program()') Expression: - IInvocationOperation ( System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new Program()') + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'new Program()') Instance Receiver: IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'new Program()') Arguments(0) @@ -5571,7 +5567,7 @@ static class Extensions Statements (1) IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'null ?? new Program()') Expression: - IInvocationOperation ( System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'null ?? new Program()') + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'null ?? new Program()') Instance Receiver: IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'null ?? new Program()') Arguments(0) @@ -5742,7 +5738,7 @@ static async Task Main(System.Collections.Generic.IAsyncEnumerable pets) Statements (1) IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'pets') Expression: - IInvocationOperation ( System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'pets') + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'pets') Instance Receiver: IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.Collections.Generic.IAsyncEnumerator, IsImplicit) (Syntax: 'pets') Arguments(0) @@ -6220,11 +6216,7 @@ public struct Enumerator : System.IDisposable Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'new C()') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'new C()') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (Boxing) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: C.Enumerator, IsImplicit) (Syntax: 'new C()') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: C.Enumerator, IsImplicit) (Syntax: 'new C()') Arguments(0) Next (StructuredExceptionHandling) Block[null] } diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IUsingStatement.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IUsingStatement.cs index 766404d3df5d2..394f3007bd19f 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IUsingStatement.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IUsingStatement.cs @@ -320,7 +320,7 @@ public static async Task M1(IAsyncDisposable disposable) Statements (1) IAwaitOperation (OperationKind.Await, Type: System.Void, IsImplicit) (Syntax: 'c = disposable') Expression: - IInvocationOperation ( System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'c = disposable') + IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsImplicit) (Syntax: 'c = disposable') Instance Receiver: ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.IAsyncDisposable, IsImplicit) (Syntax: 'c = disposable') Arguments(0) @@ -2011,11 +2011,7 @@ .maxstack 8 Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 's = new S()') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 's = new S()') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: - ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') + ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') Arguments(0) Next (StructuredExceptionHandling) Block[null] } @@ -2152,11 +2148,7 @@ .maxstack 8 Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 's = new S()') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 's = new S()') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: - ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') + ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') Arguments(0) Next (StructuredExceptionHandling) Block[null] } @@ -2293,11 +2285,7 @@ .maxstack 8 Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 's = new S()') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 's = new S()') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: - ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') + ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') Arguments(0) Next (StructuredExceptionHandling) Block[null] } @@ -2437,11 +2425,7 @@ .maxstack 8 Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 's = new S()') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 's = new S()') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: - ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') + ILocalReferenceOperation: s (OperationKind.LocalReference, Type: S, IsInvalid, IsImplicit) (Syntax: 's = new S()') Arguments(0) Next (StructuredExceptionHandling) Block[null] } @@ -2792,11 +2776,7 @@ struct MyDisposable : System.IDisposable Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (Boxing) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') Arguments(0) Next (StructuredExceptionHandling) Block[null] @@ -2901,11 +2881,7 @@ void M(MyDisposable input, bool b) where MyDisposable : System.IDi Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (Boxing) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') Arguments(0) Next (Regular) Block[B7] @@ -3032,11 +3008,10 @@ struct MyDisposable : System.IDisposable Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'GetDisposable() ?? input') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'GetDisposable() ?? input') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (Boxing) - Operand: + IInvocationOperation ( MyDisposable MyDisposable?.GetValueOrDefault()) (OperationKind.Invocation, Type: MyDisposable, IsImplicit) (Syntax: 'GetDisposable() ?? input') + Instance Receiver: IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: MyDisposable?, IsImplicit) (Syntax: 'GetDisposable() ?? input') + Arguments(0) Arguments(0) Next (Regular) Block[B7] @@ -3395,11 +3370,7 @@ struct MyDisposable Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... e() : input') Arguments(0) Next (StructuredExceptionHandling) Block[null] } @@ -3499,11 +3470,7 @@ void M(MyDisposable input, bool b) Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (Unboxing) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: MyDisposable, IsInvalid, IsImplicit) (Syntax: 'b ? GetDisp ... >() : input') Arguments(0) Next (Regular) Block[B7] Block[B7] - Block @@ -3622,11 +3589,10 @@ struct MyDisposable Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 'GetDisposable() ?? input') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 'GetDisposable() ?? input') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: + IInvocationOperation ( MyDisposable MyDisposable?.GetValueOrDefault()) (OperationKind.Invocation, Type: MyDisposable, IsInvalid, IsImplicit) (Syntax: 'GetDisposable() ?? input') + Instance Receiver: IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: MyDisposable?, IsInvalid, IsImplicit) (Syntax: 'GetDisposable() ?? input') + Arguments(0) Arguments(0) Next (Regular) Block[B7] Block[B7] - Block @@ -4418,11 +4384,10 @@ public Task DisposeAsync() Expression: IInvocationOperation (virtual System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()) (OperationKind.Invocation, Type: System.Threading.Tasks.ValueTask, IsInvalid, IsImplicit) (Syntax: 's') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IAsyncDisposable, IsInvalid, IsImplicit) (Syntax: 's') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: + IInvocationOperation ( S S?.GetValueOrDefault()) (OperationKind.Invocation, Type: S, IsInvalid, IsImplicit) (Syntax: 's') + Instance Receiver: IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: S?, IsInvalid, IsImplicit) (Syntax: 's') + Arguments(0) Arguments(0) Next (Regular) Block[B5] Block[B5] - Block @@ -7597,11 +7562,7 @@ void M(bool b) Statements (1) IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsInvalid, IsImplicit) (Syntax: 'x = new P()') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsInvalid, IsImplicit) (Syntax: 'x = new P()') - Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (NoConversion) - Operand: - ILocalReferenceOperation: x (OperationKind.LocalReference, Type: P, IsInvalid, IsImplicit) (Syntax: 'x = new P()') + ILocalReferenceOperation: x (OperationKind.LocalReference, Type: P, IsInvalid, IsImplicit) (Syntax: 'x = new P()') Arguments(0) Next (StructuredExceptionHandling) Block[null] } @@ -7889,6 +7850,118 @@ Element Values(0) VerifyFlowGraphAndDiagnosticsForTest(source + s_IAsyncEnumerable + IOperationTests_IForEachLoopStatement.s_ValueTask, expectedGraph, expectedDiagnostics); } + [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73068")] + public void UsingDeclaration_Flow_25() + { + var code = """ + class C + { + void M() + /**/{ + x: + System.Action a = () => { + using System.IDisposable d = null; + goto x; + }; + }/**/ + + } + """; + var expectedGraph = """ +Block[B0] - Entry + Statements (0) + Next (Regular) Block[B1] + Entering: {R1} +.locals {R1} +{ + Locals: [System.Action a] + Block[B1] - Block + Predecessors: [B0] + Statements (1) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Action, IsInvalid, IsImplicit) (Syntax: 'a = () => { ... }') + Left: + ILocalReferenceOperation: a (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Action, IsInvalid, IsImplicit) (Syntax: 'a = () => { ... }') + Right: + IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Action, IsInvalid, IsImplicit) (Syntax: '() => { ... }') + Target: + IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null, IsInvalid) (Syntax: '() => { ... }') + { + Block[B0#A0] - Entry + Statements (0) + Next (Regular) Block[B1#A0] + Entering: {R1#A0} + .locals {R1#A0} + { + Locals: [System.IDisposable d] + Block[B1#A0] - Block + Predecessors: [B0#A0] + Statements (1) + ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.IDisposable, IsImplicit) (Syntax: 'd = null') + Left: + ILocalReferenceOperation: d (IsDeclaration: True) (OperationKind.LocalReference, Type: System.IDisposable, IsImplicit) (Syntax: 'd = null') + Right: + IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, Constant: null, IsImplicit) (Syntax: 'null') + Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) + (ImplicitReference) + Operand: + ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null') + Next (Regular) Block[B2#A0] + Entering: {R2#A0} {R3#A0} + .try {R2#A0, R3#A0} + { + Block[B2#A0] - Block + Predecessors: [B1#A0] + Statements (0) + Next (Error) Block[null] + } + .finally {R4#A0} + { + Block[B3#A0] - Block + Predecessors (0) + Statements (0) + Jump if True (Regular) to Block[B5#A0] + IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'd = null') + Operand: + ILocalReferenceOperation: d (OperationKind.LocalReference, Type: System.IDisposable, IsImplicit) (Syntax: 'd = null') + Next (Regular) Block[B4#A0] + Block[B4#A0] - Block + Predecessors: [B3#A0] + Statements (1) + IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'd = null') + Instance Receiver: + ILocalReferenceOperation: d (OperationKind.LocalReference, Type: System.IDisposable, IsImplicit) (Syntax: 'd = null') + Arguments(0) + Next (Regular) Block[B5#A0] + Block[B5#A0] - Block + Predecessors: [B3#A0] [B4#A0] + Statements (0) + Next (StructuredExceptionHandling) Block[null] + } + } + Block[B6#A0] - Exit [UnReachable] + Predecessors (0) + Statements (0) + } + Next (Regular) Block[B2] + Leaving: {R1} +} +Block[B2] - Exit + Predecessors: [B1] + Statements (0) +"""; + var expectedDiagnostics = new[] + { + // (5,9): warning CS0164: This label has not been referenced + // x: + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "x").WithLocation(5, 9), + // (8,13): error CS0159: No such label 'x' within the scope of the goto statement + // goto x; + Diagnostic(ErrorCode.ERR_LabelNotFound, "goto").WithArguments("x").WithLocation(8, 13) + }; + VerifyFlowGraphAndDiagnosticsForTest(code, expectedGraph, expectedDiagnostics); + } + [CompilerTrait(CompilerFeature.IOperation)] [Fact, WorkItem(32100, "https://github.com/dotnet/roslyn/issues/32100")] public void UsingDeclaration_SingleDeclaration() diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs index 58b403f3ed35f..0cdb4221d7784 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs @@ -241,9 +241,9 @@ static async Task Goo() }"; var comp = CreateCompilationWithMscorlib45(text, options: TestOptions.ReleaseDll); comp.VerifyEmitDiagnostics( - // (8,27): error CS4007: 'await' cannot be used in an expression containing the type 'System.TypedReference' + // (8,27): error CS4007: Instance of type 'System.TypedReference' cannot be preserved across 'await' or 'yield' boundary. // Console.WriteLine(new TypedReference().Equals(await Task.FromResult(0))); - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await Task.FromResult(0)").WithArguments("System.TypedReference").WithLocation(8, 55)); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "new TypedReference()").WithArguments("System.TypedReference").WithLocation(8, 27)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs index 2df12ae65f737..ea484d234e28a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs @@ -914,9 +914,9 @@ public ref struct A {} public class C { public static implicit operator C(A a) => null; } "; CreateCompilationWithoutBetterCandidates(source, options: TestOptions.ReleaseExe).VerifyDiagnostics( - // (5,9): error CS0306: The type 'A' may not be used as a type argument + // (5,9): error CS9244: The type 'A' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Program.M(T, int)' // M(new A(), 0); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("A").WithLocation(5, 9) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("Program.M(T, int)", "T", "A").WithLocation(5, 9) ); var compilation = CreateCompilationWithBetterCandidates(source, options: TestOptions.ReleaseExe).VerifyDiagnostics( ); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingAsyncTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingAsyncTests.cs index 740346725b17a..8e550a2a565e8 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingAsyncTests.cs @@ -3218,9 +3218,9 @@ async Task M1(TypedReference tr) } }"; CreateCompilationWithMscorlib45(source).VerifyDiagnostics( - // (7,34): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or async lambda expressions + // (7,34): error CS4012: Parameters of type 'System.TypedReference' cannot be declared in async methods or async lambda expressions // async Task M1(TypedReference tr) - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "tr").WithArguments("System.TypedReference")); + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "tr").WithArguments("System.TypedReference")); } [Fact] @@ -3238,10 +3238,7 @@ async Task M1() await Task.Factory.StartNew(() => { }); } }"; - CreateCompilationWithMscorlib45(source).VerifyDiagnostics( - // (9,9): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or async lambda expressions - // TypedReference tr; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "TypedReference").WithArguments("System.TypedReference"), + CreateCompilationWithMscorlib45(source).VerifyEmitDiagnostics( // (9,24): warning CS0168: The variable 'tr' is declared but never used // TypedReference tr; Diagnostic(ErrorCode.WRN_UnreferencedVar, "tr").WithArguments("tr")); @@ -3257,18 +3254,33 @@ public void BadSpecialByRefVarDeclLocal() class Test { async Task M1(bool truth) + { + var tr = new TypedReference(); // 1 + await Task.Factory.StartNew(() => { }); + } + + async Task M2(bool truth) { var tr = new TypedReference(); await Task.Factory.StartNew(() => { }); + var tr2 = tr; // 2 + } + + async Task M3() + { + var tr = new TypedReference(); + await Task.Factory.StartNew(() => { }); + tr = default; + var tr2 = tr; } }"; - CreateCompilationWithMscorlib45(source).VerifyDiagnostics( - // (9,9): error CS4012: Parameters or locals of type 'TypedReference' cannot be declared in async methods or async lambda expressions. - // var tr = new TypedReference(); - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.TypedReference").WithLocation(9, 9), + CreateCompilationWithMscorlib45(source).VerifyEmitDiagnostics( // (9,13): warning CS0219: The variable 'tr' is assigned but its value is never used - // var tr = new TypedReference(); - Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "tr").WithArguments("tr").WithLocation(9, 13)); + // var tr = new TypedReference(); // 1 + Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "tr").WithArguments("tr").WithLocation(9, 13), + // (17,19): error CS4007: Instance of type 'System.TypedReference' cannot be preserved across 'await' or 'yield' boundary. + // var tr2 = tr; // 2 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "tr").WithArguments("System.TypedReference").WithLocation(17, 19)); } [Fact] @@ -3288,9 +3300,6 @@ unsafe async public static void F() // (8,31): error CS0209: The type of a local declared in a fixed statement must be a pointer type // fixed (TypedReference tr) { } Diagnostic(ErrorCode.ERR_BadFixedInitType, "tr"), - // (8,16): error CS4012: Parameters or locals of type 'System.TypedReference' cannot be declared in async methods or async lambda expressions. - // fixed (TypedReference tr) { } - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "TypedReference").WithArguments("System.TypedReference"), // (8,31): error CS0210: You must provide an initializer in a fixed or using statement declaration // fixed (TypedReference tr) { } Diagnostic(ErrorCode.ERR_FixedMustInit, "tr"), diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs index 66f72c60a5364..b30a1e4fa287e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs @@ -3054,18 +3054,12 @@ public C1(long x){} // (27,69): error CS1963: An expression tree may not contain a dynamic operation // Expression> e2 = () => new C { D = { X = { Y = 1 }, Z = 1 } }; Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "Z").WithLocation(27, 69), - // (28,46): error CS1963: An expression tree may not contain a dynamic operation - // Expression> e3 = () => new C() { { d }, { d, d, d } }; - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(28, 46), - // (28,53): error CS1963: An expression tree may not contain a dynamic operation - // Expression> e3 = () => new C() { { d }, { d, d, d } }; - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(28, 53), - // (28,56): error CS1963: An expression tree may not contain a dynamic operation + // (28,44): error CS1963: An expression tree may not contain a dynamic operation // Expression> e3 = () => new C() { { d }, { d, d, d } }; - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(28, 56), - // (28,59): error CS1963: An expression tree may not contain a dynamic operation + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "{ d }").WithLocation(28, 44), + // (28,51): error CS1963: An expression tree may not contain a dynamic operation // Expression> e3 = () => new C() { { d }, { d, d, d } }; - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(28, 59), + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "{ d, d, d }").WithLocation(28, 51), // (29,54): error CS1963: An expression tree may not contain a dynamic operation // Expression> e4 = x => x.goo(); Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "x.goo()").WithLocation(29, 54), @@ -3087,6 +3081,15 @@ public C1(long x){} // (33,54): error CS1963: An expression tree may not contain a dynamic operation // Expression> e8 = x => -x; Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "-x").WithLocation(33, 54), + // (34,54): error CS1963: An expression tree may not contain a dynamic operation + // Expression> e9 = x => f(d); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f(d)").WithLocation(34, 54), + // (36,55): error CS1963: An expression tree may not contain a dynamic operation + // Expression> e11 = x => f((dynamic)1); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f((dynamic)1)").WithLocation(36, 55), + // (37,55): error CS1963: An expression tree may not contain a dynamic operation + // Expression> e12 = x => f(d ?? null); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "f(d ?? null)").WithLocation(37, 55), // (38,55): error CS1963: An expression tree may not contain a dynamic operation // Expression> e13 = x => d ? 1 : 2; Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(38, 55), @@ -4472,7 +4475,7 @@ static void M1() [Fact] public void InArgumentDynamicLocalFunction() { - string source = @" + string source1 = @" class C { private static void M1(in dynamic x, int y, in dynamic z) => System.Console.WriteLine(x == y); @@ -4482,25 +4485,24 @@ static void Main() dynamic d = 1; M1(in d, d = 2, in d); - - void M2(in dynamic x, int y, in dynamic z) => System.Console.WriteLine(x == y); - - M2(in d, d = 3, in d); } } "; - var comp = CreateCompilationWithMscorlib45AndCSharp(source, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe); + var comp1 = CreateCompilationWithMscorlib45AndCSharp(source1, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: -@" -True -True -").VerifyDiagnostics(); + comp1.VerifyEmitDiagnostics( + // (10,15): error CS8364: Arguments with 'in' modifier cannot be used in dynamically dispatched expressions. + // M1(in d, d = 2, in d); + Diagnostic(ErrorCode.ERR_InDynamicMethodArg, "d").WithLocation(10, 15), + // (10,28): error CS8364: Arguments with 'in' modifier cannot be used in dynamically dispatched expressions. + // M1(in d, d = 2, in d); + Diagnostic(ErrorCode.ERR_InDynamicMethodArg, "d").WithLocation(10, 28) + ); - comp = CreateCompilationWithMscorlib45AndCSharp(source, parseOptions: TestOptions.Regular7_2, options: TestOptions.DebugExe); + comp1 = CreateCompilationWithMscorlib45AndCSharp(source1, parseOptions: TestOptions.Regular7_2, options: TestOptions.DebugExe); - comp.VerifyEmitDiagnostics( + comp1.VerifyEmitDiagnostics( // (10,15): error CS8364: Arguments with 'in' modifier cannot be used in dynamically dispatched expressions. // M1(in d, d = 2, in d); Diagnostic(ErrorCode.ERR_InDynamicMethodArg, "d").WithLocation(10, 15), @@ -4508,6 +4510,34 @@ static void Main() // M1(in d, d = 2, in d); Diagnostic(ErrorCode.ERR_InDynamicMethodArg, "d").WithLocation(10, 28) ); + + string source2 = @" +class C +{ + static void Main() + { + dynamic d = 1; + + void M2(in dynamic x, int y, in dynamic z) => System.Console.WriteLine(x == y); + + M2(in d, d = 3, in d); + } +} +"; + + var comp2 = CreateCompilationWithMscorlib45AndCSharp(source2, parseOptions: TestOptions.RegularPreview, options: TestOptions.DebugExe); + + CompileAndVerify(comp2, expectedOutput: +@" +True +").VerifyDiagnostics(); + + comp2 = CreateCompilationWithMscorlib45AndCSharp(source2, parseOptions: TestOptions.Regular7_2, options: TestOptions.DebugExe); + + CompileAndVerify(comp2, expectedOutput: +@" +True +").VerifyDiagnostics(); } [WorkItem(22813, "https://github.com/dotnet/roslyn/issues/22813")] @@ -4687,24 +4717,11 @@ ref struct S } """; - var verifier = CompileAndVerify(code, expectedOutput: "Hello world", targetFramework: TargetFramework.StandardAndCSharp); - verifier.VerifyDiagnostics(); - verifier.VerifyIL("", $$""" - { - // Code size 23 (0x17) - .maxstack 2 - .locals init (S V_0, //s - object V_1) //d - IL_0000: ldloca.s V_0 - IL_0002: initobj "S" - IL_0008: ldstr "Hello world" - IL_000d: stloc.1 - IL_000e: ldloca.s V_0 - IL_0010: ldloc.1 - IL_0011: call "void S.M({{argType}})" - IL_0016: ret - } - """); + CreateCompilation(code, targetFramework: TargetFramework.StandardAndCSharp).VerifyDiagnostics( + // (4,1): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // s.M(d); + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "s").WithArguments("S").WithLocation(4, 1) + ); } [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72606")] @@ -4731,49 +4748,11 @@ ref struct S } """; - var verifier = CompileAndVerify(code, expectedOutput: argType == "string" ? "Hello world" : "Caught exception", targetFramework: TargetFramework.StandardAndCSharp); - verifier.VerifyDiagnostics(); - verifier.VerifyIL("", $$""" - { - // Code size 101 (0x65) - .maxstack 4 - .locals init (S V_0, //s - object V_1) //d - IL_0000: ldloca.s V_0 - IL_0002: initobj "S" - IL_0008: ldstr "Hello world" - IL_000d: stloc.1 - .try - { - IL_000e: ldloca.s V_0 - IL_0010: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0015: brtrue.s IL_003b - IL_0017: ldc.i4.0 - IL_0018: ldtoken "{{argType}}" - IL_001d: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0022: ldtoken "Program" - IL_0027: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_002c: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_0031: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0036: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_003b: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0040: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_0045: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_004a: ldloc.1 - IL_004b: callvirt "{{argType}} System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_0050: call "void S.M({{argType}})" - IL_0055: leave.s IL_0064 - } - catch object - { - IL_0057: pop - IL_0058: ldstr "Caught exception" - IL_005d: call "void System.Console.WriteLine(string)" - IL_0062: leave.s IL_0064 - } - IL_0064: ret - } - """); + CreateCompilation(code, targetFramework: TargetFramework.StandardAndCSharp).VerifyDiagnostics( + // (6,5): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // s.M(d); + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "s").WithArguments("S").WithLocation(6, 5) + ); } [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72606")] @@ -4852,32 +4831,14 @@ public int this[{{argType}} o] } """; - var verifier = CompileAndVerify(code, expectedOutput: """ - Hello world - Hello world - """, targetFramework: TargetFramework.StandardAndCSharp); - verifier.VerifyDiagnostics(); - verifier.VerifyIL("", $$""" - { - // Code size 33 (0x21) - .maxstack 3 - .locals init (S V_0, //s - object V_1) //d - IL_0000: ldloca.s V_0 - IL_0002: initobj "S" - IL_0008: ldstr "Hello world" - IL_000d: stloc.1 - IL_000e: ldloca.s V_0 - IL_0010: ldloc.1 - IL_0011: call "int S.this[{{argType}}].get" - IL_0016: pop - IL_0017: ldloca.s V_0 - IL_0019: ldloc.1 - IL_001a: ldc.i4.1 - IL_001b: call "void S.this[{{argType}}].set" - IL_0020: ret - } - """); + CreateCompilation(code, targetFramework: TargetFramework.StandardAndCSharp).VerifyDiagnostics( + // (4,5): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // _ = s[d]; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "s").WithArguments("S").WithLocation(4, 5), + // (5,1): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // s[d] = 1; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "s").WithArguments("S").WithLocation(5, 1) + ); } [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72606")] @@ -4931,98 +4892,14 @@ public int this[{{argType}} o] } """; - var verifier = CompileAndVerify(code, expectedOutput: argType == "string" - ? """ - Hello world - Hello world - """ - : """ - Caught exception - Caught exception - """, targetFramework: TargetFramework.StandardAndCSharp); - verifier.VerifyDiagnostics(); - - verifier.VerifyIL("Program.<
$>g__get|0_0(ref Program.<>c__DisplayClass0_0)", $$""" - { - // Code size 101 (0x65) - .maxstack 4 - .locals init (S V_0) //s - IL_0000: ldloca.s V_0 - IL_0002: initobj "S" - .try - { - IL_0008: ldloca.s V_0 - IL_000a: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_000f: brtrue.s IL_0035 - IL_0011: ldc.i4.0 - IL_0012: ldtoken "{{argType}}" - IL_0017: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_001c: ldtoken "Program" - IL_0021: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0026: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_002b: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0030: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0035: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_003a: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_003f: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0044: ldarg.0 - IL_0045: ldfld "dynamic Program.<>c__DisplayClass0_0.d" - IL_004a: callvirt "{{argType}} System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_004f: call "int S.this[{{argType}}].get" - IL_0054: pop - IL_0055: leave.s IL_0064 - } - catch object - { - IL_0057: pop - IL_0058: ldstr "Caught exception" - IL_005d: call "void System.Console.WriteLine(string)" - IL_0062: leave.s IL_0064 - } - IL_0064: ret - } - """); - - verifier.VerifyIL("Program.<
$>g__set|0_1(ref Program.<>c__DisplayClass0_0)", $$""" - { - // Code size 101 (0x65) - .maxstack 4 - .locals init (S V_0) //s - IL_0000: ldloca.s V_0 - IL_0002: initobj "S" - .try - { - IL_0008: ldloca.s V_0 - IL_000a: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__1" - IL_000f: brtrue.s IL_0035 - IL_0011: ldc.i4.0 - IL_0012: ldtoken "{{argType}}" - IL_0017: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_001c: ldtoken "Program" - IL_0021: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0026: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_002b: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0030: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__1" - IL_0035: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__1" - IL_003a: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_003f: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__1" - IL_0044: ldarg.0 - IL_0045: ldfld "dynamic Program.<>c__DisplayClass0_0.d" - IL_004a: callvirt "{{argType}} System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_004f: ldc.i4.1 - IL_0050: call "void S.this[{{argType}}].set" - IL_0055: leave.s IL_0064 - } - catch object - { - IL_0057: pop - IL_0058: ldstr "Caught exception" - IL_005d: call "void System.Console.WriteLine(string)" - IL_0062: leave.s IL_0064 - } - IL_0064: ret - } - """); + CreateCompilation(code, targetFramework: TargetFramework.StandardAndCSharp).VerifyDiagnostics( + // (11,13): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // _ = s[d]; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "s").WithArguments("S").WithLocation(11, 13), + // (24,9): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. + // s[d] = 1; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "s").WithArguments("S").WithLocation(24, 9) + ); } [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72606")] @@ -5113,8 +4990,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.TargetMethod.ToTestDisplayString()); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp1).VerifyDiagnostics(); @@ -5147,8 +5023,11 @@ public interface I1 "; var comp2 = CreateCompilation(source2, options: TestOptions.DebugExe, parseOptions: parseOptions); - CompileAndVerify(comp2, - expectedOutput: @"System.Object (i1, value) => Convert(i1.Test(""name"", value)" + (ExecutionConditionUtil.IsMonoOrCoreClr ? ", Object)" : ")")).VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // var expr = GetExpression((I1 i1, dynamic value) => i1.Test("name", value)); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, @"i1.Test(""name"", value)").WithLocation(9, 60) + ); string source3 = @" #nullable enable @@ -5174,19 +5053,15 @@ class JsonSerializer "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp, parseOptions: parseOptions); - comp3.VerifyDiagnostics( - // (9,46): warning CS8604: Possible null reference argument for parameter 'c' in 'C JsonSerializer.Deserialize(Stream c)'. - // return JsonSerializer.Deserialize(result); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "result").WithArguments("c", "C JsonSerializer.Deserialize(Stream c)").WithLocation(9, 46) - ); + comp3.VerifyEmitDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Theory] @@ -5239,8 +5114,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.TargetMethod.ToTestDisplayString()); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp1).VerifyDiagnostics(); @@ -5273,8 +5147,11 @@ public interface I1 "; var comp2 = CreateCompilation(source2, options: TestOptions.DebugExe, parseOptions: parseOptions); - CompileAndVerify(comp2, - expectedOutput: @"System.Object (i1, value) => Convert(i1.Test(""name"", value)" + (ExecutionConditionUtil.IsMonoOrCoreClr ? ", Object)" : ")")).VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // var expr = GetExpression((I1 i1, dynamic value) => i1.Test("name", value)); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, @"i1.Test(""name"", value)").WithLocation(9, 60) + ); string source3 = @" #nullable enable @@ -5299,19 +5176,15 @@ class JsonSerializer } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp, parseOptions: parseOptions); - comp3.VerifyDiagnostics( - // (9,46): warning CS8604: Possible null reference argument for parameter 'c' in 'C JsonSerializer.Deserialize(Stream c)'. - // return JsonSerializer.Deserialize(result); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "result").WithArguments("c", "C JsonSerializer.Deserialize(Stream c)").WithLocation(9, 46) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Theory] @@ -5364,8 +5237,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.TargetMethod.ToTestDisplayString()); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp1).VerifyDiagnostics(); @@ -5398,8 +5270,11 @@ public interface I1 "; var comp2 = CreateCompilation(source2, options: TestOptions.DebugExe, parseOptions: parseOptions); - CompileAndVerify(comp2, - expectedOutput: @"System.Object (i1, value) => i1.Test(""name"", value)").VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // var expr = GetExpression((I1 i1, dynamic value) => i1.Test("name", value)); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, @"i1.Test(""name"", value)").WithLocation(9, 60) + ); string source3 = @" #nullable enable @@ -5425,19 +5300,15 @@ class JsonSerializer "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp, parseOptions: parseOptions); - comp3.VerifyDiagnostics( - // (9,46): warning CS8604: Possible null reference argument for parameter 'c' in 'C JsonSerializer.Deserialize(Stream c)'. - // return JsonSerializer.Deserialize(result); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "result").WithArguments("c", "C JsonSerializer.Deserialize(Stream c)").WithLocation(9, 46) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Theory] @@ -5470,17 +5341,21 @@ static class Extensions var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("? result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"new C().Test(""name"", d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); - AssertEx.Equal(@"System.Int32 C.Test(System.String name, System.Object value)", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + Assert.True(typeInfo.Type.IsErrorType()); + Assert.True(typeInfo.ConvertedType.IsErrorType()); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (7,22): error CS1973: 'C' has no applicable method named 'Test' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax. + // var result = new C().Test("name", d); + Diagnostic(ErrorCode.ERR_BadArgTypeDynamicExtension, @"new C().Test(""name"", d)").WithArguments("C", "Test").WithLocation(7, 22) + ); } [Fact] @@ -5507,17 +5382,21 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"Test(name: ""name"", d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); AssertEx.Equal(@"System.Int32 C.Test(System.String name, System.Object value)", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (7,41): error CS8324: Named argument specifications must appear after all fixed arguments have been specified in a dynamic invocation. + // var result = Test(name: "name", d); + Diagnostic(ErrorCode.ERR_NamedArgumentSpecificationBeforeFixedArgumentInDynamicInvocation, "d").WithLocation(7, 41) + ); } [Fact] @@ -5547,17 +5426,21 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"Test(&name, d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); AssertEx.Equal("System.Int32 C.Test(System.String* name, System.Object value)", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123", verify: Verification.Skipped).VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (10,27): error CS1978: Cannot use an expression of type 'string*' as an argument to a dynamically dispatched operation. + // var result = Test(&name, d); + Diagnostic(ErrorCode.ERR_BadDynamicMethodArg, "&name").WithArguments("string*").WithLocation(10, 27) + ); } [Theory] @@ -5587,20 +5470,24 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"Test(""name"", d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); AssertEx.Equal(@"System.Int32 C.Test(System.String name, System.Object value, params System.Collections.Generic.List list)", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (7,22): error CS9218: 'C.Test(string, object, params List)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // var result = Test("name", d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, @"Test(""name"", d)").WithArguments("C.Test(string, object, params System.Collections.Generic.List)").WithLocation(7, 22) + ); } [Fact] @@ -5637,7 +5524,7 @@ static void Main() AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); @@ -5662,11 +5549,7 @@ static void Test1(int x) {} var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardAndCSharp); - comp.VerifyDiagnostics( - // (7,13): error CS0815: Cannot assign void to an implicitly-typed variable - // var a = Test1(d); - Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, "a = Test1(d)").WithArguments("void").WithLocation(7, 13) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -5695,9 +5578,13 @@ public static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (7,9): error CS1059: The operand of an increment or decrement operator must be a variable, property or indexer + // Test1(d)++; + Diagnostic(ErrorCode.ERR_IncrementLvalueExpected, "Test1(d)").WithLocation(7, 9) + ); } [Fact] @@ -5729,9 +5616,16 @@ public static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32* a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "1", verify: Verification.Skipped).VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (10,10): error CS0193: The * or -> operator must be applied to a pointer + // (*Test1(d))++; + Diagnostic(ErrorCode.ERR_PtrExpected, "*Test1(d)").WithLocation(10, 10), + // (12,34): error CS0193: The * or -> operator must be applied to a pointer + // System.Console.WriteLine(*a); + Diagnostic(ErrorCode.ERR_PtrExpected, "*a").WithLocation(12, 34) + ); } [Theory] @@ -5807,8 +5701,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.TargetMethod.ToTestDisplayString()); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp).VerifyDiagnostics(); @@ -5839,17 +5732,21 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"Test(name: ""name"", d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); AssertEx.Equal(@"System.Int32 C.D.Invoke(System.String name, System.Object value)", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (7,41): error CS8324: Named argument specifications must appear after all fixed arguments have been specified in a dynamic invocation. + // var result = Test(name: "name", d); + Diagnostic(ErrorCode.ERR_NamedArgumentSpecificationBeforeFixedArgumentInDynamicInvocation, "d").WithLocation(7, 41) + ); } [Fact] @@ -5880,17 +5777,21 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"Test(&name, d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); AssertEx.Equal("System.Int32 C.D.Invoke(System.String* name, System.Object value)", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123", verify: Verification.Skipped).VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (10,27): error CS1978: Cannot use an expression of type 'string*' as an argument to a dynamically dispatched operation. + // var result = Test(&name, d); + Diagnostic(ErrorCode.ERR_BadDynamicMethodArg, "&name").WithArguments("string*").WithLocation(10, 27) + ); } [Theory] @@ -5921,20 +5822,24 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var call = tree.GetRoot().DescendantNodes().OfType().First(); AssertEx.Equal(@"Test(""name"", d)", call.ToString()); symbolInfo = model.GetSymbolInfo(call); AssertEx.Equal(@"System.Int32 C.D.Invoke(System.String name, System.Object value, params System.Collections.Generic.List list)", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(call); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (7,22): error CS9218: 'C.D.Invoke(string, object, params List)' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // var result = Test("name", d); + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, @"Test(""name"", d)").WithArguments("C.D.Invoke(string, object, params System.Collections.Generic.List)").WithLocation(7, 22) + ); } [Fact] @@ -5972,7 +5877,7 @@ static void Main() AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IInvocationOperation)model.GetOperation(call); + var operation = (IDynamicInvocationOperation)model.GetOperation(call); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); @@ -5999,11 +5904,7 @@ public static void Main() var comp = CreateCompilation(source, targetFramework: TargetFramework.StandardAndCSharp); - comp.VerifyDiagnostics( - // (7,13): error CS0815: Cannot assign void to an implicitly-typed variable - // var a = Test1(d); - Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, "a = Test1(d)").WithArguments("void").WithLocation(7, 13) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -6034,9 +5935,13 @@ public static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (7,9): error CS1059: The operand of an increment or decrement operator must be a variable, property or indexer + // Test1(d)++; + Diagnostic(ErrorCode.ERR_IncrementLvalueExpected, "Test1(d)").WithLocation(7, 9) + ); } [Fact] @@ -6069,9 +5974,16 @@ public static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32* a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "1", verify: Verification.Skipped).VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (10,10): error CS0193: The * or -> operator must be applied to a pointer + // (*Test1(d))++; + Diagnostic(ErrorCode.ERR_PtrExpected, "*Test1(d)").WithLocation(10, 10), + // (12,34): error CS0193: The * or -> operator must be applied to a pointer + // System.Console.WriteLine(*a); + Diagnostic(ErrorCode.ERR_PtrExpected, "*a").WithLocation(12, 34) + ); } [Theory] @@ -6123,8 +6035,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.Property.ToTestDisplayString()); + var operation = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp).VerifyDiagnostics(); @@ -6157,8 +6068,11 @@ public interface I1 "; var comp2 = CreateCompilation(source2, options: TestOptions.DebugExe, parseOptions: parseOptions); - CompileAndVerify(comp2, - expectedOutput: @"System.Object (i1, value) => Convert(i1.get_Item(""name"", value)" + (ExecutionConditionUtil.IsMonoOrCoreClr ? ", Object)" : ")")).VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // var expr = GetExpression((I1 i1, dynamic value) => i1["name", value]); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, @"i1[""name"", value]").WithLocation(9, 60) + ); string source3 = @" #nullable enable @@ -6184,19 +6098,15 @@ class JsonSerializer "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp, parseOptions: parseOptions); - comp3.VerifyDiagnostics( - // (9,46): warning CS8604: Possible null reference argument for parameter 'c' in 'C JsonSerializer.Deserialize(Stream c)'. - // return JsonSerializer.Deserialize(result); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "result").WithArguments("c", "C JsonSerializer.Deserialize(Stream c)").WithLocation(9, 46) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Theory] @@ -6248,8 +6158,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.Property.ToTestDisplayString()); + var operation = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp).VerifyDiagnostics(); @@ -6282,8 +6191,11 @@ public interface I1 "; var comp2 = CreateCompilation(source2, options: TestOptions.DebugExe, parseOptions: parseOptions); - CompileAndVerify(comp2, - expectedOutput: @"System.Object (i1, value) => Convert(i1.get_Item(""name"", value)" + (ExecutionConditionUtil.IsMonoOrCoreClr ? ", Object)" : ")")).VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // var expr = GetExpression((I1 i1, dynamic value) => i1["name", value]); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, @"i1[""name"", value]").WithLocation(9, 60) + ); string source3 = @" #nullable enable @@ -6309,19 +6221,15 @@ class JsonSerializer "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp, parseOptions: parseOptions); - comp3.VerifyDiagnostics( - // (9,46): warning CS8604: Possible null reference argument for parameter 'c' in 'C JsonSerializer.Deserialize(Stream c)'. - // return JsonSerializer.Deserialize(result); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "result").WithArguments("c", "C JsonSerializer.Deserialize(Stream c)").WithLocation(9, 46) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -6370,8 +6278,7 @@ class JsonSerializer AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.Property.ToTestDisplayString()); + var operation = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); CompileAndVerify(comp).VerifyDiagnostics(); @@ -6404,8 +6311,11 @@ public interface I1 "; var comp2 = CreateCompilation(source2, options: TestOptions.DebugExe); - CompileAndVerify(comp2, - expectedOutput: @"System.Object (i1, value) => i1.get_Item(""name"", value)").VerifyDiagnostics(); + comp2.VerifyDiagnostics( + // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // var expr = GetExpression((I1 i1, dynamic value) => i1["name", value]); + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, @"i1[""name"", value]").WithLocation(9, 60) + ); string source3 = @" #nullable enable @@ -6431,19 +6341,15 @@ class JsonSerializer "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (9,46): warning CS8604: Possible null reference argument for parameter 'c' in 'C JsonSerializer.Deserialize(Stream c)'. - // return JsonSerializer.Deserialize(result); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "result").WithArguments("c", "C JsonSerializer.Deserialize(Stream c)").WithLocation(9, 46) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -6480,11 +6386,10 @@ static void Main() AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var operation = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), operation.Property.ToTestDisplayString()); + var operation = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + CompileAndVerify(comp1).VerifyDiagnostics(); } [Fact] @@ -6514,20 +6419,23 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.String* name, System.Object value] { get; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); - CompileAndVerify(comp1, expectedOutput: "123", verify: Verification.Skipped).VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (10,30): error CS1978: Cannot use an expression of type 'string*' as an argument to a dynamically dispatched operation. + // var result = new C()[&name, d]; + Diagnostic(ErrorCode.ERR_BadDynamicMethodArg, "&name").WithArguments("string*").WithLocation(10, 30) + ); } [Theory] @@ -6558,20 +6466,23 @@ static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "result").Single(); var model = comp1.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 result", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic result", symbolInfo.Symbol.ToTestDisplayString()); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.String name, System.Object value, params System.Collections.Generic.List list] { get; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); - CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); + comp1.VerifyDiagnostics( + // (7,22): error CS9218: 'C.this[string, object, params List]' is applicable only with expanded form of non-array params collection which is not supported during dynamic dispatch. + // var result = new C()["name", d]; + Diagnostic(ErrorCode.ERR_DynamicDispatchToParamsCollection, @"new C()[""name"", d]").WithArguments("C.this[string, object, params System.Collections.Generic.List]").WithLocation(7, 22) + ); } [Fact] @@ -6608,8 +6519,7 @@ static void Main() AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); CompileAndVerify(comp1, expectedOutput: "123").VerifyDiagnostics(); @@ -6642,7 +6552,7 @@ public static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); TypeInfo typeInfo; @@ -6651,20 +6561,19 @@ public static void Main() symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); } var increment = tree.GetRoot().DescendantNodes().OfType().Single(); typeInfo = model.GetTypeInfo(increment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "1").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); } [Fact] @@ -6697,7 +6606,7 @@ public static void Main() var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32* a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); TypeInfo typeInfo; @@ -6706,15 +6615,21 @@ public static void Main() symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32* C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32*", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32*", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); } - CompileAndVerify(comp, expectedOutput: "1", verify: Verification.Skipped).VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (11,10): error CS0193: The * or -> operator must be applied to a pointer + // (*c[d])++; + Diagnostic(ErrorCode.ERR_PtrExpected, "*c[d]").WithLocation(11, 10), + // (13,34): error CS0193: The * or -> operator must be applied to a pointer + // System.Console.WriteLine(*a); + Diagnostic(ErrorCode.ERR_PtrExpected, "*a").WithLocation(13, 34) + ); } [Fact] @@ -6766,11 +6681,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -6779,7 +6693,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); @@ -6816,11 +6730,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -6883,8 +6793,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -6894,13 +6803,13 @@ static void Print(dynamic b) var operation = (IAssignmentOperation)model.GetOperation(assignment); AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); @@ -6930,11 +6839,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -6995,11 +6900,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -7008,14 +6912,14 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); @@ -7046,11 +6950,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (12,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(12, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -7097,11 +6997,10 @@ System.IO.Stream this[int x] symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.IO.Stream C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.IO.Stream", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.IO.Stream", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -7110,20 +7009,16 @@ System.IO.Stream this[int x] AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.IO.Stream", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.IO.Stream", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("System.Object", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Object", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.IO.Stream", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("System.Object", typeInfo.ConvertedType.ToTestDisplayString()); - comp.VerifyDiagnostics( - // (9,24): error CS0266: Cannot implicitly convert type 'object' to 'System.IO.Stream'. An explicit conversion exists (are you missing a cast?) - // var a = c[d] = o; - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "o").WithArguments("object", "System.IO.Stream").WithLocation(9, 24) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -7164,34 +7059,33 @@ static void Print(dynamic b) var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic? a", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); string source3 = @" #nullable enable @@ -7218,18 +7112,14 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); } @@ -7282,11 +7172,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -7294,10 +7183,10 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - AssertEx.Equal("System.Int32 System.Int32.op_Addition(System.Int32 left, System.Int32 right)", symbolInfo.Symbol.ToTestDisplayString()); + AssertEx.Equal("dynamic dynamic.op_Addition(dynamic left, System.Int32 right)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (ICompoundAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); Assert.Null(operation.OperatorMethod); @@ -7335,22 +7224,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (10,17): warning CS0458: The result of the expression is always 'null' of type 'dynamic' - // var a = c[d] += (int?)null; - Diagnostic(ErrorCode.WRN_AlwaysNull, "c[d] += (int?)null").WithArguments("dynamic").WithLocation(10, 17), - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -7406,8 +7288,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -7520,11 +7401,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -7532,10 +7412,10 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - AssertEx.Equal("dynamic dynamic.op_Addition(System.Int32 left, dynamic right)", symbolInfo.Symbol.ToTestDisplayString()); + AssertEx.Equal("dynamic dynamic.op_Addition(dynamic left, dynamic right)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (ICompoundAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); Assert.Null(operation.OperatorMethod); @@ -7624,36 +7504,35 @@ class C2 {} var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("? a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("?", typeInfo.Type.ToTestDisplayString()); - Assert.True(typeInfo.Type.IsErrorType()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.False(typeInfo.Type.IsErrorType()); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("C2 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("?", typeInfo.Type.ToTestDisplayString()); - Assert.True(typeInfo.Type.IsErrorType()); - AssertEx.Equal("?", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.False(typeInfo.Type.IsErrorType()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - Assert.Null(symbolInfo.Symbol); + AssertEx.Equal("dynamic dynamic.op_Addition(dynamic left, C2 right)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (ICompoundAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("C2", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); AssertEx.Equal("C2", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("?", operation.Type.ToTestDisplayString()); - Assert.True(operation.Type.IsErrorType()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); + Assert.False(operation.Type.IsErrorType()); Assert.Null(operation.OperatorMethod); var right = assignment.Right; @@ -7661,11 +7540,7 @@ class C2 {} AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); - comp.VerifyDiagnostics( - // (9,17): error CS0019: Operator '+=' cannot be applied to operands of type 'C2' and 'C2' - // var a = c[d] += right; - Diagnostic(ErrorCode.ERR_BadBinaryOps, "c[d] += right").WithArguments("+=", "C2", "C2").WithLocation(9, 17) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -7706,36 +7581,35 @@ static void Print(dynamic b) var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic? a", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - AssertEx.Equal("System.Int32 System.Int32.op_Addition(System.Int32 left, System.Int32 right)", symbolInfo.Symbol.ToTestDisplayString()); + AssertEx.Equal("dynamic dynamic.op_Addition(dynamic left, System.Int32 right)", symbolInfo.Symbol.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); string source3 = @" #nullable enable @@ -7762,22 +7636,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (10,17): warning CS0458: The result of the expression is always 'null' of type 'int?' - // var a = c[d] += (int?)null; - Diagnostic(ErrorCode.WRN_AlwaysNull, "c[d] += (int?)null").WithArguments("int?").WithLocation(10, 17), - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -7829,11 +7696,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (PostfixUnaryExpressionSyntax)elementAccess.Parent; @@ -7841,10 +7707,10 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - AssertEx.Equal("System.Int32 System.Int32.op_Increment(System.Int32 value)", symbolInfo.Symbol.ToTestDisplayString()); + AssertEx.Equal("dynamic dynamic.op_Increment(dynamic value)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (IIncrementOrDecrementOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); Assert.Null(operation.OperatorMethod); @@ -7876,19 +7742,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -7943,8 +7805,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (PostfixUnaryExpressionSyntax)elementAccess.Parent; @@ -7987,19 +7848,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -8038,42 +7895,37 @@ class C2 {} var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("? a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("?", typeInfo.Type.ToTestDisplayString()); - Assert.True(typeInfo.Type.IsErrorType()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.False(typeInfo.Type.IsErrorType()); Assert.Equal(CodeAnalysis.NullableFlowState.None, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("C2 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (PostfixUnaryExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("?", typeInfo.Type.ToTestDisplayString()); - Assert.True(typeInfo.Type.IsErrorType()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.False(typeInfo.Type.IsErrorType()); Assert.Equal(typeInfo.Type, typeInfo.ConvertedType); symbolInfo = model.GetSymbolInfo(assignment); - Assert.Null(symbolInfo.Symbol); + AssertEx.Equal("dynamic dynamic.op_Increment(dynamic value)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (IIncrementOrDecrementOperation)model.GetOperation(assignment); - AssertEx.Equal("C2", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("?", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); Assert.Null(operation.OperatorMethod); - comp.VerifyDiagnostics( - // (8,17): error CS0023: Operator '++' cannot be applied to operand of type 'C2' - // var a = c[d]++; - Diagnostic(ErrorCode.ERR_BadUnaryOp, "c[d]++").WithArguments("++", "C2").WithLocation(8, 17) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -8125,11 +7977,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (PrefixUnaryExpressionSyntax)elementAccess.Parent; @@ -8137,10 +7988,10 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - AssertEx.Equal("System.Int32 System.Int32.op_Increment(System.Int32 value)", symbolInfo.Symbol.ToTestDisplayString()); + AssertEx.Equal("dynamic dynamic.op_Increment(dynamic value)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (IIncrementOrDecrementOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); Assert.Null(operation.OperatorMethod); @@ -8172,19 +8023,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -8239,8 +8086,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (PrefixUnaryExpressionSyntax)elementAccess.Parent; @@ -8283,19 +8129,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("dynamic?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -8336,36 +8178,35 @@ static void Print(dynamic b) var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic? a", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (PrefixUnaryExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); symbolInfo = model.GetSymbolInfo(assignment); - AssertEx.Equal("System.Int32 System.Int32.op_Increment(System.Int32 value)", symbolInfo.Symbol.ToTestDisplayString()); + AssertEx.Equal("dynamic dynamic.op_Increment(dynamic value)", symbolInfo.Symbol.ToTestDisplayString()); var operation = (IIncrementOrDecrementOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); Assert.Null(operation.OperatorMethod); - CompileAndVerify(comp, expectedOutput: "3 3").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); string source3 = @" #nullable enable @@ -8392,19 +8233,15 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -8456,11 +8293,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.String C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.String", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -8469,14 +8305,14 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.String", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.String", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); @@ -8506,11 +8342,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -8570,11 +8402,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32? C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32?", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -8583,14 +8414,14 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32?", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); @@ -8620,11 +8451,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -8687,8 +8514,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -8734,11 +8560,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -8799,11 +8621,10 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.String C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.String", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -8812,14 +8633,14 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.String", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); @@ -8850,11 +8671,7 @@ static void Print(dynamic b) } "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (12,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a").WithArguments("b", "void C.Print(dynamic b)").WithLocation(12, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); @@ -8907,43 +8724,34 @@ class C2 {} var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("C2? a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic? a", symbolInfo.Symbol.ToTestDisplayString()); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("C2? C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("C2?", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2?", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("?", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("?", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("C2?", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("?", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.String", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.String", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - // The unexpected nullability warning is pre-existing condition - https://github.com/dotnet/roslyn/issues/72912 - comp.VerifyDiagnostics( - // (10,17): error CS0019: Operator '??=' cannot be applied to operands of type 'C2' and 'string' - // var a = c[d] ??= "2"; - Diagnostic(ErrorCode.ERR_BadBinaryOps, @"c[d] ??= ""2""").WithArguments("??=", "C2", "string").WithLocation(10, 17), - // (10,26): warning CS8619: Nullability of reference types in value of type 'string' doesn't match target type 'C2'. - // var a = c[d] ??= "2"; - Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, @"""2""").WithArguments("string", "C2").WithLocation(10, 26) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -8985,39 +8793,34 @@ struct C2 {} var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("? a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic a", symbolInfo.Symbol.ToTestDisplayString()); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("C2 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("?", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("?", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("C2", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("C2", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("?", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - comp.VerifyDiagnostics( - // (8,17): error CS0019: Operator '??=' cannot be applied to operands of type 'C2' and 'C2' - // var a = c[d] ??= new C2(); - Diagnostic(ErrorCode.ERR_BadBinaryOps, "c[d] ??= new C2()").WithArguments("??=", "C2", "C2").WithLocation(8, 17) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -9058,39 +8861,38 @@ static void Print(dynamic b) var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic? a", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32? C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32?", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32?", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "2 2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); } [Fact] @@ -9123,29 +8925,28 @@ int this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); @@ -9180,10 +8981,7 @@ static void Print(Expression> expr) comp2.VerifyDiagnostics( // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = 2 }); - Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d) => new C() { [d] = 2 }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60) + Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59) ); } @@ -9217,13 +9015,12 @@ dynamic this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("dynamic C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -9274,10 +9071,7 @@ static void Print(Expression> expr) comp2.VerifyDiagnostics( // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = 2 }); - Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d) => new C() { [d] = 2 }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60) + Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59) ); } @@ -9312,29 +9106,28 @@ int this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); @@ -9369,13 +9162,7 @@ static void Print(Expression> expr) comp2.VerifyDiagnostics( // (9,70): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d, dynamic v) => new C() { [d] = v }); - Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 70), - // (9,71): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d, dynamic v) => new C() { [d] = v }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 71), - // (9,76): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d, dynamic v) => new C() { [d] = v }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "v").WithLocation(9, 76) + Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 70) ); } @@ -9409,35 +9196,30 @@ int this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.String", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - comp.VerifyDiagnostics( - // (7,33): error CS0029: Cannot implicitly convert type 'string' to 'int' - // var c = new C() { [d] = "2" }; - Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""2""").WithArguments("string", "int").WithLocation(7, 33) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -9470,33 +9252,30 @@ ref int this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - // IInvalidOperation is pre-existing condition - https://github.com/dotnet/roslyn/issues/72916 - var propertyRef = (IInvalidOperation)model.GetOperation(elementAccess); - //var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - //AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IAssignmentOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); var right = assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); } [Fact] @@ -9534,13 +9313,12 @@ class C2 var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("C2 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -9590,9 +9368,6 @@ class C2 // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60), // (9,67): error CS1963: An expression tree may not contain a dynamic operation // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "F").WithLocation(9, 67) @@ -9659,13 +9434,12 @@ class C2 var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("dynamic C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -9715,9 +9489,6 @@ class C2 // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60), // (9,67): error CS1963: An expression tree may not contain a dynamic operation // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "F").WithLocation(9, 67) @@ -9783,24 +9554,23 @@ class C2 var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("ref C2 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IMemberInitializerOperation)model.GetOperation(assignment); - AssertEx.Equal("C2", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); string source2 = @" using System; @@ -9838,12 +9608,9 @@ class C2 // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,59): error CS8153: An expression tree lambda may not contain a call to a method, property, or indexer that returns by reference - // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); - Diagnostic(ErrorCode.ERR_RefReturningCallInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // (9,67): error CS1963: An expression tree may not contain a dynamic operation // var expr = GetExpression((dynamic d) => new C() { [d] = { F = 2 } }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60) + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "F").WithLocation(9, 67) ); string source3 = @" @@ -9868,11 +9635,7 @@ class C2 "; var comp3 = CreateCompilation(source3, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (7,35): error CS0117: 'C2' does not contain a definition for 'F' - // var c = new C() { [d] = { F = 2 } }; - Diagnostic(ErrorCode.ERR_NoSuchMember, "F").WithArguments("C2", "F").WithLocation(7, 35) - ); + comp3.VerifyEmitDiagnostics(); } [Fact] @@ -9905,13 +9668,12 @@ System.Collections.Generic.List this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("System.Collections.Generic.List C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -9956,9 +9718,6 @@ static void Print(Expression> expr) // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60), // (9,66): error CS1963: An expression tree may not contain a dynamic operation // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "2").WithLocation(9, 66) @@ -10020,13 +9779,12 @@ dynamic this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("dynamic C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; @@ -10071,9 +9829,6 @@ static void Print(Expression> expr) // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation - // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60), // (9,66): error CS1963: An expression tree may not contain a dynamic operation // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "2").WithLocation(9, 66) @@ -10135,24 +9890,23 @@ ref System.Collections.Generic.List this[int x] var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); var symbolInfo = model.GetSymbolInfo(elementAccess); - AssertEx.Equal("ref System.Collections.Generic.List C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Null(symbolInfo.Symbol); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Collections.Generic.List", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Collections.Generic.List", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("System.Collections.Generic.List", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Collections.Generic.List", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var operation = (IMemberInitializerOperation)model.GetOperation(assignment); - AssertEx.Equal("System.Collections.Generic.List", operation.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", operation.Type.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); string source2 = @" using System; @@ -10185,12 +9939,9 @@ static void Print(Expression> expr) // (9,59): error CS8074: An expression tree lambda may not contain a dictionary initializer. // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); Diagnostic(ErrorCode.ERR_DictionaryInitializerInExpressionTree, "[d]").WithLocation(9, 59), - // (9,59): error CS8153: An expression tree lambda may not contain a call to a method, property, or indexer that returns by reference - // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); - Diagnostic(ErrorCode.ERR_RefReturningCallInExpressionTree, "[d]").WithLocation(9, 59), - // (9,60): error CS1963: An expression tree may not contain a dynamic operation + // (9,66): error CS1963: An expression tree may not contain a dynamic operation // var expr = GetExpression((dynamic d) => new C() { [d] = {2} }); - Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "d").WithLocation(9, 60) + Diagnostic(ErrorCode.ERR_ExpressionTreeContainsDynamicOperation, "2").WithLocation(9, 66) ); string source3 = @" @@ -10215,11 +9966,7 @@ class C2 "; var comp3 = CreateCompilation(source3, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (7,33): error CS1922: Cannot initialize type 'C2' with a collection initializer because it does not implement 'System.Collections.IEnumerable' - // var c = new C() { [d] = {2} }; - Diagnostic(ErrorCode.ERR_CollectionInitRequiresIEnumerable, "{2}").WithArguments("C2").WithLocation(7, 33) - ); + comp3.VerifyEmitDiagnostics(); } [Fact] @@ -10276,17 +10023,16 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; var tupleTypeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); @@ -10303,12 +10049,12 @@ static void Print(dynamic b) var right = (TupleExpressionSyntax)assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var rightElement = right.Arguments[0].Expression; typeInfo = model.GetTypeInfo(rightElement); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); @@ -10408,8 +10154,7 @@ static void Print(dynamic b) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; @@ -10534,17 +10279,16 @@ static void Print(dynamic b) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; var tupleTypeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); @@ -10561,12 +10305,12 @@ static void Print(dynamic b) var right = (TupleExpressionSyntax)assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var rightElement = right.Arguments[0].Expression; typeInfo = model.GetTypeInfo(rightElement); AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); @@ -10634,11 +10378,7 @@ int this[int x] var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); - comp.VerifyDiagnostics( - // (8,30): error CS0029: Cannot implicitly convert type 'string' to 'int' - // var a = (c[d], _) = ("2", 123); - Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""2""").WithArguments("string", "int").WithLocation(8, 30) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -10679,36 +10419,35 @@ static void Print(dynamic b) var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").First(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("(System.Int32, System.Int32) a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("(dynamic, System.Int32) a", symbolInfo.Symbol.ToTestDisplayString()); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "Item1").Single(); symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 (System.Int32, System.Int32).Item1", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic (dynamic, System.Int32).Item1", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; var tupleTypeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); Assert.True(model.GetDeconstructionInfo(assignment) is { Method: null, Conversion: null, Nested: [{ Method: null, Conversion: { IsIdentity: true }, Nested: [] }, _] }); @@ -10720,14 +10459,14 @@ static void Print(dynamic b) var right = (TupleExpressionSyntax)assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var rightElement = right.Arguments[0].Expression; typeInfo = model.GetTypeInfo(rightElement); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics(); string source3 = @" #nullable enable @@ -10755,19 +10494,15 @@ static void Print(dynamic b) "; var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); - comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a.Item1); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a.Item1").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) - ); + comp3.VerifyDiagnostics(); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "Item1").Single(); model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -10832,24 +10567,23 @@ public void Deconstruct(out int x, out int y) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; var tupleTypeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); - Assert.True(model.GetDeconstructionInfo(assignment) is { Method: not null, Conversion: null, Nested: [{ Method: null, Conversion: { IsIdentity: true }, Nested: [] }, _] }); + Assert.True(model.GetDeconstructionInfo(assignment) is { Method: not null, Conversion: null, Nested: [{ Method: null, Conversion: { IsBoxing: true }, Nested: [] }, _] }); var operation = (IDeconstructionAssignmentOperation)model.GetOperation(assignment); Assert.Equal(tupleTypeInfo.Type, operation.Target.Type); @@ -10861,7 +10595,11 @@ public void Deconstruct(out int x, out int y) AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); + CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics( + // (10,18): warning CS8624: Argument of type 'dynamic' cannot be used as an output of type 'int' for parameter 'x' in 'void C2.Deconstruct(out int x, out int y)' due to differences in the nullability of reference types. + // var a = (c[d], _) = new C2(); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput, "c[d]").WithArguments("dynamic", "int", "x", "void C2.Deconstruct(out int x, out int y)").WithLocation(10, 18) + ); string source3 = @" #nullable enable @@ -10899,7 +10637,11 @@ public void Deconstruct(out int? x, out int y) var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); // Nullability is not tracked across deconstruction, this is a pre-existing condition - https://github.com/dotnet/roslyn/issues/33011 - comp3.VerifyDiagnostics(); + comp3.VerifyDiagnostics( + // (10,18): warning CS8624: Argument of type 'dynamic' cannot be used as an output of type 'int?' for parameter 'x' in 'void C2.Deconstruct(out int? x, out int y)' due to differences in the nullability of reference types. + // var a = (c[d], _) = new C2(); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput, "c[d]").WithArguments("dynamic", "int?", "x", "void C2.Deconstruct(out int? x, out int y)").WithLocation(10, 18) + ); tree = comp3.SyntaxTrees.Single(); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "Item1").Single(); @@ -10976,8 +10718,7 @@ public void Deconstruct(out int x, out int y) AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; @@ -11105,12 +10846,7 @@ public void Deconstruct(out dynamic x, out int y) var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); - // The unexpected error is a pre-existing condition - https://github.com/dotnet/roslyn/issues/72914 - comp.VerifyDiagnostics( - // (10,18): error CS0266: Cannot implicitly convert type 'dynamic' to 'int'. An explicit conversion exists (are you missing a cast?) - // var a = (c[d], _) = new C2(); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c[d]").WithArguments("dynamic", "int").WithLocation(10, 18) - ); + CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); string source3 = @" #nullable enable @@ -11122,7 +10858,10 @@ public static void Main() dynamic d = 1; var c = new C(); var a = (c[d], _) = new C2(); + System.Console.Write(a); Print(a.Item1); + System.Console.Write("" ""); + System.Console.Write(c._test1); } int? _test1 = 0; @@ -11145,14 +10884,9 @@ public void Deconstruct(out dynamic? x, out int y) } } "; - var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); + var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.ReleaseExe); - // The unexpected error is a pre-existing condition - https://github.com/dotnet/roslyn/issues/72914 - comp3.VerifyDiagnostics( - // (10,18): error CS0266: Cannot implicitly convert type 'dynamic' to 'int?'. An explicit conversion exists (are you missing a cast?) - // var a = (c[d], _) = new C2(); - Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "c[d]").WithArguments("dynamic", "int?").WithLocation(10, 18) - ); + CompileAndVerify(comp3, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); } [Fact] @@ -11188,11 +10922,7 @@ public void Deconstruct(out string x, out int y) var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); - comp.VerifyDiagnostics( - // (8,18): error CS0029: Cannot implicitly convert type 'string' to 'int' - // var a = (c[d], _) = new C2(); - Diagnostic(ErrorCode.ERR_NoImplicitConv, "c[d]").WithArguments("string", "int").WithLocation(8, 18) - ); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -11241,38 +10971,37 @@ public void Deconstruct(out int x, out int y) var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").First(); var model = comp.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("(System.Int32, System.Int32) a", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("(dynamic, System.Int32) a", symbolInfo.Symbol.ToTestDisplayString()); node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "Item1").Single(); symbolInfo = model.GetSymbolInfo(node); - Assert.Equal("System.Int32 (System.Int32, System.Int32).Item1", symbolInfo.Symbol.ToTestDisplayString()); + Assert.Equal("dynamic (dynamic, System.Int32).Item1", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); - var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); - AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + var propertyRef = (IDynamicIndexerAccessOperation)model.GetOperation(elementAccess); Assert.Equal(typeInfo.Type, propertyRef.Type); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; var tupleTypeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", tupleTypeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); - Assert.True(model.GetDeconstructionInfo(assignment) is { Method: not null, Conversion: null, Nested: [{ Method: null, Conversion: { IsIdentity: true }, Nested: [] }, _] }); + Assert.True(model.GetDeconstructionInfo(assignment) is { Method: not null, Conversion: null, Nested: [{ Method: null, Conversion: { IsBoxing: true }, Nested: [] }, _] }); var operation = (IDeconstructionAssignmentOperation)model.GetOperation(assignment); Assert.Equal(tupleTypeInfo.Type, operation.Target.Type); @@ -11284,7 +11013,11 @@ public void Deconstruct(out int x, out int y) AssertEx.Equal("C2", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("C2", typeInfo.ConvertedType.ToTestDisplayString()); - CompileAndVerify(comp, expectedOutput: "(2, 123) 2").VerifyDiagnostics(); + CompileAndVerify(comp).VerifyDiagnostics( + // (10,18): warning CS8624: Argument of type 'dynamic' cannot be used as an output of type 'int' for parameter 'x' in 'void C2.Deconstruct(out int x, out int y)' due to differences in the nullability of reference types. + // var a = (c[d], _) = new C2(); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput, "c[d]").WithArguments("dynamic", "int", "x", "void C2.Deconstruct(out int x, out int y)").WithLocation(10, 18) + ); string source3 = @" #nullable enable @@ -11321,9 +11054,9 @@ public void Deconstruct(out int? x, out int y) var comp3 = CreateCompilation(source3, targetFramework: TargetFramework.StandardAndCSharp); comp3.VerifyDiagnostics( - // (11,15): warning CS8604: Possible null reference argument for parameter 'b' in 'void C.Print(dynamic b)'. - // Print(a.Item1); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "a.Item1").WithArguments("b", "void C.Print(dynamic b)").WithLocation(11, 15) + // (10,18): warning CS8624: Argument of type 'dynamic' cannot be used as an output of type 'int?' for parameter 'x' in 'void C2.Deconstruct(out int? x, out int y)' due to differences in the nullability of reference types. + // var a = (c[d], _) = new C2(); + Diagnostic(ErrorCode.WRN_NullabilityMismatchInArgumentForOutput, "c[d]").WithArguments("dynamic", "int?", "x", "void C2.Deconstruct(out int? x, out int y)").WithLocation(10, 18) ); tree = comp3.SyntaxTrees.Single(); @@ -11331,8 +11064,8 @@ public void Deconstruct(out int? x, out int y) model = comp3.GetSemanticModel(tree); typeInfo = model.GetTypeInfo(node); - AssertEx.Equal("System.Int32?", typeInfo.Type.ToTestDisplayString()); - Assert.Equal(CodeAnalysis.NullableFlowState.MaybeNull, typeInfo.Nullability.FlowState); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + Assert.Equal(CodeAnalysis.NullableFlowState.NotNull, typeInfo.Nullability.FlowState); } [Fact] @@ -11373,18 +11106,18 @@ int this[int x] symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; typeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); left = (TupleExpressionSyntax)left.Parent.Parent; typeInfo = model.GetTypeInfo(left); - AssertEx.Equal("((System.Int32, System.Int32), System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("((System.Int32, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); @@ -11396,17 +11129,17 @@ int this[int x] var right = (TupleExpressionSyntax)assignment.Right; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("((System.Int32, System.Int32), System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("((System.Int32, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); right = (TupleExpressionSyntax)right.Arguments[0].Expression; typeInfo = model.GetTypeInfo(right); AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var rightElement = right.Arguments[0].Expression; typeInfo = model.GetTypeInfo(rightElement); AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); CompileAndVerify(comp, expectedOutput: "((2, 123), 124) 2").VerifyDiagnostics(); } @@ -11457,25 +11190,25 @@ public void Deconstruct(out int x, out int y) symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; typeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); left = (TupleExpressionSyntax)left.Parent.Parent; typeInfo = model.GetTypeInfo(left); - AssertEx.Equal("((System.Int32, System.Int32), System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("((System.Int32, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.Type.ToTestDisplayString()); AssertEx.Equal("((dynamic, System.Int32), System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); - Assert.True(model.GetDeconstructionInfo(assignment) is { Method: null, Conversion: null, Nested: [{ Method: not null, Conversion: null, Nested: [{ Method: null, Conversion: { IsIdentity: true }, Nested: [] }, _] }, _] }); + Assert.True(model.GetDeconstructionInfo(assignment) is { Method: null, Conversion: null, Nested: [{ Method: not null, Conversion: null, Nested: [{ Method: null, Conversion: { IsBoxing: true }, Nested: [] }, _] }, _] }); var right = (TupleExpressionSyntax)assignment.Right; typeInfo = model.GetTypeInfo(right); @@ -11535,13 +11268,13 @@ int this[int x] symbolInfo = model.GetSymbolInfo(elementAccess); AssertEx.Equal("System.Int32 C.this[System.Int32 x] { get; set; }", symbolInfo.Symbol.ToTestDisplayString()); var typeInfo = model.GetTypeInfo(elementAccess); - AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("dynamic", typeInfo.ConvertedType.ToTestDisplayString()); var left = (TupleExpressionSyntax)elementAccess.Parent.Parent; typeInfo = model.GetTypeInfo(left); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.Type.ToTestDisplayString()); - AssertEx.Equal("(System.Int32, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("(dynamic, System.Int32)", typeInfo.ConvertedType.ToTestDisplayString()); var assignment = (AssignmentExpressionSyntax)left.Parent; typeInfo = model.GetTypeInfo(assignment); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs index bb59d99fef196..fd120694a384c 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs @@ -3531,10 +3531,7 @@ public async static Task Test() System.Console.Write(x); } } -}").VerifyDiagnostics( - // (20,26): error CS8177: Async methods cannot have by-reference locals - // foreach (ref int x in new E()) - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x").WithLocation(20, 26)); +}").VerifyEmitDiagnostics(); } [Fact] @@ -3565,10 +3562,7 @@ public async static Task Test() System.Console.Write(x); } } -}").VerifyDiagnostics( - // (20,35): error CS8177: Async methods cannot have by-reference locals - // foreach (ref readonly int x in new E()) - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x").WithLocation(20, 35)); +}").VerifyEmitDiagnostics(); } [Fact] @@ -3597,10 +3591,7 @@ public static IEnumerable Test() yield return x; } } -}").VerifyDiagnostics( - // (18,26): error CS8176: Iterators cannot have by-reference locals - // foreach (ref int x in new E()) - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(18, 26)); +}").VerifyEmitDiagnostics(); } [Fact] @@ -3629,10 +3620,7 @@ public static IEnumerable Test() yield return x; } } -}").VerifyDiagnostics( - // (18,35): error CS8176: Iterators cannot have by-reference locals - // foreach (ref readonly int x in new E()) - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(18, 35)); +}").VerifyEmitDiagnostics(); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs index 601d65cdb6434..ec50444cfc588 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs @@ -240,9 +240,10 @@ public static void Main() }"; var comp = CreateCompilationWithIndexAndRangeAndSpan(src, TestOptions.ReleaseExe); comp.VerifyDiagnostics( - // (9,9): error CS0306: The type 'Span' may not be used as a type argument + // (9,9): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.Throws(Func)' // Throws(() => new Span(s.ToCharArray())[0..1]); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "Throws").WithArguments("System.Span").WithLocation(9, 9)); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Throws").WithArguments("C.Throws(System.Func)", "T", "System.Span").WithLocation(9, 9) + ); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs index 2d3ef41415b5f..3deff89e08733 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterpolationTests.cs @@ -3630,12 +3630,12 @@ ref struct S var comp = CreateCompilation(new[] { source, interpolatedStringBuilder }, options: TestOptions.UnsafeReleaseExe, targetFramework: TargetFramework.NetCoreApp); comp.VerifyDiagnostics( - // (6,11): error CS0306: The type 'int*' may not be used as a type argument + // 0.cs(6,11): error CS0306: The type 'int*' may not be used as a type argument // _ = $"{i}{s}"; Diagnostic(ErrorCode.ERR_BadTypeArgument, "{i}").WithArguments("int*").WithLocation(6, 11), - // (6,14): error CS0306: The type 'S' may not be used as a type argument + // 0.cs(6,14): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'DefaultInterpolatedStringHandler.AppendFormatted(T, int, string)' // _ = $"{i}{s}"; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "{s}").WithArguments("S").WithLocation(6, 5 + expression.Length) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "{s}").WithArguments("System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(T, int, string)", "T", "S").WithLocation(6, 5 + expression.Length) ); } @@ -4076,9 +4076,9 @@ ref struct S var comp = CreateCompilation(new[] { source, interpolatedStringBuilder }, targetFramework: TargetFramework.NetCoreApp); comp.VerifyDiagnostics( - // (5,21): error CS0306: The type 'S' may not be used as a type argument + // 0.cs(5,21): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'DefaultInterpolatedStringHandler.AppendFormatted(T)' // Console.WriteLine($"{s}"); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "{s}").WithArguments("S").WithLocation(5, 21) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "{s}").WithArguments("System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(T)", "T", "S").WithLocation(5, 21) ); } @@ -8543,7 +8543,7 @@ o in M verifier.VerifyDiagnostics(modifier == "ref readonly" ? new[] { - // 0.cs(8,5): warning CS9503: Argument 1 should be passed with 'ref' or 'in' keyword + // 0.cs(8,5): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword // C.M(i, ref s, out o, $"literal"); Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "i").WithArguments("1").WithLocation(8, 5) } @@ -14139,10 +14139,10 @@ public void AppendFormatted(dynamic d) verifier.VerifyIL("", @" { - // Code size 43 (0x2b) - .maxstack 3 + // Code size 128 (0x80) + .maxstack 9 .locals init (object V_0, //d - CustomHandler V_1) + CustomHandler V_1) IL_0000: ldc.i4.1 IL_0001: box ""int"" IL_0006: stloc.0 @@ -14153,12 +14153,39 @@ .locals init (object V_0, //d IL_0010: ldloca.s V_1 IL_0012: ldstr ""literal"" IL_0017: call ""void CustomHandler.AppendLiteral(dynamic)"" - IL_001c: ldloca.s V_1 - IL_001e: ldloc.0 - IL_001f: call ""void CustomHandler.AppendFormatted(dynamic)"" - IL_0024: ldloc.1 - IL_0025: call ""void Program.<
$>g__M|0_0(CustomHandler)"" - IL_002a: ret + IL_001c: ldsfld ""System.Runtime.CompilerServices.CallSite<<>A{00000008}> Program.<>o__0.<>p__0"" + IL_0021: brtrue.s IL_0062 + IL_0023: ldc.i4 0x100 + IL_0028: ldstr ""AppendFormatted"" + IL_002d: ldnull + IL_002e: ldtoken ""Program"" + IL_0033: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" + IL_0038: ldc.i4.2 + IL_0039: newarr ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo"" + IL_003e: dup + IL_003f: ldc.i4.0 + IL_0040: ldc.i4.s 9 + IL_0042: ldnull + IL_0043: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0048: stelem.ref + IL_0049: dup + IL_004a: ldc.i4.1 + IL_004b: ldc.i4.0 + IL_004c: ldnull + IL_004d: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)"" + IL_0052: stelem.ref + IL_0053: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable, System.Type, System.Collections.Generic.IEnumerable)"" + IL_0058: call ""System.Runtime.CompilerServices.CallSite<<>A{00000008}> System.Runtime.CompilerServices.CallSite<<>A{00000008}>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" + IL_005d: stsfld ""System.Runtime.CompilerServices.CallSite<<>A{00000008}> Program.<>o__0.<>p__0"" + IL_0062: ldsfld ""System.Runtime.CompilerServices.CallSite<<>A{00000008}> Program.<>o__0.<>p__0"" + IL_0067: ldfld ""<>A{00000008} System.Runtime.CompilerServices.CallSite<<>A{00000008}>.Target"" + IL_006c: ldsfld ""System.Runtime.CompilerServices.CallSite<<>A{00000008}> Program.<>o__0.<>p__0"" + IL_0071: ldloca.s V_1 + IL_0073: ldloc.0 + IL_0074: callvirt ""void <>A{00000008}.Invoke(System.Runtime.CompilerServices.CallSite, ref CustomHandler, dynamic)"" + IL_0079: ldloc.1 + IL_007a: call ""void Program.<
$>g__M|0_0(CustomHandler)"" + IL_007f: ret } "); } @@ -14422,74 +14449,12 @@ public override string ToString() } """; - var verifier = CompileAndVerify([source, InterpolatedStringHandlerAttribute], expectedOutput: "literalHello world!", targetFramework: TargetFramework.StandardAndCSharp); - verifier.VerifyDiagnostics(); - - verifier.VerifyIL("", type switch - { - "string" => """ - { - // Code size 110 (0x6e) - .maxstack 4 - .locals init (object V_0, //d - CustomInterpolationHandler V_1) - IL_0000: ldstr "Hello world!" - IL_0005: stloc.0 - IL_0006: ldloca.s V_1 - IL_0008: ldc.i4.7 - IL_0009: ldc.i4.1 - IL_000a: call "CustomInterpolationHandler..ctor(int, int)" - IL_000f: ldloca.s V_1 - IL_0011: ldstr "literal" - IL_0016: call "void CustomInterpolationHandler.AppendLiteral(string)" - IL_001b: ldloca.s V_1 - IL_001d: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0022: brtrue.s IL_0048 - IL_0024: ldc.i4.0 - IL_0025: ldtoken "string" - IL_002a: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_002f: ldtoken "Program" - IL_0034: call "System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)" - IL_0039: call "System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)" - IL_003e: call "System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)" - IL_0043: stsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0048: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_004d: ldfld "System.Func System.Runtime.CompilerServices.CallSite>.Target" - IL_0052: ldsfld "System.Runtime.CompilerServices.CallSite> Program.<>o__0.<>p__0" - IL_0057: ldloc.0 - IL_0058: callvirt "string System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)" - IL_005d: call "void CustomInterpolationHandler.AppendFormatted(string)" - IL_0062: ldloc.1 - IL_0063: call "string Program.<
$>g__Interpolate|0_0(CustomInterpolationHandler)" - IL_0068: call "void System.Console.WriteLine(string)" - IL_006d: ret - } - """, - _ => $$""" - { - // Code size 47 (0x2f) - .maxstack 3 - .locals init (object V_0, //d - CustomInterpolationHandler V_1) - IL_0000: ldstr "Hello world!" - IL_0005: stloc.0 - IL_0006: ldloca.s V_1 - IL_0008: ldc.i4.7 - IL_0009: ldc.i4.1 - IL_000a: call "CustomInterpolationHandler..ctor(int, int)" - IL_000f: ldloca.s V_1 - IL_0011: ldstr "literal" - IL_0016: call "void CustomInterpolationHandler.AppendLiteral(string)" - IL_001b: ldloca.s V_1 - IL_001d: ldloc.0 - IL_001e: call "void CustomInterpolationHandler.AppendFormatted({{type}})" - IL_0023: ldloc.1 - IL_0024: call "string Program.<
$>g__Interpolate|0_0(CustomInterpolationHandler)" - IL_0029: call "void System.Console.WriteLine(string)" - IL_002e: ret - } - """, - }); + var comp = CreateCompilation([source, InterpolatedStringHandlerAttribute], targetFramework: TargetFramework.StandardAndCSharp); + comp.VerifyDiagnostics( + // (7,31): error CS9230: Cannot perform a dynamic invocation on an expression with type 'CustomInterpolationHandler'. + // Console.WriteLine(Interpolate($"literal" + $"{d}")); + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, expression).WithArguments("CustomInterpolationHandler").WithLocation(7, 31) + ); } [Theory, CombinatorialData, WorkItem("https://github.com/dotnet/roslyn/issues/72606")] @@ -17225,9 +17190,14 @@ public void RefStructHandler_DynamicInHole(string expression) var comp = CreateCompilationWithCSharp(new[] { code, handler }); - // Note: We don't give any errors when mixing dynamic and ref structs today. If that ever changes, we should get an - // error here. This will crash at runtime because of this. - comp.VerifyEmitDiagnostics(); + comp.VerifyDiagnostics( + // 0.cs(4,19): error CS9230: Cannot perform a dynamic invocation on an expression with type 'CustomHandler'. + // CustomHandler c = $"{h1}" + $"{h2}"; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, expression).WithArguments("CustomHandler").WithLocation(4, 19), + // 0.cs(4,19): error CS9230: Cannot perform a dynamic invocation on an expression with type 'CustomHandler'. + // CustomHandler c = $"{h1}" + $"{h2}"; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, expression).WithArguments("CustomHandler").WithLocation(4, 19) + ); } [Theory] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs index 34be3f12005c3..06055448cc8b6 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs @@ -106,6 +106,168 @@ IEnumerable I() ); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72443")] + public void YieldInLock_Async() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + + public class C + { + public async Task ProcessValueAsync() + { + await foreach (int item in GetValuesAsync()) + { + await Task.Yield(); + Console.Write(item); + } + } + + private async IAsyncEnumerable GetValuesAsync() + { + await Task.Yield(); + lock (this) + { + for (int i = 0; i < 10; i++) + { + yield return i; + + if (i == 3) + { + yield break; + } + } + } + } + } + """ + AsyncStreamsTypes; + + var comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseDll.WithWarningLevel(8)); + CompileAndVerify(comp).VerifyDiagnostics(); + + var expectedDiagnostics = new[] + { + // (23,17): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return i; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(23, 17) + }; + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseDll.WithWarningLevel(9)); + CompileAndVerify(comp).VerifyDiagnostics(expectedDiagnostics); + + comp = CreateCompilationWithTasksExtensions(source, options: TestOptions.ReleaseDll); + CompileAndVerify(comp).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72443")] + public void YieldInLock_Sync() + { + var source = """ + using System; + using System.Collections.Generic; + using System.Threading; + + object o = new object(); + Console.WriteLine($"Before: {Monitor.IsEntered(o)}"); + using (IEnumerator e = GetValues(o).GetEnumerator()) + { + Console.WriteLine($"Inside: {Monitor.IsEntered(o)}"); + while (e.MoveNext()) + { + Console.WriteLine($"{e.Current}: {Monitor.IsEntered(o)}"); + } + Console.WriteLine($"Done: {Monitor.IsEntered(o)}"); + } + Console.WriteLine($"After: {Monitor.IsEntered(o)}"); + + static IEnumerable GetValues(object obj) + { + lock (obj) + { + for (int i = 0; i < 3; i++) + { + yield return i; + + if (i == 1) + { + yield break; + } + } + } + } + """; + + var expectedOutput = """ + Before: False + Inside: False + 0: True + 1: True + Done: False + After: False + """; + + CompileAndVerify(source, options: TestOptions.ReleaseExe.WithWarningLevel(8), + expectedOutput: expectedOutput).VerifyDiagnostics(); + + var expectedDiagnostics = new[] + { + // (24,13): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return i; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(24, 13) + }; + + CompileAndVerify(source, options: TestOptions.ReleaseExe.WithWarningLevel(9), + expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics); + + CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72443")] + public void YieldInLock_Nested() + { + var source = """ + using System.Collections.Generic; + + class C + { + IEnumerable M() + { + yield return 1; + lock (this) + { + yield return 2; + + local(); + + IEnumerable local() + { + yield return 3; + + lock (this) + { + yield return 4; + + yield break; + } + } + + yield break; + } + } + } + """; + + CreateCompilation(source).VerifyDiagnostics( + // (10,13): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return 2; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(10, 13), + // (20,21): warning CS9237: 'yield return' should not be used in the body of a lock statement + // yield return 4; + Diagnostic(ErrorCode.WRN_BadYieldInLock, "yield").WithLocation(20, 21)); + } + [WorkItem(546081, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546081")] [Fact] public void IteratorBlockWithUnreachableCode() diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs index 9b2f16c772425..2b32616b85553 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs @@ -5981,15 +5981,15 @@ static void Main() }"; var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview); comp.VerifyDiagnostics( - // (10,39): error CS4012: Parameters or locals of type 'TypedReference' cannot be declared in async methods or async lambda expressions. + // (10,39): error CS4012: Parameters of type 'TypedReference' cannot be declared in async methods or async lambda expressions. // D1 d1 = async (TypedReference r) => { await Task.Yield(); }; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "r").WithArguments("System.TypedReference").WithLocation(10, 39), - // (11,46): error CS4012: Parameters or locals of type 'RuntimeArgumentHandle' cannot be declared in async methods or async lambda expressions. + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "r").WithArguments("System.TypedReference").WithLocation(10, 39), + // (11,46): error CS4012: Parameters of type 'RuntimeArgumentHandle' cannot be declared in async methods or async lambda expressions. // D2 d2 = async (RuntimeArgumentHandle h) => { await Task.Yield(); }; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "h").WithArguments("System.RuntimeArgumentHandle").WithLocation(11, 46), - // (12,36): error CS4012: Parameters or locals of type 'ArgIterator' cannot be declared in async methods or async lambda expressions. + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "h").WithArguments("System.RuntimeArgumentHandle").WithLocation(11, 46), + // (12,36): error CS4012: Parameters of type 'ArgIterator' cannot be declared in async methods or async lambda expressions. // D3 d3 = async (ArgIterator i) => { await Task.Yield(); }; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "i").WithArguments("System.ArgIterator").WithLocation(12, 36)); + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "i").WithArguments("System.ArgIterator").WithLocation(12, 36)); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs index 74f8efa9b607c..7e4c694e57ba1 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs @@ -2394,21 +2394,52 @@ public unsafe IEnumerable M4(int* a) // (33,44): error CS1637: Iterators cannot have pointer type parameters // public unsafe IEnumerable M4(int* a) Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(33, 44), - // (33,36): error CS1629: Unsafe code may not appear in iterators + // (33,36): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // public unsafe IEnumerable M4(int* a) - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "M4").WithLocation(33, 36), - // (37,40): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "M4").WithArguments("ref and unsafe in async and iterator methods").WithLocation(33, 36), + // (37,40): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // IEnumerable Local(int* b) { yield break; } - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "int*").WithLocation(37, 40), - // (39,23): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("ref and unsafe in async and iterator methods").WithLocation(37, 40), + // (39,23): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // Local(&x); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "&x").WithLocation(39, 23), - // (39,17): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "&x").WithArguments("ref and unsafe in async and iterator methods").WithLocation(39, 23), + // (39,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // Local(&x); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "Local(&x)").WithLocation(39, 17), + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Local(&x)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(39, 17), // (37,45): error CS1637: Iterators cannot have pointer type parameters // IEnumerable Local(int* b) { yield break; } Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "b").WithLocation(37, 45)); + + var expectedDiagnostics = new[] + { + // (8,37): error CS1637: Iterators cannot have pointer type parameters + // IEnumerable Local(int* a) { yield break; } + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(8, 37), + // (17,41): error CS1637: Iterators cannot have pointer type parameters + // IEnumerable Local(int* x) { yield break; } + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "x").WithLocation(17, 41), + // (27,37): error CS1637: Iterators cannot have pointer type parameters + // IEnumerable Local(int* a) { yield break; } + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(27, 37), + // (33,44): error CS1637: Iterators cannot have pointer type parameters + // public unsafe IEnumerable M4(int* a) + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "a").WithLocation(33, 44), + // (37,40): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // IEnumerable Local(int* b) { yield break; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(37, 40), + // (37,45): error CS1637: Iterators cannot have pointer type parameters + // IEnumerable Local(int* b) { yield break; } + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "b").WithLocation(37, 45), + // (39,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // Local(&x); + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "Local(&x)").WithLocation(39, 17), + // (39,23): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // Local(&x); + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "&x").WithLocation(39, 23) + }; + + CreateCompilation(src, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.RegularNext.WithFeature("run-nullable-analysis", "never")).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(src, options: TestOptions.UnsafeDebugDll, parseOptions: TestOptions.RegularPreview.WithFeature("run-nullable-analysis", "never")).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -3516,7 +3547,7 @@ static void Main() // (10,31): error CS0190: The __arglist construct is valid only within a variable argument method // Console.WriteLine(__arglist); Diagnostic(ErrorCode.ERR_ArgsInvalid, "__arglist").WithLocation(10, 31), - // (18,31): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + // (18,31): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // Console.WriteLine(__arglist); Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(18, 31), // (24,20): error CS1669: __arglist is not valid in this context @@ -3528,7 +3559,7 @@ static void Main() // (32,20): error CS1669: __arglist is not valid in this context // void Local(__arglist) Diagnostic(ErrorCode.ERR_IllegalVarArgs, "__arglist").WithLocation(32, 20), - // (34,31): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + // (34,31): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // Console.WriteLine(__arglist); Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(34, 31) ); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs index 320f13951a7f9..07bd155f06f33 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs @@ -4369,14 +4369,31 @@ static IEnumerable F() yield return sizeof(nuint); } }"; - var comp = CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9); - comp.VerifyDiagnostics( - // (6,22): error CS1629: Unsafe code may not appear in iterators + var expectedDiagnostics = new[] + { + // (6,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nint)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 22), + // (7,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // yield return sizeof(nuint); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nuint)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 22) + }; + + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular9).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + + expectedDiagnostics = new[] + { + // (6,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context // yield return sizeof(nint); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nint)").WithLocation(6, 22), - // (7,22): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 22), + // (7,22): error CS0233: 'nuint' does not have a predefined size, therefore sizeof can only be used in an unsafe context // yield return sizeof(nuint); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(nuint)").WithLocation(7, 22)); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nuint)").WithArguments("nuint").WithLocation(7, 22) + }; + + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(source, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs index b9edc6addca35..038f5839f3eee 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs @@ -872,9 +872,6 @@ void M(C c) }"; var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (15,9): error CS0200: Property or indexer 'C.this[int, int]' cannot be assigned to -- it is read only - // c[a: 1, d] = d; - Diagnostic(ErrorCode.ERR_AssgReadonlyProp, "c[a: 1, d]").WithArguments("C.this[int, int]").WithLocation(15, 9) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index 81d33246c8d68..11f632233060e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -65962,11 +65962,10 @@ static void G(object? x, dynamic y) } }"; var comp = CreateCompilationWithMscorlib40AndSystemCore(new[] { source }, options: WithNullableEnable()); - comp.VerifyDiagnostics( - // 0.cs(8,11): warning CS8604: Possible null reference argument for parameter 'x' in 'void C.F(object x, object y)'. - // F(x, y); - Diagnostic(ErrorCode.WRN_NullReferenceArgument, "x").WithArguments("x", "void C.F(object x, object y)").WithLocation(8, 11) - ); + // https://github.com/dotnet/roslyn/issues/29893: We should be able to report warnings + // when all applicable methods agree on the nullability of particular parameters. + // (For instance, x in F(x, y) above.) + comp.VerifyDiagnostics(); } [Fact] @@ -158692,5 +158691,45 @@ static void M() where T : struct, I // y.Value.Item.ToString(); Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "y.Value.Item").WithLocation(15, 9)); } + + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2045970")] + public void BadAsyncLambdaInNamedArgument() + { + var source = """ + #nullable enable + using System; + using System.Threading.Tasks; + + class D + { + void M() + { + var c1 = new C(); + var c2 = new C(); + C.M1(f: async () => + { + if (c2 != null) + { + c1. + await c2.M2(); + } + }); + } + } + + class C + { + public static void M1(Func f) { } + public async Task M2() => await Task.Yield(); + } + """; + CreateCompilation(source).VerifyDiagnostics( + // (15,20): error CS1001: Identifier expected + // c1. + Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(15, 20), + // (15,20): error CS1002: ; expected + // c1. + Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(15, 20)); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs index 22c0f35991cb8..bb9290473490d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs @@ -6,6 +6,8 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; @@ -4178,13 +4180,118 @@ public void DynamicInvocationOnRefStructs() """; CreateCompilation(source).VerifyDiagnostics( - // (5,15): error CS1922: Cannot initialize type 'S' with a collection initializer because it does not implement 'System.Collections.IEnumerable' + // (5,11): error CS9230: Cannot perform a dynamic invocation on an expression with type 'S'. // S s = new S() { d }; - Diagnostic(ErrorCode.ERR_CollectionInitRequiresIEnumerable, "{ d }").WithArguments("S").WithLocation(5, 15), - // (7,16): error CS8343: 'S': ref structs cannot implement interfaces - // ref struct S : IEnumerable - Diagnostic(ErrorCode.ERR_RefStructInterfaceImpl, "IEnumerable").WithArguments("S").WithLocation(7, 16) + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, "S").WithArguments("S").WithLocation(5, 11) ); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72916")] + public void RefReturning_Indexer() + { + var source = """ + public class C + { + public static void Main() + { + var c = new C() { [1] = 2 }; + System.Console.WriteLine(c[1]); + } + + int _test1 = 0; + ref int this[int x] + { + get => ref _test1; + } + } + """; + + var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); + + CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + + var elementAccess = tree.GetRoot().DescendantNodes().OfType().Single(); + var symbolInfo = model.GetSymbolInfo(elementAccess); + AssertEx.Equal("ref System.Int32 C.this[System.Int32 x] { get; }", symbolInfo.Symbol.ToTestDisplayString()); + var typeInfo = model.GetTypeInfo(elementAccess); + AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + + var propertyRef = (IPropertyReferenceOperation)model.GetOperation(elementAccess); + AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + Assert.Equal(typeInfo.Type, propertyRef.Type); + + var assignment = (AssignmentExpressionSyntax)elementAccess.Parent; + typeInfo = model.GetTypeInfo(assignment); + AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + + var operation = (IAssignmentOperation)model.GetOperation(assignment); + AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + + var right = assignment.Right; + typeInfo = model.GetTypeInfo(right); + AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72916")] + public void RefReturning_Property() + { + var source = """ + public class C + { + public static void Main() + { + var c = new C() { P = 2 }; + System.Console.WriteLine(c.P); + } + + int _test1 = 0; + ref int P + { + get => ref _test1; + } + } + """; + + var comp = CreateCompilation(source, options: TestOptions.DebugExe, targetFramework: TargetFramework.StandardAndCSharp); + + CompileAndVerify(comp, expectedOutput: "2").VerifyDiagnostics(); + + var tree = comp.SyntaxTrees.Single(); + var model = comp.GetSemanticModel(tree); + + var propertyAccess = tree.GetRoot().DescendantNodes().OfType().First().Left; + var symbolInfo = model.GetSymbolInfo(propertyAccess); + AssertEx.Equal("ref System.Int32 C.P { get; }", symbolInfo.Symbol.ToTestDisplayString()); + var typeInfo = model.GetTypeInfo(propertyAccess); + AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + + var propertyRef = (IPropertyReferenceOperation)model.GetOperation(propertyAccess); + AssertEx.Equal(symbolInfo.Symbol.ToTestDisplayString(), propertyRef.Property.ToTestDisplayString()); + Assert.Equal(typeInfo.Type, propertyRef.Type); + + var assignment = (AssignmentExpressionSyntax)propertyAccess.Parent; + typeInfo = model.GetTypeInfo(assignment); + AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + + var operation = (IAssignmentOperation)model.GetOperation(assignment); + AssertEx.Equal("System.Int32", operation.Target.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", operation.Value.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", operation.Type.ToTestDisplayString()); + + var right = assignment.Right; + typeInfo = model.GetTypeInfo(right); + AssertEx.Equal("System.Int32", typeInfo.Type.ToTestDisplayString()); + AssertEx.Equal("System.Int32", typeInfo.ConvertedType.ToTestDisplayString()); + } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs index 57fade24f3da2..29eae2695f2e0 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs @@ -11305,12 +11305,12 @@ ref struct RefLike{} // (17,9): error CS0411: The type arguments for method 'Program.M1(in T, in T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. // M1(new object(), default(RefLike)); Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("Program.M1(in T, in T)").WithLocation(17, 9), - // (19,9): error CS0306: The type 'Program.RefLike' may not be used as a type argument + // (19,9): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Program.M1(in T, in T)' // M1(rl, rl); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M1").WithArguments("Program.RefLike").WithLocation(19, 9), - // (20,9): error CS0306: The type 'Program.RefLike' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M1").WithArguments("Program.M1(in T, in T)", "T", "Program.RefLike").WithLocation(19, 9), + // (20,9): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Program.M1(in T, in T)' // M1(in rl, in rl); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M1").WithArguments("Program.RefLike").WithLocation(20, 9), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M1").WithArguments("Program.M1(in T, in T)", "T", "Program.RefLike").WithLocation(20, 9), // (22,9): error CS0411: The type arguments for method 'Program.M1(in T, in T)' cannot be inferred from the usage. Try specifying the type arguments explicitly. // M1(in y, in x); Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M1").WithArguments("Program.M1(in T, in T)").WithLocation(22, 9), @@ -11397,27 +11397,27 @@ ref struct RefLike{} // (16,16): error CS1503: Argument 1: cannot convert from '(, int)' to 'in (int arg1, int arg2)' // Method((null, 1)); Diagnostic(ErrorCode.ERR_BadArgType, "(null, 1)").WithArguments("1", "(, int)", "in (int arg1, int arg2)").WithLocation(16, 16), - // (17,31): error CS0306: The type 'Program.RefLike' may not be used as a type argument + // (17,31): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // Method((new object(), default(RefLike))); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "default(RefLike)").WithArguments("Program.RefLike").WithLocation(17, 31), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "default(RefLike)").WithArguments("(T1, T2)", "T2", "Program.RefLike").WithLocation(17, 31), // (17,9): error CS0411: The type arguments for method 'Program.Method(in (T arg1, T arg2))' cannot be inferred from the usage. Try specifying the type arguments explicitly. // Method((new object(), default(RefLike))); Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "Method").WithArguments("Program.Method(in (T arg1, T arg2))").WithLocation(17, 9), - // (19,17): error CS0306: The type 'Program.RefLike' may not be used as a type argument + // (19,17): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // Method((rl, rl)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "rl").WithArguments("Program.RefLike").WithLocation(19, 17), - // (19,21): error CS0306: The type 'Program.RefLike' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "rl").WithArguments("(T1, T2)", "T1", "Program.RefLike").WithLocation(19, 17), + // (19,21): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // Method((rl, rl)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "rl").WithArguments("Program.RefLike").WithLocation(19, 21), - // (19,9): error CS0306: The type 'Program.RefLike' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "rl").WithArguments("(T1, T2)", "T2", "Program.RefLike").WithLocation(19, 21), + // (19,9): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Program.Method(in (T arg1, T arg2))' // Method((rl, rl)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "Method").WithArguments("Program.RefLike").WithLocation(19, 9), - // (20,20): error CS0306: The type 'Program.RefLike' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Method").WithArguments("Program.Method(in (T arg1, T arg2))", "T", "Program.RefLike").WithLocation(19, 9), + // (20,20): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // Method(in (rl, rl)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "rl").WithArguments("Program.RefLike").WithLocation(20, 20), - // (20,24): error CS0306: The type 'Program.RefLike' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "rl").WithArguments("(T1, T2)", "T1", "Program.RefLike").WithLocation(20, 20), + // (20,24): error CS9244: The type 'Program.RefLike' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // Method(in (rl, rl)); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "rl").WithArguments("Program.RefLike").WithLocation(20, 24), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "rl").WithArguments("(T1, T2)", "T2", "Program.RefLike").WithLocation(20, 24), // (20,19): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference // Method(in (rl, rl)); Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "(rl, rl)").WithLocation(20, 19), diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs index 08ff7b26dc486..6ca1b71853154 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RawInterpolationTests_Handler.cs @@ -2025,22 +2025,22 @@ ref struct S if (expression.Contains('+')) { comp.VerifyDiagnostics( - // (6,13): error CS0306: The type 'int*' may not be used as a type argument + // 0.cs(6,13): error CS0306: The type 'int*' may not be used as a type argument // _ = $"""{i}""" + $"""{s}"""; Diagnostic(ErrorCode.ERR_BadTypeArgument, "{i}").WithArguments("int*").WithLocation(6, 13), - // (6,26): error CS0306: The type 'S' may not be used as a type argument + // 0.cs(6,26): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'DefaultInterpolatedStringHandler.AppendFormatted(T, int, string)' // _ = $"""{i}""" + $"""{s}"""; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "{s}").WithArguments("S").WithLocation(6, 26)); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "{s}").WithArguments("System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(T, int, string)", "T", "S").WithLocation(6, 26)); } else { comp.VerifyDiagnostics( - // (6,13): error CS0306: The type 'int*' may not be used as a type argument + // 0.cs(6,13): error CS0306: The type 'int*' may not be used as a type argument // _ = $"""{i}{s}"""; Diagnostic(ErrorCode.ERR_BadTypeArgument, "{i}").WithArguments("int*").WithLocation(6, 13), - // (6,16): error CS0306: The type 'S' may not be used as a type argument + // 0.cs(6,16): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'DefaultInterpolatedStringHandler.AppendFormatted(T, int, string)' // _ = $"""{i}{s}"""; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "{s}").WithArguments("S").WithLocation(6, 16)); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "{s}").WithArguments("System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(T, int, string)", "T", "S").WithLocation(6, 16)); } } @@ -2506,9 +2506,10 @@ ref struct S var comp = CreateCompilation(new[] { source, interpolatedStringBuilder }, targetFramework: TargetFramework.NetCoreApp); comp.VerifyDiagnostics( - // (5,21): error CS0306: The type 'S' may not be used as a type argument - // Console.WriteLine($"{s}"); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "{s}").WithArguments("S").WithLocation(5, 23)); + // 0.cs(5,23): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'DefaultInterpolatedStringHandler.AppendFormatted(T)' + // Console.WriteLine($"""{s}"""); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "{s}").WithArguments("System.Runtime.CompilerServices.DefaultInterpolatedStringHandler.AppendFormatted(T)", "T", "S").WithLocation(5, 23) + ); } [Theory] @@ -6752,7 +6753,7 @@ o in M verifier.VerifyDiagnostics(modifier == "ref readonly" ? new[] { - // 0.cs(8,5): warning CS9503: Argument 1 should be passed with 'ref' or 'in' keyword + // 0.cs(8,5): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword // C.M(i, ref s, out o, $"""literal"""); Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "i").WithArguments("1").WithLocation(8, 5) } @@ -12638,9 +12639,14 @@ public void RefStructHandler_DynamicInHole(string expression) var comp = CreateCompilationWithCSharp(new[] { code, handler }); - // Note: We don't give any errors when mixing dynamic and ref structs today. If that ever changes, we should get an - // error here. This will crash at runtime because of this. - comp.VerifyEmitDiagnostics(); + comp.VerifyDiagnostics( + // 0.cs(4,19): error CS9230: Cannot perform a dynamic invocation on an expression with type 'CustomHandler'. + // CustomHandler c = $"""{h1}""" + $"""{h2}"""; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, expression).WithArguments("CustomHandler").WithLocation(4, 19), + // 0.cs(4,19): error CS9230: Cannot perform a dynamic invocation on an expression with type 'CustomHandler'. + // CustomHandler c = $"""{h1}""" + $"""{h2}"""; + Diagnostic(ErrorCode.ERR_CannotDynamicInvokeOnExpression, expression).WithArguments("CustomHandler").WithLocation(4, 19) + ); } [Theory] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs index 0cd3ee133280d..2821c4bcabfc2 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefEscapingTests.cs @@ -4342,12 +4342,12 @@ public ValueTuple(T1 item1, T2 item2) } }"; CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)).VerifyDiagnostics( - // (8,19): error CS0306: The type 'Span' may not be used as a type argument + // (8,19): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // var t = ((global, global) = global); // error - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(8, 19), - // (8,27): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(8, 19), + // (8,27): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // var t = ((global, global) = global); // error - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(8, 27) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(T1, T2)", "T2", "System.Span").WithLocation(8, 27) ); } @@ -4398,27 +4398,27 @@ public ValueTuple(T1 item1, T2 item2) "; var compilation = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)); compilation.VerifyDiagnostics( - // (12,29): error CS0306: The type 'Span' may not be used as a type argument + // (12,29): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (global, global) = (local, local); // error 1 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(12, 29), - // (12,36): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(12, 29), + // (12,36): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // (global, global) = (local, local); // error 1 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(12, 36), - // (14,24): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T2", "System.Span").WithLocation(12, 36), + // (14,24): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (global, s) = (local, ""); // error 2 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(14, 24), - // (15,24): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(14, 24), + // (15,24): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (global, s) = (local, null); // error 3 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(15, 24), - // (17,23): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(15, 24), + // (17,23): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (local, s) = (global, ""); // error 4 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(17, 23), - // (18,23): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(17, 23), + // (18,23): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (local, s) = (global, null); // error 5 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(18, 23), - // (20,19): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(18, 23), + // (20,19): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (c, s) = (local, ""); // error 6 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(20, 19) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(20, 19) ); // Check the Type and ConvertedType of tuples on the right-hand-side @@ -4486,36 +4486,36 @@ public void M(ref Span global) // (12,28): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (global, global) = (local, local); // error 1 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(local, local)").WithArguments("System.ValueTuple`2").WithLocation(12, 28), - // (12,29): error CS0306: The type 'Span' may not be used as a type argument + // (12,29): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '' in the generic type or method '(, )' // (global, global) = (local, local); // error 1 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(12, 29), - // (12,36): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(, )", "", "System.Span").WithLocation(12, 29), + // (12,36): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '' in the generic type or method '(, )' // (global, global) = (local, local); // error 1 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(12, 36), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(, )", "", "System.Span").WithLocation(12, 36), // (14,23): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (global, s) = (local, ""); // error 2 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, @"(local, """")").WithArguments("System.ValueTuple`2").WithLocation(14, 23), - // (14,24): error CS0306: The type 'Span' may not be used as a type argument + // (14,24): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '' in the generic type or method '(, )' // (global, s) = (local, ""); // error 2 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(14, 24), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(, )", "", "System.Span").WithLocation(14, 24), // (15,23): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (global, s) = (local, null); // error 3 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(local, null)").WithArguments("System.ValueTuple`2").WithLocation(15, 23), // (17,22): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (local, s) = (global, ""); // error 4 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, @"(global, """")").WithArguments("System.ValueTuple`2").WithLocation(17, 22), - // (17,23): error CS0306: The type 'Span' may not be used as a type argument + // (17,23): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '' in the generic type or method '(, )' // (local, s) = (global, ""); // error 4 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(17, 23), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(, )", "", "System.Span").WithLocation(17, 23), // (18,22): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (local, s) = (global, null); // error 5 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(global, null)").WithArguments("System.ValueTuple`2").WithLocation(18, 22), // (20,18): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (c, s) = (local, ""); // error 6 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, @"(local, """")").WithArguments("System.ValueTuple`2").WithLocation(20, 18), - // (20,19): error CS0306: The type 'Span' may not be used as a type argument + // (20,19): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter '' in the generic type or method '(, )' // (c, s) = (local, ""); // error 6 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(20, 19), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(, )", "", "System.Span").WithLocation(20, 19), // (21,18): error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported // (c, s) = (local, null); // error 7 Diagnostic(ErrorCode.ERR_PredefinedValueTupleTypeNotFound, "(local, null)").WithArguments("System.ValueTuple`2").WithLocation(21, 18) @@ -4598,27 +4598,28 @@ public ValueTuple(T1 item1, T2 item2) "; var compilation = CreateCompilationWithMscorlibAndSpan(text, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)); compilation.VerifyDiagnostics( - // (12,29): error CS0306: The type 'Span' may not be used as a type argument + // (12,29): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (global, global) = (local, local); // error 1 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(12, 29), - // (12,36): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(12, 29), + // (12,36): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // (global, global) = (local, local); // error 1 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(12, 36), - // (14,24): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T2", "System.Span").WithLocation(12, 36), + // (14,24): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (global, s) = (local, ""); // error 2 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(14, 24), - // (15,24): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(14, 24), + // (15,24): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (global, s) = (local, null); // error 3 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(15, 24), - // (17,23): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(15, 24), + // (17,23): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (local, s) = (global, ""); // error 4 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(17, 23), - // (18,23): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(17, 23), + // (18,23): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (local, s) = (global, null); // error 5 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "global").WithArguments("System.Span").WithLocation(18, 23), - // (20,19): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "global").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(18, 23), + // (20,19): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (c, s) = (local, ""); // error 6 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "local").WithArguments("System.Span").WithLocation(20, 19)); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "local").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(20, 19) + ); } [Theory] @@ -4968,9 +4969,10 @@ public static unsafe void Test(TestStruct[] ar) [Theory] [InlineData(LanguageVersion.CSharp10)] [InlineData(LanguageVersion.CSharp11)] + [InlineData(LanguageVersionFacts.CSharpNext)] public void AwaitRefStruct(LanguageVersion languageVersion) { - CreateCompilation(@" + var comp = CreateCompilation(@" using System.Threading.Tasks; ref struct S { } @@ -4990,20 +4992,67 @@ async Task M(Task t) void M(S t, ref S t1) { } -}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics( - // (8,26): error CS0306: The type 'S' may not be used as a type argument - // async Task M(Task t) - Diagnostic(ErrorCode.ERR_BadTypeArgument, "t").WithArguments("S").WithLocation(8, 26), - // (12,9): error CS4012: Parameters or locals of type 'S' cannot be declared in async methods or async lambda expressions. - // var a = await t; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("S").WithLocation(12, 9), - // (14,9): error CS4012: Parameters or locals of type 'S' cannot be declared in async methods or async lambda expressions. - // var r = t.Result; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("S").WithLocation(14, 9), - // (15,9): error CS8350: This combination of arguments to 'C.M(S, ref S)' is disallowed because it may expose variables referenced by parameter 't' outside of their declaration scope - // M(await t, ref r); - Diagnostic(ErrorCode.ERR_CallArgMixing, "M(await t, ref r)").WithArguments("C.M(S, ref S)", "t").WithLocation(15, 9) - ); +}", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll); + if (languageVersion < LanguageVersionFacts.CSharpNext) + { + comp.VerifyDiagnostics( + // (8,26): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Task' + // async Task M(Task t) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "t").WithArguments("System.Threading.Tasks.Task", "TResult", "S").WithLocation(8, 26), + // (12,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // var a = await t; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(12, 9), + // (14,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // var r = t.Result; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "var").WithArguments("ref and unsafe in async and iterator methods").WithLocation(14, 9), + // (15,9): error CS8350: This combination of arguments to 'C.M(S, ref S)' is disallowed because it may expose variables referenced by parameter 't' outside of their declaration scope + // M(await t, ref r); + Diagnostic(ErrorCode.ERR_CallArgMixing, "M(await t, ref r)").WithArguments("C.M(S, ref S)", "t").WithLocation(15, 9) + ); + } + else + { + comp.VerifyDiagnostics( + // (8,26): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Task' + // async Task M(Task t) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "t").WithArguments("System.Threading.Tasks.Task", "TResult", "S").WithLocation(8, 26), + // (15,9): error CS8350: This combination of arguments to 'C.M(S, ref S)' is disallowed because it may expose variables referenced by parameter 't' outside of their declaration scope + // M(await t, ref r); + Diagnostic(ErrorCode.ERR_CallArgMixing, "M(await t, ref r)").WithArguments("C.M(S, ref S)", "t").WithLocation(15, 9) + ); + } + } + + [Fact] + public void AsyncLocals_Reassignment() + { + var code = """ + using System.Threading.Tasks; + class C + { + async Task M1() + { + int x = 42; + ref int y = ref x; + y.ToString(); + await Task.Yield(); + y.ToString(); // 1 + } + async Task M2() + { + int x = 42; + ref int y = ref x; + y.ToString(); + await Task.Yield(); + y = ref x; + y.ToString(); + } + } + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (10,9): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // y.ToString(); // 1 + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(10, 9)); } [WorkItem(25398, "https://github.com/dotnet/roslyn/issues/25398")] @@ -5024,12 +5073,12 @@ void M() var a = (S?)null ?? default; } }", parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion), options: TestOptions.ReleaseDll).VerifyDiagnostics( - // (8,14): error CS0306: The type 'S' may not be used as a type argument + // (8,14): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // _ = (S?)null ?? default; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "S?").WithArguments("S").WithLocation(8, 14), - // (10,18): error CS0306: The type 'S' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "S?").WithArguments("System.Nullable", "T", "S").WithLocation(8, 14), + // (10,18): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Nullable' // var a = (S?)null ?? default; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "S?").WithArguments("S").WithLocation(10, 18) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "S?").WithArguments("System.Nullable", "T", "S").WithLocation(10, 18) ); } @@ -5344,9 +5393,9 @@ public static IEnumerable Iterator() { } """); compilation.VerifyEmitDiagnostics( - // (20,19): error CS4013: Instance of type 'PooledArrayHandle' cannot be used inside a nested function, query expression, iterator block or async method + // (20,19): error CS4007: Instance of type 'PooledArrayHandle' cannot be preserved across 'await' or 'yield' boundary. // using var handle = RentArray(200, out var array); - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "handle = RentArray(200, out var array)").WithArguments("PooledArrayHandle").WithLocation(20, 19)); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "handle = RentArray(200, out var array)").WithArguments("PooledArrayHandle").WithLocation(20, 19)); } [Theory(Skip = "https://github.com/dotnet/roslyn/issues/40583")] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs index 62c1adc4a5632..392842983ba7d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs @@ -8990,12 +8990,13 @@ static void Main() }"; var comp = CreateCompilationWithSpanAndMemoryExtensions(source, parseOptions: TestOptions.Regular.WithLanguageVersion(languageVersion)); comp.VerifyEmitDiagnostics( - // (8,19): error CS0306: The type 'Span' may not be used as a type argument + // (8,19): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T1' in the generic type or method '(T1, T2)' // (x, y) = (y, x); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "y").WithArguments("System.Span").WithLocation(8, 19), - // (8,22): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "y").WithArguments("(T1, T2)", "T1", "System.Span").WithLocation(8, 19), + // (8,22): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T2' in the generic type or method '(T1, T2)' // (x, y) = (y, x); - Diagnostic(ErrorCode.ERR_BadTypeArgument, "x").WithArguments("System.Span").WithLocation(8, 22)); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "x").WithArguments("(T1, T2)", "T2", "System.Span").WithLocation(8, 22) + ); } [Theory] @@ -9772,9 +9773,9 @@ public static void M() where T : unmanaged { } // (4,40): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithRefField') // StructWithRefField* p = stackalloc StructWithRefField[10]; // 1, 2 Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithRefField").WithArguments("StructWithRefField").WithLocation(4, 40), - // (5,7): error CS0306: The type 'StructWithRefField' may not be used as a type argument + // (5,7): error CS9244: The type 'StructWithRefField' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.M()' // C.M(); // 3 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("StructWithRefField").WithLocation(5, 7) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("C.M()", "T", "StructWithRefField").WithLocation(5, 7) ); Assert.True(comp.GetTypeByMetadataName("StructWithRefField").IsManagedTypeNoUseSiteDiagnostics); @@ -9811,13 +9812,13 @@ public static void M() where T : unmanaged { } // (4,48): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('StructWithIndirectRefField') // StructWithIndirectRefField* p = stackalloc StructWithIndirectRefField[10]; // 1, 2 Diagnostic(ErrorCode.ERR_ManagedAddr, "StructWithIndirectRefField").WithArguments("StructWithIndirectRefField").WithLocation(4, 48), - // (5,7): error CS0306: The type 'StructWithIndirectRefField' may not be used as a type argument + // (5,7): error CS9244: The type 'StructWithIndirectRefField' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.M()' // C.M(); // 3 - Diagnostic(ErrorCode.ERR_BadTypeArgument, "M").WithArguments("StructWithIndirectRefField").WithLocation(5, 7), - // (10,36): warning CS0649: Field 'StructWithIndirectRefField.Field' is never assigned to, and will always have its default value + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "M").WithArguments("C.M()", "T", "StructWithIndirectRefField").WithLocation(5, 7), + // (10,36): warning CS0649: Field 'StructWithIndirectRefField.Field' is never assigned to, and will always have its default value // public StructWithRefField Field; Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("StructWithIndirectRefField.Field", "").WithLocation(10, 36), - // (14,18): warning CS0649: Field 'StructWithRefField.RefField' is never assigned to, and will always have its default value + // (14,18): warning CS0649: Field 'StructWithRefField.RefField' is never assigned to, and will always have its default value // public ref T RefField; Diagnostic(ErrorCode.WRN_UnassignedInternalField, "RefField").WithArguments("StructWithRefField.RefField", "").WithLocation(14, 18) ); @@ -17712,9 +17713,6 @@ static void F1(scoped Unknown x, scoped R y) }"; var comp = CreateCompilation(source); comp.VerifyDiagnostics( - // (4,20): error CS9048: The 'scoped' modifier can be used for refs and ref struct values only. - // static void F1(scoped Unknown x, scoped R y) - Diagnostic(ErrorCode.ERR_ScopedRefAndRefStructOnly, "scoped Unknown x").WithLocation(4, 20), // (4,27): error CS0246: The type or namespace name 'Unknown' could not be found (are you missing a using directive or an assembly reference?) // static void F1(scoped Unknown x, scoped R y) Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unknown").WithArguments("Unknown").WithLocation(4, 27), @@ -22058,10 +22056,10 @@ object P6 }"; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition, IsExternalInitTypeDefinition }); comp.VerifyDiagnostics( - // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] object P3 { get; init; } // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6), - // (15,10): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (15,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] init; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 10)); } @@ -22161,7 +22159,7 @@ R this[int i] // (11,16): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'. // init { value.F = ref this; } // 1 Diagnostic(ErrorCode.ERR_RefAssignNarrower, "value.F = ref this").WithArguments("F", "this").WithLocation(11, 16), - // (19,10): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (19,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(19, 10), // (20,16): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'. @@ -22193,22 +22191,22 @@ [UnscopedRef] event D E6 { add { } remove { } } // 6 }"; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net60); comp.VerifyDiagnostics( - // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E1; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6), - // (7,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (7,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E2 { add { } remove { } } // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(7, 6), - // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E3; // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 6), - // (12,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (12,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E4 { add { } remove { } } // 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(12, 6), - // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E5; // 5 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 6), - // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E6 { add { } remove { } } // 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 6)); } @@ -22238,22 +22236,22 @@ event D E6 { add { } [UnscopedRef] remove { } } // 6 "; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyDiagnostics( - // (6,19): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (6,19): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D E1 { [UnscopedRef] add { } remove { } } // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 19), - // (7,27): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (7,27): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D E2 { add { } [UnscopedRef] remove { } } // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(7, 27), - // (11,19): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (11,19): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D E3 { [UnscopedRef] add { } remove { } } // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 19), - // (12,27): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (12,27): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D E4 { add { } [UnscopedRef] remove { } } // 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(12, 27), - // (16,19): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,19): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D E5 { [UnscopedRef] add { } remove { } } // 5 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 19), - // (17,27): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (17,27): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D E6 { add { } [UnscopedRef] remove { } } // 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 27)); } @@ -22278,10 +22276,10 @@ void F() "; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); comp.VerifyDiagnostics( - // (6,18): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (6,18): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // var d = [UnscopedRef] (ref int i) => ref i; Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 18), - // (7,10): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (7,10): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] ref int Local() => throw null; Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(7, 10)); } @@ -22467,7 +22465,7 @@ struct B // (15,6): warning CS0436: The type 'UnscopedRefAttribute' in '1.cs' conflicts with the imported type 'UnscopedRefAttribute' in 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Using the type defined in ''. // [UnscopedRef] Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "UnscopedRef").WithArguments("1.cs", "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute", "System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Diagnostics.CodeAnalysis.UnscopedRefAttribute").WithLocation(15, 6), - // (15,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (15,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 6), // (18,9): error CS8374: Cannot ref-assign 'this' to 'F' because 'this' has a narrower escape scope than 'F'. @@ -22486,7 +22484,7 @@ class C }"; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); comp.VerifyDiagnostics( - // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] ~C() { } Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(4, 6)); } @@ -22504,13 +22502,13 @@ [UnscopedRef] static S() { } // 1 }"; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); comp.VerifyDiagnostics( - // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static S() { } // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(4, 6), - // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static object F() => null; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(5, 6), - // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static object P => null; // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6)); } @@ -22534,10 +22532,10 @@ record struct S }"; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); comp.VerifyDiagnostics( - // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (4,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] object F1() => null; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(4, 6), - // (8,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (8,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] object F2() => null; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 6)); } @@ -25038,30 +25036,31 @@ [UnscopedRef] void I.F2() { } // 6 """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (23,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + // (23,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.F1()' doesn't have this attribute. // [UnscopedRef] public ref int F1() => ref _f2; // 1 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(23, 34), - // (24,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithArguments("I.F1()").WithLocation(23, 34), + // (24,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.F2()' doesn't have this attribute. // [UnscopedRef] public void F2() { } // 2 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(24, 31), - // (25,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithArguments("I.F2()").WithLocation(24, 31), + // (25,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.F3(out R)' doesn't have this attribute. // [UnscopedRef] public void F3(out R r) { r = new R(ref _f2); } // 3 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(25, 31), - // (26,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithArguments("I.F3(out R)").WithLocation(25, 31), + // (26,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.P.get' doesn't have this attribute. // [UnscopedRef] public ref int P => ref _f2; // 4 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f2").WithLocation(26, 39), - // (38,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f2").WithArguments("I.P.get").WithLocation(26, 39), + // (38,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.F1()' doesn't have this attribute. // [UnscopedRef] ref int I.F1() => ref _f4; // 5 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(38, 34), - // (39,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithArguments("I.F1()").WithLocation(38, 34), + // (39,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.F2()' doesn't have this attribute. // [UnscopedRef] void I.F2() { } // 6 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(39, 31), - // (40,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithArguments("I.F2()").WithLocation(39, 31), + // (40,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.F3(out R)' doesn't have this attribute. // [UnscopedRef] void I.F3(out R r) { r = new R(ref _f4); } // 7 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(40, 31), - // (41,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithArguments("I.F3(out R)").WithLocation(40, 31), + // (41,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I.P.get' doesn't have this attribute. // [UnscopedRef] ref int I.P => ref _f4; // 8 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f4").WithLocation(41, 39)); + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f4").WithArguments("I.P.get").WithLocation(41, 39) + ); } // As above, but interface members are also marked [UnscopedRef]. @@ -25077,10 +25076,10 @@ public R(ref T t) { } } interface I { - [UnscopedRef] ref T F1(); // 1 - [UnscopedRef] void F2(); // 2 - [UnscopedRef] void F3(out R r); // 3 - [UnscopedRef] ref T P { get; } // 4 + [UnscopedRef] ref T F1(); + [UnscopedRef] void F2(); + [UnscopedRef] void F3(out R r); + [UnscopedRef] ref T P { get; } } struct S1 : I { @@ -25092,10 +25091,10 @@ public void F2() { } struct S2 : I { private int _f2; - [UnscopedRef] public ref int F1() => ref _f2; // 5 - [UnscopedRef] public void F2() { } // 6 - [UnscopedRef] public void F3(out R r) { r = new R(ref _f2); } // 7 - [UnscopedRef] public ref int P => ref _f2; // 8 + [UnscopedRef] public ref int F1() => ref _f2; + [UnscopedRef] public void F2() { } + [UnscopedRef] public void F3(out R r) { r = new R(ref _f2); } + [UnscopedRef] public ref int P => ref _f2; } struct S3 : I { @@ -25107,50 +25106,14 @@ void I.F2() { } struct S4 : I { private int _f4; - [UnscopedRef] ref int I.F1() => ref _f4; // 9 - [UnscopedRef] void I.F2() { } // 10 - [UnscopedRef] void I.F3(out R r) { r = new R(ref _f4); } // 11 - [UnscopedRef] ref int I.P => ref _f4; // 12 + [UnscopedRef] ref int I.F1() => ref _f4; + [UnscopedRef] void I.F2() { } + [UnscopedRef] void I.F3(out R r) { r = new R(ref _f4); } + [UnscopedRef] ref int I.P => ref _f4; } """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); - comp.VerifyEmitDiagnostics( - // (8,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - // [UnscopedRef] ref T F1(); // 1 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(8, 6), - // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - // [UnscopedRef] void F2(); // 2 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6), - // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - // [UnscopedRef] void F3(out R r); // 3 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6), - // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - // [UnscopedRef] ref T P { get; } // 4 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 6), - // (23,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] public ref int F1() => ref _f2; // 5 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(23, 34), - // (24,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] public void F2() { } // 6 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(24, 31), - // (25,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] public void F3(out R r) { r = new R(ref _f2); } // 7 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(25, 31), - // (26,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] public ref int P => ref _f2; // 8 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f2").WithLocation(26, 39), - // (38,34): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] ref int I.F1() => ref _f4; // 9 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F1").WithLocation(38, 34), - // (39,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] void I.F2() { } // 10 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F2").WithLocation(39, 31), - // (40,31): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] void I.F3(out R r) { r = new R(ref _f4); } // 11 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "F3").WithLocation(40, 31), - // (41,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. - // [UnscopedRef] ref int I.P => ref _f4; // 12 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "ref _f4").WithLocation(41, 39)); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -25189,27 +25152,28 @@ public int P3 { [UnscopedRef] set { } } // 7 """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (16,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + // (16,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I1.P1.get' doesn't have this attribute. // [UnscopedRef] public ref int P1 => throw null; // 1 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "throw null").WithLocation(16, 40), - // (17,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "throw null").WithArguments("I1.P1.get").WithLocation(16, 40), + // (17,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I2.P2.get' doesn't have this attribute. // [UnscopedRef] public int P2 { get; set; } // 2, 3 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithLocation(17, 35), - // (17,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I2.P2.get").WithLocation(17, 35), + // (17,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I2.P2.set' doesn't have this attribute. // [UnscopedRef] public int P2 { get; set; } // 2, 3 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithLocation(17, 40), - // (21,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithArguments("I2.P2.set").WithLocation(17, 40), + // (21,39): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I1.P1.get' doesn't have this attribute. // public ref int P1 { [UnscopedRef] get => throw null; } // 4 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithLocation(21, 39), - // (22,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I1.P1.get").WithLocation(21, 39), + // (22,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I2.P2.get' doesn't have this attribute. // public int P2 { [UnscopedRef] get; set; } // 5 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithLocation(22, 35), - // (26,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "get").WithArguments("I2.P2.get").WithLocation(22, 35), + // (26,40): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I2.P2.set' doesn't have this attribute. // public int P2 { get; [UnscopedRef] set; } // 6 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithLocation(26, 40), - // (27,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation. + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithArguments("I2.P2.set").WithLocation(26, 40), + // (27,35): error CS9102: UnscopedRefAttribute cannot be applied to an interface implementation because implemented member 'I3.P3.set' doesn't have this attribute. // public int P3 { [UnscopedRef] set { } } // 7 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithLocation(27, 35)); + Diagnostic(ErrorCode.ERR_UnscopedRefAttributeInterfaceImplementation, "set").WithArguments("I3.P3.set").WithLocation(27, 35) + ); } [Fact] @@ -25243,7 +25207,7 @@ public void UnscopedRefAttribute_InterfaceImplementation_05() interface I { ref T F1(); - [UnscopedRef] ref T F2(); // 1 + [UnscopedRef] ref T F2(); } class C1 : I { @@ -25260,19 +25224,16 @@ class C2 : I """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. - // [UnscopedRef] ref T F2(); // 1 - Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(5, 6), - // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public ref int F1() => ref _f1; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6), - // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (11,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public ref int F2() => ref _f1; // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 6), - // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] ref int I.F1() => ref _f2; // 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 6), - // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] ref int I.F2() => ref _f2; // 5 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 6)); } @@ -25298,10 +25259,10 @@ class B : A, I """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public ref int F() => throw null; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6), - // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public ref int P => throw null; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6)); } @@ -25324,10 +25285,10 @@ interface IB : IA """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] ref int IA.F() => throw null; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6), - // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] ref int IA.P => throw null; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6)); } @@ -25370,22 +25331,22 @@ [UnscopedRef] event D I.E { add { } remove { } } // 6 """; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); comp.VerifyEmitDiagnostics( - // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public event D E; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6), - // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public event D E { add { } remove { } } // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6), - // (18,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (18,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D I.E { add { } remove { } } // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(18, 6), - // (22,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (22,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public event D E; // 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 6), - // (26,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (26,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public event D E { add { } remove { } } // 5 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(26, 6), - // (30,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (30,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D I.E { add { } remove { } } // 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(30, 6)); } @@ -25425,28 +25386,28 @@ event D I.E2 { add { } [UnscopedRef] remove { } } // 8 """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (11,31): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (11,31): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public event D E1 { [UnscopedRef] add { } remove { } } // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(11, 31), - // (12,39): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (12,39): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public event D E2 { add { } [UnscopedRef] remove { } } // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(12, 39), - // (16,37): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,37): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D I.E1 { [UnscopedRef] add { } remove { } } // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 37), - // (17,45): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (17,45): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D I.E2 { add { } [UnscopedRef] remove { } } // 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 45), - // (21,31): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (21,31): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public event D E1 { [UnscopedRef] add { } remove { } } // 5 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(21, 31), - // (22,39): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (22,39): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public event D E2 { add { } [UnscopedRef] remove { } } // 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 39), - // (26,37): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (26,37): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D I.E1 { [UnscopedRef] add { } remove { } } // 7 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(26, 37), - // (27,45): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (27,45): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D I.E2 { add { } [UnscopedRef] remove { } } // 8 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(27, 45)); } @@ -25476,13 +25437,13 @@ event D I.E { add { } [UnscopedRef] remove { } } // 3 """; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }, targetFramework: TargetFramework.Net60); comp.VerifyEmitDiagnostics( - // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (9,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D I.E { add { } remove { } } // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(9, 6), - // (13,36): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (13,36): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D I.E { [UnscopedRef] add { } remove { } } // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(13, 36), - // (17,44): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (17,44): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // event D I.E { add { } [UnscopedRef] remove { } } // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 44)); } @@ -25509,13 +25470,13 @@ [UnscopedRef] event D I.E { add { } remove { } } // 3 """; var comp = CreateCompilation(new[] { source, UnscopedRefAttributeDefinition }); comp.VerifyEmitDiagnostics( - // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (6,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D E; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(6, 6), - // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (10,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public event D E; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(10, 6), - // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] event D I.E { add { } remove { } } // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6)); } @@ -25553,40 +25514,40 @@ interface I """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (13,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (13,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public static R F() => default; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(13, 6), - // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public static R P1 { get { return default; } set { } } // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6), - // (15,32): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (15,32): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public static R P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 32), - // (15,70): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (15,70): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public static R P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 70), - // (16,37): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,37): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public static event D E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 37), - // (16,59): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,59): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // public static event D E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 59), - // (20,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (20,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static R I.F() => default; // 7 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(20, 6), - // (21,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (21,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static R I.P1 => default; // 8 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(21, 6), - // (22,38): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (22,38): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static R I.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 9, 10 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 38), - // (22,76): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (22,76): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static R I.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 9, 10 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(22, 76), - // (23,43): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (23,43): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static event D I.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 11, 12 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(23, 43), - // (23,65): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (23,65): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static event D I.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 11, 12 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(23, 65)); } @@ -25615,22 +25576,22 @@ interface IB : IA """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (13,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (13,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static R IA.F() => default; // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(13, 6), - // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (14,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] static R IA.P1 => default; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(14, 6), - // (15,39): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (15,39): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static R IA.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 39), - // (15,77): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (15,77): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static R IA.P2 { [UnscopedRef] get { return default; } [UnscopedRef] set { } } // 3, 4 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(15, 77), - // (16,44): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,44): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static event D IA.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 44), - // (16,66): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,66): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // static event D IA.E { [UnscopedRef] add { } [UnscopedRef] remove { } } // 5, 6 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 66)); } @@ -25660,13 +25621,13 @@ class B2 : A """; var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70); comp.VerifyEmitDiagnostics( - // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (5,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public abstract ref T F2(); // 1 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(5, 6), - // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (16,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public override ref string F1() => ref _f2; // 2 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(16, 6), - // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct instance methods and properties, and cannot be applied to constructors or init-only members. + // (17,6): error CS9101: UnscopedRefAttribute can only be applied to struct or virtual interface instance methods and properties, and cannot be applied to constructors or init-only members. // [UnscopedRef] public override ref string F2() => ref _f2; // 3 Diagnostic(ErrorCode.ERR_UnscopedRefAttributeUnsupportedMemberTarget, "UnscopedRef").WithLocation(17, 6)); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index 825e55fd10807..7299939536559 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -1209,10 +1209,7 @@ async Task M() await Task.FromResult(false); } }"); - comp.VerifyDiagnostics( - // (7,26): error CS8177: Async methods cannot have by-reference locals - // ref readonly int x = ref (new int[1])[0]; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x").WithLocation(7, 26)); + comp.VerifyEmitDiagnostics(); } [Fact] @@ -1229,10 +1226,87 @@ IEnumerable M() yield return i; } }"); - comp.VerifyDiagnostics( - // (7,26): error CS8176: Iterators cannot have by-reference locals - // ref readonly int x = ref (new int[1])[0]; - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(7, 26)); + comp.VerifyEmitDiagnostics(); + } + + [Fact] + public void RefReadonlyInIterator_ForEach() + { + var source = """ + using System.Collections.Generic; + class C + { + int[] arr = new int[2]; + IEnumerable M() + { + ref readonly int[] x = ref arr; + + foreach (var i in x) + { + System.Console.Write(i); + yield return 1; + } + + foreach (var j in x) + { + System.Console.Write(j); + yield return 2; + } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,28): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly int[] x = ref arr; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 28)); + + var expectedDiagnostics = new[] + { + // (15,27): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // foreach (var j in x) + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "x").WithLocation(15, 27) + }; + + CreateCompilation(source, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + + CreateCompilation(source).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefReadonlyInIterator_ForEach_02() + { + var source = """ + using System.Collections.Generic; + + foreach (var i in new C().M()) System.Console.Write(i); + + class C + { + int[] arr = new[] { 4, 5 }; + public IEnumerable M() + { + ref readonly int[] x = ref arr; + + foreach (var i in x) + { + System.Console.Write(i); + yield return 1; + } + } + } + """; + + CreateCompilation(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (10,28): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref readonly int[] x = ref arr; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "x").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 28)); + + var expectedOutput = "4151"; + + CompileAndVerify(source, parseOptions: TestOptions.RegularNext, expectedOutput: expectedOutput).VerifyDiagnostics(); + + CompileAndVerify(source, expectedOutput: expectedOutput).VerifyDiagnostics(); } [Fact] @@ -1247,7 +1321,7 @@ IEnumerable M() switch (this) { default: - ref readonly int x = ref (new int[1])[0]; // 1 + ref readonly int x = ref (new int[1])[0]; yield return 1; yield return x; @@ -1260,10 +1334,10 @@ void local() } } }"); - comp.VerifyDiagnostics( - // (10,34): error CS8176: Iterators cannot have by-reference locals - // ref readonly int x = ref (new int[1])[0]; // 1 - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(10, 34)); + comp.VerifyEmitDiagnostics( + // (12,30): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // yield return x; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "x").WithLocation(12, 30)); } [Fact] @@ -1278,22 +1352,19 @@ IEnumerable M() switch (this) { default: - ref readonly int x; // 1, 2 + ref readonly int x; // 1 yield return 1; - yield return x; // 3 + yield return x; // 2 break; } } }"); comp.VerifyDiagnostics( - // (10,34): error CS8176: Iterators cannot have by-reference locals - // ref readonly int x; // 1, 2 - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(10, 34), // (10,34): error CS8174: A declaration of a by-reference variable must have an initializer - // ref readonly int x; // 1, 2 + // ref readonly int x; // 1 Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "x").WithLocation(10, 34), // (12,30): error CS0165: Use of unassigned local variable 'x' - // yield return x; // 3 + // yield return x; // 2 Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(12, 30)); } @@ -1316,9 +1387,9 @@ IEnumerable M() } }"); comp.VerifyDiagnostics( - // (10,43): error CS8176: Iterators cannot have by-reference locals + // (10,49): error CS1510: A ref or out value must be an assignable variable // foreach (ref readonly int x in (new int[1])) - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(10, 43)); + Diagnostic(ErrorCode.ERR_RefLvalueExpected, "new int[1]").WithLocation(10, 49)); } [Fact] @@ -1331,18 +1402,15 @@ class C IEnumerable M() { if (true) - ref int x = ref (new int[1])[0]; // 1, 2 + ref int x = ref (new int[1])[0]; // 1 yield return 1; } }"); comp.VerifyDiagnostics( // (8,13): error CS1023: Embedded statement cannot be a declaration or labeled statement - // ref int x = ref (new int[1])[0]; // 1, 2 - Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "ref int x = ref (new int[1])[0];").WithLocation(8, 13), - // (8,21): error CS8176: Iterators cannot have by-reference locals - // ref int x = ref (new int[1])[0]; // 1, 2 - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(8, 21)); + // ref int x = ref (new int[1])[0]; // 1 + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "ref int x = ref (new int[1])[0];").WithLocation(8, 13)); } [Fact] @@ -1355,18 +1423,15 @@ class C async Task M() { if (true) - ref int x = ref (new int[1])[0]; // 1, 2 + ref int x = ref (new int[1])[0]; // 1 await Task.Yield(); } }"); comp.VerifyDiagnostics( // (8,13): error CS1023: Embedded statement cannot be a declaration or labeled statement - // ref int x = ref (new int[1])[0]; // 1, 2 - Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "ref int x = ref (new int[1])[0];").WithLocation(8, 13), - // (8,21): error CS8177: Async methods cannot have by-reference locals - // ref int x = ref (new int[1])[0]; // 1, 2 - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x").WithLocation(8, 21)); + // ref int x = ref (new int[1])[0]; // 1 + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "ref int x = ref (new int[1])[0];").WithLocation(8, 13)); } [Fact] @@ -3087,14 +3152,147 @@ IEnumerable localFunction() } } }"; - - CreateCompilation(code).VerifyDiagnostics( - // (13,21): error CS8176: Iterators cannot have by-reference locals - // ref int z = ref x; - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "z").WithLocation(13, 21), - // (8,17): error CS8176: Iterators cannot have by-reference locals + CreateCompilation(code, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // ref int y = ref x; - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "y").WithLocation(8, 17)); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 17), + // (13,21): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int z = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "z").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 21)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(code).VerifyEmitDiagnostics(); + } + + [Fact] + public void RefLocal_Iterator_LocalFunction_01() + { + var code = """ + using System; + using System.Collections.Generic; + + int x = 5; + + foreach (var z in func()) + { + Console.Write(z); + x++; + } + + IEnumerable func() + { + ref int y = ref x; + yield return y; + y = ref x; + yield return y; + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (14,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(14, 13)); + + var expectedOutput = "56"; + + CompileAndVerify(code, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + CompileAndVerify(code, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void RefLocal_Iterator_LocalFunction_02() + { + var code = """ + using System.Collections.Generic; + + int x = 5; + + IEnumerable func() + { + ref int y = ref x; + yield return y; + yield return y; + } + + func(); + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 13)); + + var expectedDiagnostics = new[] + { + // (9,18): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // yield return y; + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(9, 18) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(code).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_Iterator_LocalFunction_01() + { + var code = """ + using System; + using System.Collections.Generic; + + int x = 5; + + foreach (var z in func()) + { + Console.Write(z); + x++; + } + + IEnumerable func() + { + Span y = new(ref x); + yield return y[0]; + y = new(ref x); + yield return y[0]; + } + """; + + var expectedOutput = ExecutionConditionUtil.IsDesktop ? null : "56"; + + CompileAndVerify(code, expectedOutput: expectedOutput, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net70, verify: Verification.FailsPEVerify).VerifyDiagnostics(); + CompileAndVerify(code, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net70, verify: Verification.FailsPEVerify).VerifyDiagnostics(); + CompileAndVerify(code, expectedOutput: expectedOutput, targetFramework: TargetFramework.Net70, verify: Verification.FailsPEVerify).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_Iterator_LocalFunction_02() + { + var code = """ + using System; + using System.Collections.Generic; + + int x = 5; + + IEnumerable func() + { + Span y = new(ref x); + yield return y[0]; + yield return y[0]; + } + + func(); + """; + + var expectedDiagnostics = new[] + { + // (10,18): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // yield return y[0]; + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(10, 18) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(code, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); } [Fact, WorkItem(13073, "https://github.com/dotnet/roslyn/issues/13073")] @@ -3115,13 +3313,152 @@ await Task.Run(async () => }); } }"; - CreateCompilationWithMscorlib45(code).VerifyDiagnostics( - // (8,17): error CS8177: Async methods cannot have by-reference locals + CreateCompilation(code, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // ref int y = ref x; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y").WithLocation(8, 17), - // (11,21): error CS8177: Async methods cannot have by-reference locals + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 17), + // (11,21): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // ref int z = ref x; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "z").WithLocation(11, 21)); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "z").WithArguments("ref and unsafe in async and iterator methods").WithLocation(11, 21)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(code).VerifyEmitDiagnostics(); + } + + [Fact] + public void RefLocal_Async_LocalFunction_01() + { + var code = """ + using System; + using System.Threading.Tasks; + + int x = 5; + + await func(); + + async Task func() + { + ref int y = ref x; + Console.Write(y); + await Task.Yield(); + y = ref x; + Console.Write(y); + await Task.Yield(); + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (10,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 13)); + + var expectedOutput = "55"; + + CompileAndVerify(code, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(); + CompileAndVerify(code, expectedOutput: expectedOutput).VerifyDiagnostics(); + } + + [Fact] + public void RefLocal_Async_LocalFunction_02() + { + var code = """ + using System; + using System.Threading.Tasks; + + int x = 5; + + async Task func() + { + ref int y = ref x; + await Task.Yield(); + Console.Write(y); + } + + await func(); + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int y = ref x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "y").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 13)); + + var expectedDiagnostics = new[] + { + // (10,19): error CS9217: A 'ref' local cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y); + Diagnostic(ErrorCode.ERR_RefLocalAcrossAwait, "y").WithLocation(10, 19) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(code).VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void RefStruct_Async_LocalFunction_01() + { + var code = """ + using System; + using System.Threading.Tasks; + + int x = 5; + + await func(); + + async Task func() + { + Span y = new(ref x); + Console.Write(y[0]); + await Task.Yield(); + y = new(ref x); + Console.Write(y[0]); + await Task.Yield(); + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (10,5): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // Span y = new(ref x); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Span").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 5)); + + var expectedOutput = ExecutionConditionUtil.IsDesktop ? null : "55"; + + CompileAndVerify(code, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net70, verify: Verification.FailsPEVerify).VerifyDiagnostics(); + CompileAndVerify(code, expectedOutput: expectedOutput, targetFramework: TargetFramework.Net70, verify: Verification.FailsPEVerify).VerifyDiagnostics(); + } + + [Fact] + public void RefStruct_Async_LocalFunction_02() + { + var code = """ + using System; + using System.Threading.Tasks; + + int x = 5; + + async Task func() + { + Span y = new(ref x); + await Task.Yield(); + Console.Write(y[0]); + } + + await func(); + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, targetFramework: TargetFramework.Net70).VerifyDiagnostics( + // (8,5): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // Span y = new(ref x); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Span").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 5)); + + var expectedDiagnostics = new[] + { + // (10,19): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // Console.Write(y[0]); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(10, 19) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); + CreateCompilation(code, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics(expectedDiagnostics); } [Fact, WorkItem(13073, "https://github.com/dotnet/roslyn/issues/13073")] @@ -3434,15 +3771,40 @@ static async void Goo() } "; - CreateCompilationWithMscorlib46(text).VerifyDiagnostics( - // (8,17): error CS8177: Async methods cannot have by-reference locals - // ref int i = ref field; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "i").WithLocation(8, 17), + CreateCompilationWithMscorlib46(text).VerifyEmitDiagnostics( // (6,23): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. // static async void Goo() Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Goo").WithLocation(6, 23)); } + [Fact] + public void RefReturnAcrossAwaitExpression() + { + var code = """ + using System.Threading.Tasks; + + class Program + { + static int field = 1; + + static async Task Main() + { + M1(ref GiveMeRef(), await M2()); + } + + static void M1(ref int i, int j) { } + + static ref int GiveMeRef() => ref field; + + static Task M2() => Task.FromResult(field++); + } + """; + CreateCompilation(code).VerifyEmitDiagnostics( + // (9,16): error CS8178: A reference returned by a call to 'Program.GiveMeRef()' cannot be preserved across 'await' or 'yield' boundary. + // M1(ref GiveMeRef(), await M2()); + Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, "GiveMeRef()").WithArguments("Program.GiveMeRef()").WithLocation(9, 16)); + } + [Fact] public void BadRefLocalInIteratorMethod() { @@ -3461,10 +3823,7 @@ static IEnumerable ObjEnumerable() } "; - CreateCompilationWithMscorlib46(text).VerifyDiagnostics( - // (10,17): error CS8931: Iterators cannot have by-reference locals - // ref int i = ref field; - Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "i").WithLocation(10, 17)); + CreateCompilationWithMscorlib46(text).VerifyEmitDiagnostics(); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index 5fb336b121a87..d361b612ede78 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -7269,15 +7269,15 @@ static void Main() }"; var comp = CreateCompilationWithMscorlib40AndSystemCore(source); comp.VerifyDiagnostics( - // (10,14): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + // (10,14): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // f = x=>f(__arglist); - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle"), - // (11,29): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(10, 14), + // (11,29): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // f = delegate { return f(__arglist); }; - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle"), - // (12,44): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(11, 29), + // (12,44): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // var q = from x in new int[10] select f(__arglist); - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle") + Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "__arglist").WithArguments("System.RuntimeArgumentHandle").WithLocation(12, 44) ); } @@ -7304,12 +7304,12 @@ static void Main() } }"; CreateCompilationWithMscorlib45(source).VerifyEmitDiagnostics( - // (10,34): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + // (10,34): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // RuntimeArgumentHandle h2 = h; // Bad use of h - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "h").WithArguments("System.RuntimeArgumentHandle"), - // (11,43): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "h").WithArguments("System.RuntimeArgumentHandle").WithLocation(10, 34), + // (11,43): error CS4013: Instance of type 'RuntimeArgumentHandle' cannot be used inside a nested function, query expression, iterator block or async method // ArgIterator args1 = new ArgIterator(h); // Bad use of h - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "h").WithArguments("System.RuntimeArgumentHandle")); + Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "h").WithArguments("System.RuntimeArgumentHandle").WithLocation(11, 43)); } [Fact] @@ -7321,9 +7321,9 @@ public void CS4013ERR_SpecialByRefInLambda03() public class C { static void N(RuntimeArgumentHandle x) {} - static IEnumerable M(RuntimeArgumentHandle h1) // Error: hoisted to field + static IEnumerable M(RuntimeArgumentHandle h1) { - N(h1); + N(h1); // Error: hoisted to field yield return 1; RuntimeArgumentHandle h2 = default(RuntimeArgumentHandle); yield return 2; @@ -7339,12 +7339,12 @@ static void Main() CreateCompilation(source).Emit(new System.IO.MemoryStream()).Diagnostics .Verify( - // (7,51): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method - // static IEnumerable M(RuntimeArgumentHandle h1) // Error: hoisted to field - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "h1").WithArguments("System.RuntimeArgumentHandle"), - // (13,7): error CS4013: Instance of type 'System.RuntimeArgumentHandle' cannot be used inside an anonymous function, query expression, iterator block or async method + // (9,7): error CS4007: Instance of type 'System.RuntimeArgumentHandle' cannot be preserved across 'await' or 'yield' boundary. + // N(h1); // Error: hoisted to field + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "h1").WithArguments("System.RuntimeArgumentHandle").WithLocation(9, 7), + // (13,7): error CS4007: Instance of type 'System.RuntimeArgumentHandle' cannot be preserved across 'await' or 'yield' boundary. // N(h2); // Error: hoisted to field - Diagnostic(ErrorCode.ERR_SpecialByRefInLambda, "h2").WithArguments("System.RuntimeArgumentHandle") + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "h2").WithArguments("System.RuntimeArgumentHandle").WithLocation(13, 7) ); } @@ -15318,35 +15318,48 @@ class C { IEnumerator IteratorMeth() { int i; - unsafe // CS1629 + unsafe { int *p = &i; yield return *p; } } - unsafe IEnumerator IteratorMeth2() { // CS1629 + unsafe IEnumerator IteratorMeth2() { yield break; } } "; - CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (7,7): error CS1629: Unsafe code may not appear in iterators - // unsafe // CS1629 - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "unsafe"), - // (9,10): error CS1629: Unsafe code may not appear in iterators + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (7,7): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 7), + // (9,10): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // int *p = &i; - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "int *"), - // (9,19): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int *").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 10), + // (9,19): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // int *p = &i; - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "&i"), - // (10,24): error CS1629: Unsafe code may not appear in iterators + Diagnostic(ErrorCode.ERR_FeatureInPreview, "&i").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 19), + // (10,24): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // yield return *p; - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "p"), - // (14,29): error CS1629: Unsafe code may not appear in iterators - // unsafe IEnumerator IteratorMeth2() { // CS1629 - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "IteratorMeth2") + Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 24), + // (14,29): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe IEnumerator IteratorMeth2() { + Diagnostic(ErrorCode.ERR_FeatureInPreview, "IteratorMeth2").WithArguments("ref and unsafe in async and iterator methods").WithLocation(14, 29) ); + + var expectedDiagnostics = new[] + { + // (9,20): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int *p = &i; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "i").WithLocation(9, 20), + // (10,10): error CS9238: Cannot use 'yield return' in an 'unsafe' block + // yield return *p; + Diagnostic(ErrorCode.ERR_BadYieldInUnsafe, "yield").WithLocation(10, 10) + }; + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -18436,7 +18449,10 @@ static void Main() } "; var comp = CreateCompilation(text, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: "Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (12,9): error CS1971: The call to method 'M' needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access. + // base.M(d); + Diagnostic(ErrorCode.ERR_NoDynamicPhantomOnBase, "base.M(d)").WithArguments("M")); } [Fact] @@ -18527,39 +18543,10 @@ public string M(object o) "; var comp = CreateCompilation(text, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.DebugExe); - var verifier = CompileAndVerify(comp, expectedOutput: "You passed 1").VerifyDiagnostics(); - - verifier.VerifyIL("D.M", -@" -{ - // Code size 78 (0x4e) - .maxstack 4 - .locals init (string V_0) - IL_0000: nop - IL_0001: ldarg.0 - IL_0002: ldsfld ""System.Runtime.CompilerServices.CallSite> D.<>o__1.<>p__0"" - IL_0007: brfalse.s IL_000b - IL_0009: br.s IL_002f - IL_000b: ldc.i4.0 - IL_000c: ldtoken ""int"" - IL_0011: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0016: ldtoken ""D"" - IL_001b: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)"" - IL_0020: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.Convert(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, System.Type, System.Type)"" - IL_0025: call ""System.Runtime.CompilerServices.CallSite> System.Runtime.CompilerServices.CallSite>.Create(System.Runtime.CompilerServices.CallSiteBinder)"" - IL_002a: stsfld ""System.Runtime.CompilerServices.CallSite> D.<>o__1.<>p__0"" - IL_002f: ldsfld ""System.Runtime.CompilerServices.CallSite> D.<>o__1.<>p__0"" - IL_0034: ldfld ""System.Func System.Runtime.CompilerServices.CallSite>.Target"" - IL_0039: ldsfld ""System.Runtime.CompilerServices.CallSite> D.<>o__1.<>p__0"" - IL_003e: ldarg.1 - IL_003f: callvirt ""int System.Func.Invoke(System.Runtime.CompilerServices.CallSite, dynamic)"" - IL_0044: call ""string B.this[int].get"" - IL_0049: stloc.0 - IL_004a: br.s IL_004c - IL_004c: ldloc.0 - IL_004d: ret -} -"); + comp.VerifyDiagnostics( + // (19,16): error CS1972: The indexer access needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access. + // int s = base[(dynamic)o]; + Diagnostic(ErrorCode.ERR_NoDynamicPhantomOnBaseIndexer, "base[(dynamic)o]")); } [Fact] @@ -18582,7 +18569,11 @@ static public class Extension }"; var comp = CreateCompilation(text, targetFramework: TargetFramework.StandardAndCSharp, options: TestOptions.DebugExe); - CompileAndVerify(comp, expectedOutput: "Called").VerifyDiagnostics(); + comp.VerifyDiagnostics( + // (8,9): error CS1973: 'B' has no applicable method named 'Goo' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax. + // b.Goo(d); + Diagnostic(ErrorCode.ERR_BadArgTypeDynamicExtension, "b.Goo(d)").WithArguments("B", "Goo").WithLocation(8, 9) + ); } [Fact] @@ -22778,7 +22769,10 @@ static void Bar(string x) {} }"; var comp = CreateCompilationWithMscorlib40AndSystemCore(text); - comp.VerifyDiagnostics(); + comp.VerifyDiagnostics( +// (9,9): warning CS1974: The dynamically dispatched call to method 'Goo' may fail at runtime because one or more applicable overloads are conditional methods. +// Goo(d); +Diagnostic(ErrorCode.WRN_DynamicDispatchToConditionalMethod, "Goo(d)").WithArguments("Goo")); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs index 922ac7985d750..76443b048bb7f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SpanStackSafetyTests.cs @@ -264,9 +264,9 @@ void M(T t) } }"); comp.VerifyDiagnostics( - // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'T' and 'Span' + // (7,13): warning CS0184: The given expression is never of the provided ('Span') type // if (t is Span) - Diagnostic(ErrorCode.ERR_BadBinaryOps, "t is Span").WithArguments("is", "T", "System.Span").WithLocation(7, 13), + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "t is Span").WithArguments("System.Span").WithLocation(7, 13), // (9,18): error CS8121: An expression of type 'T' cannot be handled by a pattern of type 'Span'. // if (t is Span s) Diagnostic(ErrorCode.ERR_PatternWrongType, "Span").WithArguments("T", "System.Span").WithLocation(9, 18)); @@ -308,9 +308,9 @@ void M(Span s) } }"); comp.VerifyDiagnostics( - // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'Span' and 'T' + // (7,13): warning CS0184: The given expression is never of the provided ('T') type // if (s is T) { } - Diagnostic(ErrorCode.ERR_BadBinaryOps, "s is T").WithArguments("is", "System.Span", "T").WithLocation(7, 13), + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "s is T").WithArguments("T").WithLocation(7, 13), // (8,18): error CS8121: An expression of type 'Span' cannot be handled by a pattern of type 'T'. // if (s is T t) { } Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("System.Span", "T").WithLocation(8, 18)); @@ -330,9 +330,9 @@ void M(Span s) where T : struct } }"); comp.VerifyDiagnostics( - // (7,13): error CS0019: Operator 'is' cannot be applied to operands of type 'Span' and 'T' + // (7,13): warning CS0184: The given expression is never of the provided ('T') type // if (s is T) { } - Diagnostic(ErrorCode.ERR_BadBinaryOps, "s is T").WithArguments("is", "System.Span", "T").WithLocation(7, 13), + Diagnostic(ErrorCode.WRN_IsAlwaysFalse, "s is T").WithArguments("T").WithLocation(7, 13), // (8,18): error CS8121: An expression of type 'Span' cannot be handled by a pattern of type 'T'. // if (s is T t) { } Diagnostic(ErrorCode.ERR_PatternWrongType, "T").WithArguments("System.Span", "T").WithLocation(8, 18)); @@ -444,9 +444,9 @@ class C1 where T: Span // (13,26): error CS0701: 'Span' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter. // class C1 where T: Span Diagnostic(ErrorCode.ERR_BadBoundType, "Span").WithArguments("System.Span").WithLocation(13, 26), - // (10,14): error CS0306: The type 'Span' may not be used as a type argument + // (10,14): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Func' // Func> d = ()=>x; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "Span").WithArguments("System.Span").WithLocation(10, 14), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "Span").WithArguments("System.Func", "TResult", "System.Span").WithLocation(10, 14), // (10,33): error CS8175: Cannot use ref local 'x' inside an anonymous method, lambda expression, or query expression // Func> d = ()=>x; Diagnostic(ErrorCode.ERR_AnonDelegateCantUseLocal, "x").WithArguments("x").WithLocation(10, 33) @@ -698,7 +698,7 @@ public struct S2 [WorkItem(20226, "https://github.com/dotnet/roslyn/issues/20226")] [Fact] - public void InterfaceImpl() + public void InterfaceImpl_01() { var text = @" using System; @@ -709,24 +709,177 @@ static void Main(string[] args) { using (new S1()) { + System.Console.Write(1); + } + + System.Console.Write(3); + } + public ref struct S1 : IDisposable + { + public void Dispose() + { + System.Console.Write(2); } } +} +"; + + CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: @"123").VerifyDiagnostics(); + + verifier.VerifyIL("Program.Main", +@" +{ + // Code size 31 (0x1f) + .maxstack 1 + .locals init (Program.S1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ""Program.S1"" + .try + { + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: leave.s IL_0018 + } + finally + { + IL_0010: ldloca.s V_0 + IL_0012: call ""void Program.S1.Dispose()"" + IL_0017: endfinally + } + IL_0018: ldc.i4.3 + IL_0019: call ""void System.Console.Write(int)"" + IL_001e: ret +} +"); + } + + [Fact] + public void InterfaceImpl_02() + { + var text = @" +using System; + +public class Program +{ + static void Main(string[] args) + { + using (new S1()) + { + System.Console.Write(1); + } + + System.Console.Write(3); + } public ref struct S1 : IDisposable { - public void Dispose() { } + public void Dispose() + { + System.Console.Write(22); + } + + void IDisposable.Dispose() + { + System.Console.Write(2); + } } } "; - CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); + CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: @"1223").VerifyDiagnostics(); + + // We prioritize pattern over an interface according to https://github.com/dotnet/csharplang/blob/main/proposals/ref-struct-interfaces.md#using-statement + + verifier.VerifyIL("Program.Main", +@" +{ + // Code size 31 (0x1f) + .maxstack 1 + .locals init (Program.S1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ""Program.S1"" + .try + { + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: leave.s IL_0018 + } + finally + { + IL_0010: ldloca.s V_0 + IL_0012: call ""void Program.S1.Dispose()"" + IL_0017: endfinally + } + IL_0018: ldc.i4.3 + IL_0019: call ""void System.Console.Write(int)"" + IL_001e: ret +} +"); + } - comp.VerifyDiagnostics( - // (14,28): error CS8343: 'Program.S1': ref structs cannot implement interfaces - // public ref struct S1 : IDisposable - Diagnostic(ErrorCode.ERR_RefStructInterfaceImpl, "IDisposable").WithArguments("Program.S1").WithLocation(14, 28) - ); + [Fact] + public void InterfaceImpl_03() + { + var text = @" +using System; + +public class Program +{ + static void Main(string[] args) + { + using (new S1()) + { + System.Console.Write(1); + } + + System.Console.Write(3); + } + + public ref struct S1 : IDisposable + { + void IDisposable.Dispose() + { + System.Console.Write(2); + } + } +} +"; + + CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: @"123").VerifyDiagnostics(); + + verifier.VerifyIL("Program.Main", +@" +{ + // Code size 37 (0x25) + .maxstack 1 + .locals init (Program.S1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ""Program.S1"" + .try + { + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: leave.s IL_001e + } + finally + { + IL_0010: ldloca.s V_0 + IL_0012: constrained. ""Program.S1"" + IL_0018: callvirt ""void System.IDisposable.Dispose()"" + IL_001d: endfinally + } + IL_001e: ldc.i4.3 + IL_001f: call ""void System.Console.Write(int)"" + IL_0024: ret +} +"); } [Fact] @@ -739,21 +892,51 @@ static void Main(string[] args) { using (new S1()) { - + System.Console.Write(1); } + + System.Console.Write(3); } public ref struct S1 { - public void Dispose() { } + public void Dispose() + { + System.Console.Write(2); + } } } "; - CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); - - comp.VerifyDiagnostics( - ); + CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text, options: TestOptions.ReleaseExe); + + var verifier = CompileAndVerify(comp, expectedOutput: @"123").VerifyDiagnostics(); + + verifier.VerifyIL("Program.Main", +@" +{ + // Code size 31 (0x1f) + .maxstack 1 + .locals init (Program.S1 V_0) + IL_0000: ldloca.s V_0 + IL_0002: initobj ""Program.S1"" + .try + { + IL_0008: ldc.i4.1 + IL_0009: call ""void System.Console.Write(int)"" + IL_000e: leave.s IL_0018 + } + finally + { + IL_0010: ldloca.s V_0 + IL_0012: call ""void Program.S1.Dispose()"" + IL_0017: endfinally + } + IL_0018: ldc.i4.3 + IL_0019: call ""void System.Console.Write(int)"" + IL_001e: ret +} +"); } [WorkItem(20226, "https://github.com/dotnet/roslyn/issues/20226")] @@ -807,7 +990,7 @@ public bool MoveNext() CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); comp.VerifyDiagnostics( - // (15,9): error CS8344: foreach statement cannot operate on enumerators of type 'C1.S1' in async or iterator methods because 'C1.S1' is a ref struct. + // (15,9): error CS8344: foreach statement cannot operate on enumerators of type 'C1.S1' in async or iterator methods because 'C1.S1' is a ref struct or a type parameter that allows ref struct. // foreach (var i in obj) Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("C1.S1").WithLocation(15, 9) ); @@ -879,7 +1062,7 @@ public bool MoveNext() CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); comp.VerifyDiagnostics( - // (33,9): error CS8344: foreach statement cannot operate on enumerators of type 'C1.S1' in async or iterator methods because 'C1.S1' is a ref struct. + // (33,9): error CS8344: foreach statement cannot operate on enumerators of type 'C1.S1' in async or iterator methods because 'C1.S1' is a ref struct or a type parameter that allows ref struct. // foreach (var i in new C1()) Diagnostic(ErrorCode.ERR_BadSpecialByRefIterator, "foreach").WithArguments("C1.S1").WithLocation(33, 9) ); @@ -975,9 +1158,9 @@ public static async Task M1(Span arg) CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); comp.VerifyDiagnostics( - // (11,48): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. + // (11,48): error CS4012: Parameters of type 'Span' cannot be declared in async methods or async lambda expressions. // public static async Task M1(Span arg) - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "arg").WithArguments("System.Span").WithLocation(11, 48) + Diagnostic(ErrorCode.ERR_BadSpecialByRefParameter, "arg").WithArguments("System.Span").WithLocation(11, 48) ); } @@ -996,48 +1179,77 @@ static void Main() public static async Task M1() { - Span local1 = default(Span); // 1 - var local2 = default(Span); // 2 + Span local1 = default(Span); + var local2 = default(Span); await Task.Yield(); return 42; } + + public static async Task M2() + { + Span local1 = default(Span); + var local2 = default(Span); + + await Task.Yield(); + return local1.Length; // 1 + } + + public static async Task M3() + { + Span local1 = default(Span); + var local2 = default(Span); + + await Task.Yield(); + return local2.Length; // 2 + } + + public static async Task M4() + { + Span local1 = default(Span); + var local2 = default(Span); + + await Task.Yield(); + return local1.Length + local2.Length; // 3, 4 + } } "; - CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); - - comp.VerifyDiagnostics( - // (13,9): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // Span local1 = default(Span); // 1 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(13, 9), + var expectedDiagnostics = new[] + { // (13,19): warning CS0219: The variable 'local1' is assigned but its value is never used - // Span local1 = default(Span); // 1 + // Span local1 = default(Span); Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local1").WithArguments("local1").WithLocation(13, 19), - // (14,9): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // var local2 = default(Span); // 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.Span").WithLocation(14, 9), // (14,13): warning CS0219: The variable 'local2' is assigned but its value is never used - // var local2 = default(Span); // 2 - Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local2").WithArguments("local2").WithLocation(14, 13) - ); + // var local2 = default(Span); + Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local2").WithArguments("local2").WithLocation(14, 13), + // (23,13): warning CS0219: The variable 'local2' is assigned but its value is never used + // var local2 = default(Span); + Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local2").WithArguments("local2").WithLocation(23, 13), + // (26,16): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // return local1.Length; // 1 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local1").WithArguments("System.Span").WithLocation(26, 16), + // (31,19): warning CS0219: The variable 'local1' is assigned but its value is never used + // Span local1 = default(Span); + Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local1").WithArguments("local1").WithLocation(31, 19), + // (35,16): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // return local2.Length; // 2 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local2").WithArguments("System.Span").WithLocation(35, 16), + // (44,16): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // return local1.Length + local2.Length; // 3, 4 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local1").WithArguments("System.Span").WithLocation(44, 16), + // (44,32): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // return local1.Length + local2.Length; // 3, 4 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local2").WithArguments("System.Span").WithLocation(44, 32) + }; + + CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); + + comp.VerifyEmitDiagnostics(expectedDiagnostics); comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.DebugExe); - comp.VerifyDiagnostics( - // (13,9): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // Span local1 = default(Span); // 1 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(13, 9), - // (13,19): warning CS0219: The variable 'local1' is assigned but its value is never used - // Span local1 = default(Span); // 1 - Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local1").WithArguments("local1").WithLocation(13, 19), - // (14,9): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // var local2 = default(Span); // 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.Span").WithLocation(14, 9), - // (14,13): warning CS0219: The variable 'local2' is assigned but its value is never used - // var local2 = default(Span); // 2 - Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "local2").WithArguments("local2").WithLocation(14, 13) - ); + comp.VerifyEmitDiagnostics(expectedDiagnostics); } [Fact] @@ -1051,27 +1263,44 @@ public class Program { public static async Task M1() { - M2(out var local1); // 1 - M2(out Span local2); // 2 + M2(out var local1); + M2(out Span local2); await Task.Yield(); return 42; } + public static async Task M3() + { + M2(out var local1); + M2(out Span local2); + + await Task.Yield(); + return local1.Length; // 1 + } + + public static async Task M4() + { + M2(out var local1); + M2(out Span local2); + + await Task.Yield(); + return local2.Length; // 2 + } + static void M2(out Span s) => throw null; } "; CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); - comp.VerifyDiagnostics( - // (9,16): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // M2(out var local1); // 1 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.Span").WithLocation(9, 16), - // (10,16): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // M2(out Span local2); // 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(10, 16) - ); + comp.VerifyEmitDiagnostics( + // (22,16): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // return local1.Length; // 1 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local1").WithArguments("System.Span").WithLocation(22, 16), + // (31,16): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // return local2.Length; // 2 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "local2").WithArguments("System.Span").WithLocation(31, 16)); } [Fact, WorkItem(62747, "https://github.com/dotnet/roslyn/issues/62747")] @@ -1086,30 +1315,49 @@ public class Program { public async Task M(IReadOnlyList o) { - foreach (ReadOnlySpan c1 in o) { } // 1 + foreach (ReadOnlySpan c1 in o) { } var enumerator = ((IEnumerable)o).GetEnumerator(); while (enumerator.MoveNext()) { - ReadOnlySpan c2 = (ReadOnlySpan)(string)enumerator.Current; // 2 + ReadOnlySpan c2 = (ReadOnlySpan)(string)enumerator.Current; _ = c2.Length; } await Task.Yield(); return; } + + public async Task M2(IReadOnlyList o) + { + foreach (ReadOnlySpan c1 in o) + { + await Task.Yield(); + _ = c1.Length; // 1 + } + + var enumerator = ((IEnumerable)o).GetEnumerator(); + while (enumerator.MoveNext()) + { + ReadOnlySpan c2 = (ReadOnlySpan)(string)enumerator.Current; + await Task.Yield(); + _ = c2.Length; // 2 + } + + await Task.Yield(); + return; + } } "; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70); - comp.VerifyDiagnostics( - // (10,18): error CS4012: Parameters or locals of type 'ReadOnlySpan' cannot be declared in async methods or async lambda expressions. - // foreach (ReadOnlySpan c1 in o) { } // 1 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "ReadOnlySpan").WithArguments("System.ReadOnlySpan").WithLocation(10, 18), - // (15,13): error CS4012: Parameters or locals of type 'ReadOnlySpan' cannot be declared in async methods or async lambda expressions. - // ReadOnlySpan c2 = (ReadOnlySpan)(string)enumerator.Current; // 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "ReadOnlySpan").WithArguments("System.ReadOnlySpan").WithLocation(15, 13) - ); + comp.VerifyEmitDiagnostics( + // (28,17): error CS4007: Instance of type 'System.ReadOnlySpan' cannot be preserved across 'await' or 'yield' boundary. + // _ = c1.Length; // 1 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "c1").WithArguments("System.ReadOnlySpan").WithLocation(28, 17), + // (36,17): error CS4007: Instance of type 'System.ReadOnlySpan' cannot be preserved across 'await' or 'yield' boundary. + // _ = c2.Length; // 2 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "c2").WithArguments("System.ReadOnlySpan").WithLocation(36, 17)); } [Fact, WorkItem(62747, "https://github.com/dotnet/roslyn/issues/62747")] @@ -1123,11 +1371,23 @@ public class Program { public async Task M() { - (Span s1, Span s2) = new Program(); // 1, 2 - var (s3, s4) = new Program(); // 3, 4 - (var s5, var s6) = new Program(); // 5, 6 + (Span s1, Span s2) = new Program(); + var (s3, s4) = new Program(); + (var s5, var s6) = new Program(); + + await Task.Yield(); + return; + } + + public async Task M2() + { + (Span s1, Span s2) = new Program(); + var (s3, s4) = new Program(); + (var s5, var s6) = new Program(); await Task.Yield(); + + _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3 return; } @@ -1135,26 +1395,16 @@ public async Task M() } "; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70); - comp.VerifyDiagnostics( - // (9,10): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // (Span s1, Span s2) = new Program(); // 1, 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(9, 10), - // (9,24): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // (Span s1, Span s2) = new Program(); // 1, 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(9, 24), - // (10,14): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // var (s3, s4) = new Program(); // 3, 4 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "s3").WithArguments("System.Span").WithLocation(10, 14), - // (10,18): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // var (s3, s4) = new Program(); // 3, 4 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "s4").WithArguments("System.Span").WithLocation(10, 18), - // (11,10): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // (var s5, var s6) = new Program(); // 5, 6 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.Span").WithLocation(11, 10), - // (11,18): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // (var s5, var s6) = new Program(); // 5, 6 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("System.Span").WithLocation(11, 18) - ); + comp.VerifyEmitDiagnostics( + // (25,13): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s1").WithArguments("System.Span").WithLocation(25, 13), + // (25,25): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s4").WithArguments("System.Span").WithLocation(25, 25), + // (25,37): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // _ = s1.Length + s4.Length + s5.Length; // 1, 2, 3 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s5").WithArguments("System.Span").WithLocation(25, 37)); } [Fact, WorkItem(62747, "https://github.com/dotnet/roslyn/issues/62747")] @@ -1167,11 +1417,26 @@ public class Program { public async Task M() { - using (default(RS)) { } // 1 - using (var s1 = default(RS)) { } // 2 - using (RS s2 = default(RS)) { } // 3 - using RS s3 = default(RS); // 4 - using var s4 = default(RS); // 5 + using (default(RS)) { } + using (var s1 = default(RS)) { } + using (RS s2 = default(RS)) { } + using RS s3 = default(RS); // 1 + using var s4 = default(RS); // 2 + + await Task.Yield(); + return; + } + + public async Task M2() + { + using (default(RS)) { await Task.Yield(); } // 3 + using (var s1 = default(RS)) { await Task.Yield(); } // 4 + using (RS s2 = default(RS)) { await Task.Yield(); } // 5 + { + using RS s3 = default(RS); // 6 + await Task.Yield(); + using var s4 = default(RS); + } await Task.Yield(); return; @@ -1184,23 +1449,25 @@ public void Dispose() { } } "; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70); - comp.VerifyDiagnostics( - // (8,16): error CS9104: A using statement resource of type 'RS' cannot be used in async methods or async lambda expressions. - // using (default(RS)) { } // 1 - Diagnostic(ErrorCode.ERR_BadSpecialByRefUsing, "default(RS)").WithArguments("RS").WithLocation(8, 16), - // (9,16): error CS4012: Parameters or locals of type 'RS' cannot be declared in async methods or async lambda expressions. - // using (var s1 = default(RS)) { } // 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("RS").WithLocation(9, 16), - // (10,16): error CS4012: Parameters or locals of type 'RS' cannot be declared in async methods or async lambda expressions. - // using (RS s2 = default(RS)) { } // 3 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "RS").WithArguments("RS").WithLocation(10, 16), - // (11,15): error CS4012: Parameters or locals of type 'RS' cannot be declared in async methods or async lambda expressions. - // using RS s3 = default(RS); // 4 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "RS").WithArguments("RS").WithLocation(11, 15), - // (12,15): error CS4012: Parameters or locals of type 'RS' cannot be declared in async methods or async lambda expressions. - // using var s4 = default(RS); // 5 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "var").WithArguments("RS").WithLocation(12, 15) - ); + comp.VerifyEmitDiagnostics( + // (11,18): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary. + // using RS s3 = default(RS); // 1 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s3 = default(RS)").WithArguments("RS").WithLocation(11, 18), + // (12,19): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary. + // using var s4 = default(RS); // 2 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s4 = default(RS)").WithArguments("RS").WithLocation(12, 19), + // (20,16): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary. + // using (default(RS)) { await Task.Yield(); } // 3 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "default(RS)").WithArguments("RS").WithLocation(20, 16), + // (21,20): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary. + // using (var s1 = default(RS)) { await Task.Yield(); } // 4 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s1 = default(RS)").WithArguments("RS").WithLocation(21, 20), + // (22,19): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary. + // using (RS s2 = default(RS)) { await Task.Yield(); } // 5 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s2 = default(RS)").WithArguments("RS").WithLocation(22, 19), + // (24,22): error CS4007: Instance of type 'RS' cannot be preserved across 'await' or 'yield' boundary. + // using RS s3 = default(RS); // 6 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s3 = default(RS)").WithArguments("RS").WithLocation(24, 22)); } [Fact] @@ -1214,24 +1481,76 @@ public class Program { public async Task M() { - if (M2() is var s1) { } // 1 - if (M2() is Span s2) { } // 2 + if (M2() is var s1) { } + if (M2() is Span s2) { } + if (M2() is var s3) { await Task.Yield(); } + if (M2() is Span s4) { await Task.Yield(); } + + await Task.Yield(); + return; + } + + public async Task M3() + { + if (M2() is var s1) + { + await Task.Yield(); + _ = s1.Length; // 1 + } + if (M2() is Span s2) + { + await Task.Yield(); + _ = s2.Length; // 2 + } await Task.Yield(); return; } + static Span M2() => throw null; } "; var comp = CreateCompilation(src, targetFramework: TargetFramework.Net70); - comp.VerifyDiagnostics( - // (9,25): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // if (M2() is var s1) { } // 1 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "s1").WithArguments("System.Span").WithLocation(9, 25), - // (10,21): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // if (M2() is Span s2) { } // 2 - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(10, 21) - ); + comp.VerifyEmitDiagnostics( + // (23,17): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // _ = s1.Length; + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s1").WithArguments("System.Span").WithLocation(23, 17), + // (28,17): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // _ = s2.Length; + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "s2").WithArguments("System.Span").WithLocation(28, 17)); + } + + [Fact] + public void AsyncLocals_Reassignment() + { + var code = """ + using System; + using System.Threading.Tasks; + class C + { + async Task M1() + { + int x = 42; + Span y = new(ref x); + y.ToString(); + await Task.Yield(); + y.ToString(); // 1 + } + async Task M2() + { + int x = 42; + Span y = new(ref x); + y.ToString(); + await Task.Yield(); + y = new(ref x); + y.ToString(); + } + } + """; + CreateCompilation(code, targetFramework: TargetFramework.Net70).VerifyEmitDiagnostics( + // (11,9): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. + // y.ToString(); // 1 + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "y").WithArguments("System.Span").WithLocation(11, 9)); } [Fact] @@ -1280,19 +1599,18 @@ public static async Task I1() CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); - comp.VerifyEmitDiagnostics( - // (17,39): error CS4007: 'await' cannot be used in an expression containing the type 'System.Span' + var expectedDiagnostics = new[] + { + // (17,19): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. // TakesSpan(default(Span), await I1()); - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await I1()").WithArguments("System.Span") - ); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "default(Span)").WithArguments("System.Span").WithLocation(17, 19) + }; + + comp.VerifyEmitDiagnostics(expectedDiagnostics); comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.DebugExe); - comp.VerifyEmitDiagnostics( - // (17,39): error CS4007: 'await' cannot be used in an expression containing the type 'System.Span' - // TakesSpan(default(Span), await I1()); - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await I1()").WithArguments("System.Span") - ); + comp.VerifyEmitDiagnostics(expectedDiagnostics); } [Fact] @@ -1331,19 +1649,49 @@ public static async Task I1() CSharpCompilation comp = CreateCompilationWithMscorlibAndSpan(text); - comp.VerifyEmitDiagnostics( - // (14,45): error CS4007: 'await' cannot be used in an expression containing the type 'Span' + var expectedDiagnostics = new[] + { + // (14,22): error CS4007: Instance of type 'System.Span' cannot be preserved across 'await' or 'yield' boundary. // TakesSpan(s: default(Span), i: await I1()); - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await I1()").WithArguments("System.Span").WithLocation(14, 45) - ); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "default(Span)").WithArguments("System.Span").WithLocation(14, 22) + }; + + comp.VerifyEmitDiagnostics(expectedDiagnostics); comp = CreateCompilationWithMscorlibAndSpan(text, TestOptions.DebugExe); - comp.VerifyEmitDiagnostics( - // (14,45): error CS4007: 'await' cannot be used in an expression containing the type 'Span' - // TakesSpan(s: default(Span), i: await I1()); - Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "await I1()").WithArguments("System.Span").WithLocation(14, 45) - ); + comp.VerifyEmitDiagnostics(expectedDiagnostics); + } + + [Fact] + public void AwaitAssignSpan() + { + var source = """ + using System; + using System.Threading.Tasks; + + ReadOnlySpan r = await M(); + Console.Write(r[1]); + + async Task M() + { + await Task.Yield(); + return new[] { 4, 5, 6 }; + } + """; + + CreateCompilationWithSpan(source, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,1): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ReadOnlySpan r = await M(); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "ReadOnlySpan").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 1)); + + var expectedOutput = "5"; + + var comp = CreateCompilationWithSpan(source, parseOptions: TestOptions.RegularNext); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); + + comp = CreateCompilationWithSpan(source); + CompileAndVerify(comp, expectedOutput: expectedOutput).VerifyDiagnostics(); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs index d96e6abf25f3b..d528b3110b0c5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs @@ -432,9 +432,9 @@ void Method1(S s, bool c) // (8,34): error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('') // var obj2 = c ? default : stackalloc[] { new {} }; Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new {} }").WithArguments("").WithLocation(8, 34), - // (9,34): error CS0306: The type 'Test.S' may not be used as a type argument + // (9,34): error CS9244: The type 'Test.S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Span' // var obj3 = c ? default : stackalloc[] { s }; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "stackalloc[] { s }").WithArguments("Test.S").WithLocation(9, 34) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "stackalloc[] { s }").WithArguments("System.Span", "T", "Test.S").WithLocation(9, 34) ); var tree = comp.SyntaxTrees.Single(); @@ -657,21 +657,21 @@ static void Method1(int[] array) ); CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseDll, parseOptions: TestOptions.Regular8) .VerifyDiagnostics( - // (7,37): error CS0306: The type 'Span' may not be used as a type argument + // (7,37): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Enumerable.Select(IEnumerable, Func)' // var q1 = from item in array select stackalloc int[3] { 1, 2, 3 }; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "select stackalloc int[3] { 1, 2, 3 }").WithArguments("System.Span").WithLocation(7, 37), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "select stackalloc int[3] { 1, 2, 3 }").WithArguments("System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)", "TResult", "System.Span").WithLocation(7, 37), // (7,44): error CS8353: A result of a stackalloc expression of type 'Span' cannot be used in this context because it may be exposed outside of the containing method // var q1 = from item in array select stackalloc int[3] { 1, 2, 3 }; Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[3] { 1, 2, 3 }").WithArguments("System.Span").WithLocation(7, 44), - // (8,37): error CS0306: The type 'Span' may not be used as a type argument + // (8,37): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Enumerable.Select(IEnumerable, Func)' // var q2 = from item in array select stackalloc int[ ] { 1, 2, 3 }; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "select stackalloc int[ ] { 1, 2, 3 }").WithArguments("System.Span").WithLocation(8, 37), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "select stackalloc int[ ] { 1, 2, 3 }").WithArguments("System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)", "TResult", "System.Span").WithLocation(8, 37), // (8,44): error CS8353: A result of a stackalloc expression of type 'Span' cannot be used in this context because it may be exposed outside of the containing method // var q2 = from item in array select stackalloc int[ ] { 1, 2, 3 }; Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc int[ ] { 1, 2, 3 }").WithArguments("System.Span").WithLocation(8, 44), - // (9,37): error CS0306: The type 'Span' may not be used as a type argument + // (9,37): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Enumerable.Select(IEnumerable, Func)' // var q3 = from item in array select stackalloc [ ] { 1, 2, 3 }; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "select stackalloc [ ] { 1, 2, 3 }").WithArguments("System.Span").WithLocation(9, 37), + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "select stackalloc [ ] { 1, 2, 3 }").WithArguments("System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)", "TResult", "System.Span").WithLocation(9, 37), // (9,44): error CS8353: A result of a stackalloc expression of type 'Span' cannot be used in this context because it may be exposed outside of the containing method // var q3 = from item in array select stackalloc [ ] { 1, 2, 3 }; Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc [ ] { 1, 2, 3 }").WithArguments("System.Span").WithLocation(9, 44) @@ -706,15 +706,15 @@ static void Method1(int[] array) ); CreateCompilationWithMscorlibAndSpan(source, TestOptions.ReleaseDll, parseOptions: TestOptions.Regular8) .VerifyDiagnostics( - // (7,75): error CS0306: The type 'Span' may not be used as a type argument + // (7,75): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Enumerable.Select(IEnumerable, Func)' // var q1 = from item in array let v = stackalloc int[3] { 1, 2, 3 } select v; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "select v").WithArguments("System.Span").WithLocation(7, 75), - // (8,75): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "select v").WithArguments("System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)", "TResult", "System.Span").WithLocation(7, 75), + // (8,75): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Enumerable.Select(IEnumerable, Func)' // var q2 = from item in array let v = stackalloc int[ ] { 1, 2, 3 } select v; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "select v").WithArguments("System.Span").WithLocation(8, 75), - // (9,75): error CS0306: The type 'Span' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "select v").WithArguments("System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)", "TResult", "System.Span").WithLocation(8, 75), + // (9,75): error CS9244: The type 'Span' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'TResult' in the generic type or method 'Enumerable.Select(IEnumerable, Func)' // var q3 = from item in array let v = stackalloc [ ] { 1, 2, 3 } select v; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "select v").WithArguments("System.Span").WithLocation(9, 75) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "select v").WithArguments("System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)", "TResult", "System.Span").WithLocation(9, 75) ); } @@ -757,13 +757,29 @@ async void M() comp.VerifyDiagnostics( // (8,38): error CS0150: A constant value is expected // Span p = stackalloc int[await Task.FromResult(1)] { await Task.FromResult(2) }; - Diagnostic(ErrorCode.ERR_ConstantExpected, "await Task.FromResult(1)").WithLocation(8, 38), - // (8,9): error CS4012: Parameters or locals of type 'Span' cannot be declared in async methods or async lambda expressions. - // Span p = stackalloc int[await Task.FromResult(1)] { await Task.FromResult(2) }; - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "Span").WithArguments("System.Span").WithLocation(8, 9) + Diagnostic(ErrorCode.ERR_ConstantExpected, "await Task.FromResult(1)").WithLocation(8, 38) ); } + [Fact] + public void TestAwait_Span_02() + { + var comp = CreateCompilationWithMscorlibAndSpan(""" + using System; + using System.Threading.Tasks; + class Test + { + static async Task Main() + { + Span p = stackalloc int[1] { await Task.FromResult(2) }; + Console.WriteLine(p[0]); + } + } + """, TestOptions.UnsafeReleaseExe); + + CompileAndVerify(comp, expectedOutput: "2", verify: Verification.Fails).VerifyDiagnostics(); + } + [Fact] public void TestSelfInSize() { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs index 102ee4ea9aca7..22a137fcd9673 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocSpanExpressionsTests.cs @@ -737,15 +737,15 @@ void M() var implicitError = explicitError.Length > 0 ? stackalloc S[10] : stackalloc S[100]; } }").VerifyDiagnostics( - // (8,14): error CS0306: The type 'S' may not be used as a type argument + // (8,14): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Span' // Span explicitError = default; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "S").WithArguments("S").WithLocation(8, 14), - // (9,67): error CS0306: The type 'S' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "S").WithArguments("System.Span", "T", "S").WithLocation(8, 14), + // (9,67): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Span' // var implicitError = explicitError.Length > 0 ? stackalloc S[10] : stackalloc S[100]; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "S[10]").WithArguments("S").WithLocation(9, 67), - // (9,86): error CS0306: The type 'S' may not be used as a type argument + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "S[10]").WithArguments("System.Span", "T", "S").WithLocation(9, 67), + // (9,86): error CS9244: The type 'S' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'Span' // var implicitError = explicitError.Length > 0 ? stackalloc S[10] : stackalloc S[100]; - Diagnostic(ErrorCode.ERR_BadTypeArgument, "S[100]").WithArguments("S").WithLocation(9, 86) + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "S[100]").WithArguments("System.Span", "T", "S").WithLocation(9, 86) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/TopLevelStatementsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/TopLevelStatementsTests.cs index 6ab50856c1131..a8723ce4cb72b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/TopLevelStatementsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/TopLevelStatementsTests.cs @@ -1113,13 +1113,24 @@ public void LocalDeclarationStatement_18() await System.Threading.Tasks.Task.Yield(); "; + var expectedDiagnostics = new[] + { + // (3,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // ref int d = ref c; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "d").WithArguments("ref and unsafe in async and iterator methods").WithLocation(3, 9) + }; + var comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: DefaultParseOptions); + comp.VerifyDiagnostics(expectedDiagnostics); - comp.VerifyDiagnostics( - // (3,9): error CS8177: Async methods cannot have by-reference locals - // ref int d = ref c; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "d").WithLocation(3, 9) - ); + comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular12); + comp.VerifyDiagnostics(expectedDiagnostics); + + comp = CreateCompilation(text, options: TestOptions.DebugExe, parseOptions: TestOptions.RegularNext); + comp.VerifyEmitDiagnostics(); + + comp = CreateCompilation(text, options: TestOptions.DebugExe); + comp.VerifyEmitDiagnostics(); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 12753c86accd8..ccfc049d18034 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -275,67 +275,2326 @@ unsafe System.Collections.Generic.IEnumerator Goo() } "; - CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (4,56): error CS1629: Unsafe code may not appear in iterators - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "Goo")); + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe System.Collections.Generic.IEnumerator Goo() + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Goo").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 56)); + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void IteratorUnsafe3() + { + var text = @" +class C +{ + System.Collections.Generic.IEnumerator Goo() + { + unsafe { } + yield return 1; + } +} +"; + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe { } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 9)); + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void IteratorUnsafe4() + { + var text = @" +unsafe class C +{ + System.Collections.Generic.IEnumerator Goo() + { + unsafe { } + yield return 1; + } +} +"; + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe { } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 9)); + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [WorkItem(546657, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546657")] + [Fact] + public void IteratorUnsafe5() + { + var text = @" +unsafe class C +{ + System.Collections.Generic.IEnumerator Goo() + { + System.Action a = () => { unsafe { } }; + yield return 1; + } +} +"; + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,35): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // System.Action a = () => { unsafe { } }; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 35)); + + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73280")] + public void Iterator_UnsafeBlock_LangVersion() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M1() + { + unsafe // langversion error in C# 12 + { + int* p = null; // unnecessary langversion error in C# 12 + } + yield break; + } + System.Collections.Generic.IEnumerable M2() + { + int* p = null; // necessary langversion error in C# 12 + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe // langversion error in C# 12 + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9), + // (7,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int* p = null; // unnecessary langversion error in C# 12 + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 13), + // (13,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int* p = null; // necessary langversion error in C# 12 + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("ref and unsafe in async and iterator methods").WithLocation(13, 9)); + + var expectedDiagnostics = new[] + { + // (13,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // int* p = null; // necessary langversion error in C# 12 + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(13, 9) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Iterator_UnsafeBlock_Local() + { + var code = """ + class C + { + public System.Collections.Generic.IEnumerable M() + { + int x = 1; + unsafe + { + int *p = &x; + *p = *p + 1; + } + yield return x; + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - diagnostics inside the unsafe block are unnecessary + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 9), + // (8,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int *p = &x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int *").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 13), + // (8,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int *p = &x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "&x").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 22), + // (9,14): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // *p = *p + 1; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 14), + // (9,19): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // *p = *p + 1; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("ref and unsafe in async and iterator methods").WithLocation(9, 19)); + + var expectedDiagnostics = new[] + { + // (8,23): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int *p = &x; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "x").WithLocation(8, 23) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Iterator_UnsafeBlock_Parameter() + { + var code = """ + class C + { + public System.Collections.Generic.IEnumerable M(int x) + { + unsafe + { + int *p = &x; + *p = *p + 1; + } + yield return x; + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - diagnostics inside the unsafe block are unnecessary + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9), + // (7,13): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int *p = &x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int *").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 13), + // (7,22): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int *p = &x; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "&x").WithArguments("ref and unsafe in async and iterator methods").WithLocation(7, 22), + // (8,14): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // *p = *p + 1; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 14), + // (8,19): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // *p = *p + 1; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "p").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 19)); + + var expectedDiagnostics = new[] + { + // (7,23): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int *p = &x; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "x").WithLocation(7, 23) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Iterator_UnsafeBlock_Field_01() + { + var code = """ + class Program + { + static int _f; + static System.Collections.Generic.IEnumerable F() + { + unsafe + { + fixed (int* p = &_f) { } + } + yield break; + } + } + """; + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void Iterator_UnsafeBlock_Field_02() + { + var code = """ + #pragma warning disable CS0649 // field is never assigned to + unsafe class Program + { + static int* _p; + static System.Collections.Generic.IEnumerable F() + { + unsafe + { + int* p = _p; + p = &p[1]; + } + yield break; + } + } + """; + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void Iterator_UnsafeBlock_Field_03() + { + var code = """ + struct S + { + public int F; + } + class Program + { + static System.Collections.Generic.IEnumerable F() + { + unsafe + { + S s = default; + int* p = &s.F; + } + yield break; + } + } + """; + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (12,23): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int* p = &s.F; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "s.F").WithLocation(12, 23)); + } + + [Fact] + public void Iterator_UnsafeBlock_Field_04() + { + var code = """ + class Program + { + static int _f; + static System.Collections.Generic.IEnumerable F() + { + unsafe + { + int* p = &_f; + (*p)++; + } + yield break; + } + } + """; + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (8,22): error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer + // int* p = &_f; + Diagnostic(ErrorCode.ERR_FixedNeeded, "&_f").WithLocation(8, 22)); + } + + [Fact] + public void Iterator_UnsafeBlock_SizeOf() + { + var code = """ + foreach (var x in new C().M()) System.Console.Write(x); + + class C + { + public System.Collections.Generic.IEnumerable M() + { + int x; + unsafe + { + x = sizeof(nint); + } + yield return x; + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - diagnostics inside the unsafe block are unnecessary + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics( + // (8,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(8, 9), + // (10,17): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // x = sizeof(nint); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nint)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(10, 17)); + + var expectedOutput = IntPtr.Size.ToString(); + CompileAndVerify(code, expectedOutput: expectedOutput, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CompileAndVerify(code, expectedOutput: expectedOutput, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + } + + [Fact] + public void Iterator_UnsafeBlock_YieldBreak() + { + var code = """ + class C + { + public System.Collections.Generic.IEnumerable M() + { + unsafe + { + yield break; + } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void Iterator_UnsafeBlock_YieldReturn() + { + var code = """ + class C + { + public System.Collections.Generic.IEnumerable M() + { + unsafe + { + yield return 1; + } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe + Diagnostic(ErrorCode.ERR_FeatureInPreview, "unsafe").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9)); + + var expectedDiagnostics = new[] + { + // (7,13): error CS9238: Cannot use 'yield return' in an 'unsafe' block + // yield return 1; + Diagnostic(ErrorCode.ERR_BadYieldInUnsafe, "yield").WithLocation(7, 13) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Iterator_UnsafeBlock_Async_01() + { + var code = """ + await foreach (var x in new C().M()) System.Console.Write(x); + + class C + { + public async System.Collections.Generic.IAsyncEnumerable M() + { + int x = 1; + await System.Threading.Tasks.Task.Yield(); + unsafe + { + int *p = &x; + *p = *p + 1; + } + yield return x; + } + } + """ + AsyncStreamsTypes; + + var comp = CreateCompilationWithTasksExtensions(code, options: TestOptions.UnsafeReleaseExe); + CompileAndVerify(comp, expectedOutput: "1", verify: Verification.Fails).VerifyDiagnostics( + // (11,23): warning CS9123: The '&' operator should not be used on parameters or local variables in async methods. + // int *p = &x; + Diagnostic(ErrorCode.WRN_AddressOfInAsync, "x").WithLocation(11, 23)); + } + + // Should behave equivalently to AwaitBetweenUnsafeBlocks. + [Fact] + public void Iterator_UnsafeBlock_Async_02() + { + var code = """ + class C + { + public System.Collections.Generic.IEnumerable M() + { + int x = 1; + unsafe + { + int *p = &x; + *p = *p + 1; + } + yield return x; + unsafe + { + int *p = &x; + *p = *p + 1; + } + yield return x; + unsafe + { + int *p = &x; + if (*p == 3) yield break; + } + yield return x; + } + } + """; + + var expectedDiagnostics = new[] + { + // (8,23): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int *p = &x; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "x").WithLocation(8, 23), + // (14,23): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int *p = &x; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "x").WithLocation(14, 23), + // (20,23): error CS9239: The '&' operator cannot be used on parameters or local variables in iterator methods. + // int *p = &x; + Diagnostic(ErrorCode.ERR_AddressOfInIterator, "x").WithLocation(20, 23) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + // Should behave equivalently to Iterator_UnsafeBlock_Async_02. + [Fact] + public void AwaitBetweenUnsafeBlocks() + { + var code = """ + using System; + using System.Threading.Tasks; + + await new C().M(); + + class C + { + async Task Report(int x) + { + Console.Write(x); + await Task.Yield(); + } + public async Task M() + { + int x = 1; + unsafe + { + int *p = &x; + *p = *p + 1; + } + await Report(x); + unsafe + { + int *p = &x; + *p = *p + 1; + } + await Report(x); + unsafe + { + int *p = &x; + if (*p == 3) return; + } + await Report(x); + } + } + """; + var expectedDiagnostics = new[] + { + // (18,23): warning CS9123: The '&' operator should not be used on parameters or local variables in async methods. + // int *p = &x; + Diagnostic(ErrorCode.WRN_AddressOfInAsync, "x").WithLocation(18, 23), + // (24,23): warning CS9123: The '&' operator should not be used on parameters or local variables in async methods. + // int *p = &x; + Diagnostic(ErrorCode.WRN_AddressOfInAsync, "x").WithLocation(24, 23), + // (30,23): warning CS9123: The '&' operator should not be used on parameters or local variables in async methods. + // int *p = &x; + Diagnostic(ErrorCode.WRN_AddressOfInAsync, "x").WithLocation(30, 23) + }; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void Iterator_LocalFunction_Nested() + { + var code = """ + class Program + { + static void F() + { + unsafe + { + static System.Collections.Generic.IEnumerable G(int x) + { + unsafe + { + x = sizeof(nint); + } + yield return x; + + unsafe + { + G2(new int*[0]); + static System.Collections.Generic.IEnumerable G2(int*[] x) + { + int y; + unsafe + { + y = *x[0]; + } + yield return y; + } + } + } + G(0); + } + } + } + """; + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void UnsafeContext_LambdaInIterator_Async() + { + var code = """ + using System.Collections.Generic; + using System.Threading.Tasks; + unsafe class C + { + IEnumerable M() + { + yield return 1; + var lam = async () => await Task.Yield(); + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - these should ideally be langversion errors + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (8,31): error CS4004: Cannot await in an unsafe context + // var lam = async () => await Task.Yield(); + Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Yield()").WithLocation(8, 31)); + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_Async() + { + var code = """ + using System.Collections.Generic; + using System.Threading.Tasks; + unsafe class C + { + IEnumerable M() + { + yield return 1; + local(); + async void local() { await Task.Yield(); } + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - these should ideally be langversion errors + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (9,30): error CS4004: Cannot await in an unsafe context + // async void local() { await Task.Yield(); } + Diagnostic(ErrorCode.ERR_AwaitInUnsafeContext, "await Task.Yield()").WithLocation(9, 30)); + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void UnsafeContext_LambdaInIterator_Unsafe() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + yield return 1; + var lam = () => sizeof(nint); + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (6,25): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // var lam = () => sizeof(nint); + Diagnostic(ErrorCode.ERR_FeatureInPreview, "sizeof(nint)").WithArguments("ref and unsafe in async and iterator methods").WithLocation(6, 25)); + + var expectedDiagnostics = new[] + { + // (6,25): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // var lam = () => sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 25) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_BreakingChange() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + yield return 1; + local(); + void local() { int* p = null; } + } + } + """; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + var expectedDiagnostics = new[] + { + // (7,24): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void local() { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(7, 24) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_BreakingChangeWorkaround() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + yield return 1; + local(); + unsafe void local() { int* p = null; } + } + } + """; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_BreakingChange_Property() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable P + { + get + { + yield return 1; + local(); + void local() { int* p = null; } + } + } + } + """; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + var expectedDiagnostics = new[] + { + // (9,28): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void local() { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(9, 28) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_BreakingChange_Operator() + { + var code = """ + unsafe class C + { + public static System.Collections.Generic.IEnumerable operator+(C c1, C c2) + { + yield return 1; + local(); + void local() { int* p = null; } + } + } + """; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + var expectedDiagnostics = new[] + { + // (7,24): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void local() { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(7, 24) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_BreakingChange_Nested_01() + { + var code = """ + unsafe class C + { + void M() + { + local1(); + System.Collections.Generic.IEnumerable local1() + { + yield return 1; + local2(); + void local2() { int* p = null; } + } + } + } + """; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + var expectedDiagnostics = new[] + { + // (10,29): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void local2() { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(10, 29) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunctionInIterator_BreakingChange_Nested_02() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + yield return 1; + local1(); + void local1() + { + local2(); + void local2() { int* p = null; } + } + } + } + """; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyEmitDiagnostics(); + + var expectedDiagnostics = new[] + { + // (10,29): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void local2() { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(10, 29) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/73280")] + public void UnsafeContext_LangVersion() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + int* p = null; + yield break; + } + } + """; + + // https://github.com/dotnet/roslyn/issues/73280 - should not be a langversion error since this remains an error in C# 13 + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // int* p = null; + Diagnostic(ErrorCode.ERR_FeatureInPreview, "int*").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9)); + + var expectedDiagnostics = new[] + { + // (5,9): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // int* p = null; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(5, 9) + }; + + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Method_Signature_Unsafe(bool unsafeClass, bool unsafeMethod) + { + if (!unsafeClass && !unsafeMethod) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeMethod ? "unsafe" : "")}} void M(int* p) { } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Method_Signature_Safe() + { + var code = """ + class C + { + void M(int* p) { } + } + """; + + var expectedDiagnostics = new[] + { + // (3,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void M(int* p) + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 12) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Method_Body_Unsafe(bool unsafeClass, bool unsafeMethod) + { + if (!unsafeClass && !unsafeMethod) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeMethod ? "unsafe" : "")}} int M() + { + return sizeof(nint); + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Method_Body_Safe() + { + var code = """ + class C + { + int M() + { + return sizeof(nint); + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,16): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 16) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Method_Iterator_Signature_UnsafeClass() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M(int*[] p) + { + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Method_Iterator_Signature_UnsafeMethod(bool unsafeClass) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + unsafe System.Collections.Generic.IEnumerable M(int*[] p) + { + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (3,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe System.Collections.Generic.IEnumerable M(int*[] p) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("ref and unsafe in async and iterator methods").WithLocation(3, 56)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Method_Iterator_Signature_Safe() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable M(int*[] p) + { + yield break; + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,51): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // System.Collections.Generic.IEnumerable M(int*[] p) + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 51) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Method_Iterator_Body_CSharp12_Safe() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable M() + { + yield return sizeof(nint); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 22)); + } + + [Fact] + public void UnsafeContext_Method_Iterator_Body_CSharp12_Safe_NestedBlock() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable M() + { + { + yield return sizeof(nint); + } + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (6,26): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 26)); + } + + [Fact] + public void UnsafeContext_Method_Iterator_Body_CSharp12_Unsafe() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + yield return local(); + int local() => sizeof(nint); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Method_Iterator_Body_CSharp12_Unsafe_NestedBlock() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable M() + { + { + yield return local(); + } + int local() => sizeof(nint); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Method_Iterator_Body_CSharp13(bool unsafeClass, bool unsafeMethod) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeMethod ? "unsafe" : "")}} System.Collections.Generic.IEnumerable M() + { + yield return sizeof(nint); + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 22) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Method_Iterator_Body_CSharp13_NestedBlock(bool unsafeClass, bool unsafeMethod) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeMethod ? "unsafe" : "")}} System.Collections.Generic.IEnumerable M() + { + { + yield return sizeof(nint); + } + } + } + """; + + var expectedDiagnostics = new[] + { + // (6,26): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 26) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Operator_Signature_Unsafe(bool unsafeClass, bool unsafeOperator) + { + if (!unsafeClass && !unsafeOperator) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeOperator ? "unsafe" : "")}} public static C operator+(C c, int* p) + { + return c; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Operator_Signature_Safe() + { + var code = """ + class C + { + public static C operator+(C c, int* p) + { + return c; + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,36): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // public static C operator+(C c, int* p) + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 36) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Operator_Body_Unsafe(bool unsafeClass, bool unsafeOperator) + { + if (!unsafeClass && !unsafeOperator) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeOperator ? "unsafe" : "")}} public static int operator+(C c1, C c2) + { + return sizeof(nint); + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Operator_Body_Safe() + { + var code = """ + class C + { + public static int operator+(C c1, C c2) + { + return sizeof(nint); + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,16): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 16) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Operator_Iterator_Signature_UnsafeClass() + { + var code = """ + unsafe class C + { + public static System.Collections.Generic.IEnumerable operator+(C c, int*[] p) + { + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Operator_Iterator_Signature_UnsafeOperator(bool unsafeClass) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + public static unsafe System.Collections.Generic.IEnumerable operator+(C c, int*[] p) + { + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (3,78): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // public static unsafe System.Collections.Generic.IEnumerable operator+(C c, int*[] p) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "+").WithArguments("ref and unsafe in async and iterator methods").WithLocation(3, 78)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Operator_Iterator_Signature_Safe() + { + var code = """ + class C + { + public static System.Collections.Generic.IEnumerable operator+(C c, int*[] p) + { + yield break; + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,78): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // public static System.Collections.Generic.IEnumerable operator+(C c, int*[] p) + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 78) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Operator_Iterator_Body_CSharp12_Safe() + { + var code = """ + class C + { + public static System.Collections.Generic.IEnumerable operator+(C c1, C c2) + { + yield return sizeof(nint); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 22)); + } + + [Fact] + public void UnsafeContext_Operator_Iterator_Body_CSharp12_Unsafe() + { + var code = """ + unsafe class C + { + public static System.Collections.Generic.IEnumerable operator+(C c1, C c2) + { + yield return local(); + int local() => sizeof(nint); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Operator_Iterator_Body_CSharp13(bool unsafeClass, bool unsafeIndexer) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeIndexer ? "unsafe" : "")}} public static System.Collections.Generic.IEnumerable operator+(C c1, C c2) + { + yield return sizeof(nint); + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 22) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Indexer_Signature_Unsafe(bool unsafeClass, bool unsafeIndexer) + { + if (!unsafeClass && !unsafeIndexer) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeIndexer ? "unsafe" : "")}} int this[int* p] + { + get { return 0; } + set { } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Indexer_Signature_Safe() + { + var code = """ + class C + { + int this[int* p] + { + get { return 0; } + set { } + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,14): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // int this[int* p] + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 14) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Indexer_Body_Unsafe(bool unsafeClass, bool unsafeIndexer) + { + if (!unsafeClass && !unsafeIndexer) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeIndexer ? "unsafe" : "")}} int this[int x] + { + get { return sizeof(nint); } + set { int* p = null; } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Indexer_Body_Safe() + { + var code = """ + class C + { + int this[int x] + { + get { return sizeof(nint); } + set { int* p = null; } + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 22), + // (6,15): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // set { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 15) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Indexer_Iterator_Signature_UnsafeClass() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable this[int*[] p] + { + get { yield break; } + set { } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Indexer_Iterator_Signature_UnsafeIndexer(bool unsafeClass) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + unsafe System.Collections.Generic.IEnumerable this[int*[] p] + { + get { yield break; } + set { } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // get { yield break; } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Indexer_Iterator_Signature_Safe() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable this[int*[] p] + { + get { yield break; } + set { } + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,54): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // System.Collections.Generic.IEnumerable this[int*[] p] + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 54) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Indexer_Iterator_Body_CSharp12_Safe() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable this[int x] + { + get { yield return sizeof(nint); } + set { int* p = null; } + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,28): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { yield return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 28), + // (6,15): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // set { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 15)); + } + + [Fact] + public void UnsafeContext_Indexer_Iterator_Body_CSharp12_Unsafe() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable this[int x] + { + get + { + yield return local(); + int local() => sizeof(nint); + } + set { int* p = null; } + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Indexer_Iterator_Body_CSharp13_UnsafeSetter(bool unsafeClass, bool unsafeIndexer) + { + if (!unsafeClass && !unsafeIndexer) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeIndexer ? "unsafe" : "")}} System.Collections.Generic.IEnumerable this[int x] + { + get { yield return sizeof(nint); } + set { int* p = null; } + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,28): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { yield return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 28) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Indexer_Iterator_Body_CSharp13_SafeSetter() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable this[int x] + { + get { yield return sizeof(nint); } + set { int* p = null; } + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,28): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { yield return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 28), + // (6,15): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // set { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 15) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Property_Signature_Unsafe(bool unsafeClass, bool unsafeProperty) + { + if (!unsafeClass && !unsafeProperty) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeProperty ? "unsafe" : "")}} int* P + { + get { throw null; } + set { } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Property_Signature_Safe() + { + var code = """ + class C + { + int* P + { + get { throw null; } + set { } + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,5): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // int* P + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 5) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Property_Body_Unsafe(bool unsafeClass, bool unsafeProperty) + { + if (!unsafeClass && !unsafeProperty) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeProperty ? "unsafe" : "")}} int P + { + get { return sizeof(nint); } + set { int* p = null; } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Property_Body_Safe() + { + var code = """ + class C + { + int P + { + get { return sizeof(nint); } + set { int* p = null; } + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 22), + // (6,15): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // set { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 15) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Property_Iterator_Signature_UnsafeClass() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable P + { + get { yield break; } + set { } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Property_Iterator_Signature_UnsafeProperty(bool unsafeClass) + { + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + unsafe System.Collections.Generic.IEnumerable P + { + get { yield break; } + set { } + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,9): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // get { yield break; } + Diagnostic(ErrorCode.ERR_FeatureInPreview, "get").WithArguments("ref and unsafe in async and iterator methods").WithLocation(5, 9)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Property_Iterator_Signature_Safe() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable P + { + get { yield break; } + set { } + } + } + """; + + var expectedDiagnostics = new[] + { + // (3,44): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // System.Collections.Generic.IEnumerable P + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(3, 44) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Property_Iterator_Body_CSharp12_Safe() + { + var code = """ + class C + { + System.Collections.Generic.IEnumerable P + { + get { yield return sizeof(nint); } + set { int* p = null; } + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( + // (5,28): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { yield return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 28), + // (6,15): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // set { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 15)); + } + + [Fact] + public void UnsafeContext_Property_Iterator_Body_CSharp12_Unsafe() + { + var code = """ + unsafe class C + { + System.Collections.Generic.IEnumerable P + { + get + { + yield return local(); + int local() => sizeof(nint); + } + set { int* p = null; } + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_Property_Iterator_Body_CSharp13_UnsafeSetter(bool unsafeClass, bool unsafeProperty) + { + if (!unsafeClass && !unsafeProperty) + { + return; + } + + var code = $$""" + {{(unsafeClass ? "unsafe" : "")}} class C + { + {{(unsafeProperty ? "unsafe" : "")}} System.Collections.Generic.IEnumerable P + { + get { yield return sizeof(nint); } + set { int* p = null; } + } + } + """; + + var expectedDiagnostics = new[] + { + // (5,28): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { yield return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 28) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); } [Fact] - public void IteratorUnsafe3() + public void UnsafeContext_Property_Iterator_Body_CSharp13_SafeSetter() { - var text = @" -class C -{ - System.Collections.Generic.IEnumerator Goo() - { - unsafe { } - yield return 1; - } -} -"; + var code = """ + class C + { + System.Collections.Generic.IEnumerable P + { + get { yield return sizeof(nint); } + set { int* p = null; } + } + } + """; - CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (6,9): error CS1629: Unsafe code may not appear in iterators - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "unsafe")); + var expectedDiagnostics = new[] + { + // (5,28): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // get { yield return sizeof(nint); } + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(5, 28), + // (6,15): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // set { int* p = null; } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(6, 15) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_LocalFunction_Signature_Unsafe(bool unsafeBlock, bool unsafeFunction) + { + if (!unsafeBlock && !unsafeFunction) + { + return; + } + + var code = $$""" + #pragma warning disable CS8321 // The local function 'M' is declared but never used + {{(unsafeBlock ? "unsafe" : "")}} + { + {{(unsafeFunction ? "unsafe" : "")}} void M(int* p) { } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); } [Fact] - public void IteratorUnsafe4() + public void UnsafeContext_LocalFunction_Signature_Safe() { - var text = @" -unsafe class C -{ - System.Collections.Generic.IEnumerator Goo() - { - unsafe { } - yield return 1; - } -} -"; + var code = """ + #pragma warning disable CS8321 // The local function 'M' is declared but never used + void M(int* p) { } + """; - CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (6,9): error CS1629: Unsafe code may not appear in iterators - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "unsafe")); + var expectedDiagnostics = new[] + { + // (2,8): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // void M(int* p) { } + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 8) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Theory, CombinatorialData] + public void UnsafeContext_LocalFunction_Body_Unsafe(bool unsafeBlock, bool unsafeFunction) + { + if (!unsafeBlock && !unsafeFunction) + { + return; + } + + var code = $$""" + #pragma warning disable CS8321 // The local function 'M' is declared but never used + {{(unsafeBlock ? "unsafe" : "")}} + { + {{(unsafeFunction ? "unsafe" : "")}} int M() + { + return sizeof(nint); + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); } - [WorkItem(546657, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546657")] [Fact] - public void IteratorUnsafe5() + public void UnsafeContext_LocalFunction_Body_Safe() { - var text = @" -unsafe class C -{ - System.Collections.Generic.IEnumerator Goo() - { - System.Action a = () => { unsafe { } }; - yield return 1; - } -} -"; + var code = """ + #pragma warning disable CS8321 // The local function 'M' is declared but never used + int M() + { + return sizeof(nint); + } + """; - CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (6,9): error CS1629: Unsafe code may not appear in iterators - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "unsafe")); + var expectedDiagnostics = new[] + { + // (4,12): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(4, 12) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunction_Iterator_Signature_UnsafeBlock() + { + var code = """ + #pragma warning disable CS8321 // The local function 'M' is declared but never used + unsafe + { + System.Collections.Generic.IEnumerable M(int*[] p) + { + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_LocalFunction_Iterator_Signature_UnsafeFunction(bool unsafeBlock) + { + var code = $$""" + #pragma warning disable CS8321 // The local function 'M' is declared but never used + {{(unsafeBlock ? "unsafe" : "")}} + { + unsafe System.Collections.Generic.IEnumerable M(int*[] p) + { + yield break; + } + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics( + // (4,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe System.Collections.Generic.IEnumerable M(int*[] p) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "M").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 56)); + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_LocalFunction_Iterator_Signature_Safe() + { + var code = """ + #pragma warning disable CS8321 // The local function 'M' is declared but never used + System.Collections.Generic.IEnumerable M(int*[] p) + { + yield break; + } + """; + + var expectedDiagnostics = new[] + { + // (2,47): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // System.Collections.Generic.IEnumerable M(int*[] p) + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(2, 47) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_LocalFunction_Iterator_Body_CSharp12_Safe() + { + var code = """ + #pragma warning disable CS8321 // The local function 'M' is declared but never used + System.Collections.Generic.IEnumerable M() + { + yield return sizeof(nint); + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics( + // (4,18): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(4, 18)); + } + + [Fact] + public void UnsafeContext_LocalFunction_Iterator_Body_CSharp12_Unsafe() + { + var code = """ + #pragma warning disable CS8321 // The local function 'M' is declared but never used + unsafe + { + System.Collections.Generic.IEnumerable M() + { + yield return local(); + int local() => sizeof(nint); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + } + + [Theory, CombinatorialData] + public void UnsafeContext_LocalFunction_Iterator_Body_CSharp13(bool unsafeBlock, bool unsafeFunction) + { + var code = $$""" + #pragma warning disable CS8321 // The local function 'M' is declared but never used + {{(unsafeBlock ? "unsafe" : "")}} + { + {{(unsafeFunction ? "unsafe" : "")}} System.Collections.Generic.IEnumerable M() + { + yield return sizeof(nint); + } + } + """; + + var expectedDiagnostics = new[] + { + // (6,22): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(6, 22) + }; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Lambda_Signature_Unsafe() + { + var code = """ + unsafe + { + var lam = (int* p) => { }; + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Lambda_Signature_Safe() + { + var code = """ + var lam = (int* p) => { }; + """; + + var expectedDiagnostics = new[] + { + // (1,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var lam = (int* p) => { }; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 12), + // (1,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var lam = (int* p) => { }; + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(1, 17) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Lambda_Body_Unsafe() + { + var code = """ + unsafe + { + var lam = () => + { + return sizeof(nint); + }; + } + """; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(); + } + + [Fact] + public void UnsafeContext_Lambda_Body_Safe() + { + var code = """ + var lam = () => + { + return sizeof(nint); + }; + """; + + var expectedDiagnostics = new[] + { + // (3,12): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(3, 12) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Lambda_Iterator_Signature_Unsafe() + { + var code = """ + unsafe + { + var lam = (int*[] p) => + { + yield break; + }; + } + """; + + var expectedDiagnostics = new[] + { + // (5,9): error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression + // yield break; + Diagnostic(ErrorCode.ERR_YieldInAnonMeth, "yield").WithLocation(5, 9) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Lambda_Iterator_Signature_Safe() + { + var code = """ + var lam = (int*[] p) => + { + yield break; + }; + """; + + var expectedDiagnostics = new[] + { + // (1,12): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var lam = (int*[] p) => + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "int*").WithLocation(1, 12), + // (1,19): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context + // var lam = (int*[] p) => + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "p").WithLocation(1, 19), + // (3,5): error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression + // yield break; + Diagnostic(ErrorCode.ERR_YieldInAnonMeth, "yield").WithLocation(3, 5) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Lambda_Iterator_Body_Unsafe() + { + var code = """ + unsafe + { + var lam = () => + { + yield return sizeof(nint); + }; + } + """; + + var expectedDiagnostics = new[] + { + // (5,9): error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_YieldInAnonMeth, "yield").WithLocation(5, 9) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + + expectedDiagnostics = [ + // (5,9): error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_YieldInAnonMeth, "yield").WithLocation(5, 9), + // (5,9): error CS9238: Cannot use 'yield return' in an 'unsafe' block + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_BadYieldInUnsafe, "yield").WithLocation(5, 9) + ]; + + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeContext_Lambda_Iterator_Body_Safe() + { + var code = """ + var lam = () => + { + yield return sizeof(nint); + }; + """; + + var expectedDiagnostics = new[] + { + // (3,5): error CS1621: The yield statement cannot be used inside an anonymous method or lambda expression + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_YieldInAnonMeth, "yield").WithLocation(3, 5), + // (3,18): error CS0233: 'nint' does not have a predefined size, therefore sizeof can only be used in an unsafe context + // yield return sizeof(nint); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(nint)").WithArguments("nint").WithLocation(3, 18) + }; + + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(code, options: TestOptions.UnsafeReleaseExe).VerifyDiagnostics(expectedDiagnostics); + } + + [Fact] + public void UnsafeBlock_InAsyncMethod() + { + var code = """ + using System.Threading.Tasks; + class C + { + async Task M(int x) + { + unsafe { x = sizeof(nint); } + await Task.Yield(); + } + } + """; + CreateCompilation(code, parseOptions: TestOptions.Regular12, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + CreateCompilation(code, parseOptions: TestOptions.RegularNext, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + CreateCompilation(code, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); } [Fact] @@ -936,18 +3195,41 @@ public void UnsafeIteratorSignatures() Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p")); var withUnsafeOnMembers = string.Format(template, "", "unsafe"); - CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (4,64): error CS1637: Iterators cannot have pointer type parameters - Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p"), - // (4,56): error CS1629: Unsafe code may not appear in iterators - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "Iterator")); //this is for putting "unsafe" on an iterator, not for the parameter type + CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,70): error CS1637: Iterators cannot have pointer type parameters + // unsafe System.Collections.Generic.IEnumerable Iterator(int* p) + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p").WithLocation(4, 70), + // (4,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe System.Collections.Generic.IEnumerable Iterator(int* p) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Iterator").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 56)); //this is for putting "unsafe" on an iterator, not for the parameter type + + var expectedDiagnostics = new[] + { + // (4,70): error CS1637: Iterators cannot have pointer type parameters + // unsafe System.Collections.Generic.IEnumerable Iterator(int* p) + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p").WithLocation(4, 70) + }; + + CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); var withUnsafeOnTypeAndMembers = string.Format(template, "unsafe", "unsafe"); - CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (4,64): error CS1637: Iterators cannot have pointer type parameters - Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p"), - // (4,56): error CS1629: Unsafe code may not appear in iterators - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "Iterator")); //this is for putting "unsafe" on an iterator, not for the parameter type + CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,70): error CS1637: Iterators cannot have pointer type parameters + // unsafe System.Collections.Generic.IEnumerable Iterator(int* p) + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p").WithLocation(4, 70), + // (4,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. + // unsafe System.Collections.Generic.IEnumerable Iterator(int* p) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Iterator").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 56)); //this is for putting "unsafe" on an iterator, not for the parameter type + + expectedDiagnostics = [ + // (4,70): error CS1637: Iterators cannot have pointer type parameters + // unsafe System.Collections.Generic.IEnumerable Iterator(int* p) + Diagnostic(ErrorCode.ERR_UnsafeIteratorArgType, "p").WithLocation(4, 70) + ]; + + CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -974,18 +3256,24 @@ public void UnsafeIteratorSignatures_PointerArray() CreateCompilation(withUnsafeOnType, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); var withUnsafeOnMembers = string.Format(template, "", "unsafe"); - CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (4,56): error CS1629: Unsafe code may not appear in iterators + CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // unsafe System.Collections.Generic.IEnumerable Iterator(int*[] p) - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "Iterator").WithLocation(4, 56) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Iterator").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 56) ); + CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(withUnsafeOnMembers, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); + var withUnsafeOnTypeAndMembers = string.Format(template, "unsafe", "unsafe"); - CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics( - // (4,56): error CS1629: Unsafe code may not appear in iterators + CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.Regular12).VerifyDiagnostics( + // (4,56): error CS8652: The feature 'ref and unsafe in async and iterator methods' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. // unsafe System.Collections.Generic.IEnumerable Iterator(int*[] p) - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "Iterator").WithLocation(4, 56) + Diagnostic(ErrorCode.ERR_FeatureInPreview, "Iterator").WithArguments("ref and unsafe in async and iterator methods").WithLocation(4, 56) ); + + CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularNext).VerifyEmitDiagnostics(); + CreateCompilation(withUnsafeOnTypeAndMembers, options: TestOptions.UnsafeReleaseDll).VerifyEmitDiagnostics(); } [Fact] @@ -8156,10 +10444,17 @@ System.Collections.Generic.IEnumerable M() } } "; - CreateCompilation(text).VerifyDiagnostics( - // (6,22): error CS1629: Unsafe code may not appear in iterators + + var expectedDiagnostics = new[] + { + // (6,22): error CS0233: 'S' does not have a predefined size, therefore sizeof can only be used in an unsafe context // yield return sizeof(S); - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "sizeof(S)")); + Diagnostic(ErrorCode.ERR_SizeofUnsafe, "sizeof(S)").WithArguments("S").WithLocation(6, 22) + }; + + CreateCompilation(text, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(text, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(text).VerifyDiagnostics(expectedDiagnostics); } [Fact] @@ -8522,10 +10817,17 @@ System.Collections.Generic.IEnumerable M() } } "; - CreateCompilation(text).VerifyDiagnostics( - // (6,17): error CS1629: Unsafe code may not appear in iterators + + var expectedDiagnostics = new[] + { + // (6,17): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context // var p = stackalloc int[1]; - Diagnostic(ErrorCode.ERR_IllegalInnerUnsafe, "stackalloc int[1]")); + Diagnostic(ErrorCode.ERR_UnsafeNeeded, "stackalloc int[1]").WithLocation(6, 17) + }; + + CreateCompilation(text, parseOptions: TestOptions.Regular12).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(text, parseOptions: TestOptions.RegularNext).VerifyDiagnostics(expectedDiagnostics); + CreateCompilation(text).VerifyDiagnostics(expectedDiagnostics); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs index 3b9371a1c3769..610897b83d561 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs @@ -1127,12 +1127,67 @@ static async Task Main() } } }"; - var compilation = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }).VerifyDiagnostics( - // (16,22): error CS4012: Parameters or locals of type 'S1' cannot be declared in async methods or async lambda expressions. + var compilation = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, options: TestOptions.ReleaseExe); + CompileAndVerify(compilation, expectedOutput: "Dispose async").VerifyDiagnostics(); + } + + [Fact] + public void UsingPatternAsyncTest_02() + { + var source = """ + using System.Threading.Tasks; + ref struct S1 + { + public ValueTask DisposeAsync() + { + System.Console.WriteLine("Dispose async"); + return new ValueTask(Task.CompletedTask); + } + } + class C2 + { + static async Task Main() + { + await using (S1 c = new S1()) + { + await Task.Yield(); + } + } + } + """; + var compilation = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }); + compilation.VerifyEmitDiagnostics( + // 0.cs(14,25): error CS4007: Instance of type 'S1' cannot be preserved across 'await' or 'yield' boundary. // await using (S1 c = new S1()) - Diagnostic(ErrorCode.ERR_BadSpecialByRefLocal, "S1").WithArguments("S1").WithLocation(16, 22) - ); + Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, "c = new S1()").WithArguments("S1").WithLocation(14, 25)); + } + [Fact] + public void UsingPatternAsyncTest_03() + { + var source = """ + using System.Threading.Tasks; + ref struct S1 + { + public S1(int x) { } + public ValueTask DisposeAsync() + { + System.Console.WriteLine("Dispose async"); + return new ValueTask(Task.CompletedTask); + } + } + class C2 + { + static async Task Main() + { + await using (S1 c = new S1(await Task.FromResult(1))) + { + } + } + } + """; + var compilation = CreateCompilationWithTasksExtensions(new[] { source, IAsyncDisposableDefinition }, options: TestOptions.ReleaseExe); + CompileAndVerify(compilation, expectedOutput: "Dispose async").VerifyDiagnostics(); } [Fact] diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/Utf8StringsLiteralsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/Utf8StringsLiteralsTests.cs index 03979b7732a2d..37475d8c100c6 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/Utf8StringsLiteralsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/Utf8StringsLiteralsTests.cs @@ -2432,9 +2432,9 @@ static void PrintType(T value) var comp = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp, options: TestOptions.DebugExe); comp.VerifyDiagnostics( - // (6,9): error CS0306: The type 'ReadOnlySpan' may not be used as a type argument - // PrintType(""" - Diagnostic(ErrorCode.ERR_BadTypeArgument, "PrintType").WithArguments("System.ReadOnlySpan").WithLocation(6, 9) + // (6,9): error CS9244: The type 'ReadOnlySpan' may not be a ref struct or a type parameter allowing ref structs in order to use it as parameter 'T' in the generic type or method 'C.PrintType(T)' + // PrintType(@"hello"u8); + Diagnostic(ErrorCode.ERR_NotRefStructConstraintNotSatisfied, "PrintType").WithArguments("C.PrintType(T)", "T", "System.ReadOnlySpan").WithLocation(6, 9) ); } diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs index 2e233219a3fc0..203805fa93bd7 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs @@ -85,7 +85,7 @@ public void M(dynamic d) Assert.Equal("C", semanticInfo.Type.Name); Assert.Equal("C..ctor(out dynamic x, dynamic y)", semanticInfo.Symbol.ToTestDisplayString()); - Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); + Assert.Equal(CandidateReason.LateBound, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.Equal(1, semanticInfo.MethodGroup.Length); Assert.False(semanticInfo.IsCompileTimeConstant); @@ -227,9 +227,9 @@ public void M(dynamic d) Assert.True(semanticInfo.Type.IsDynamic()); Assert.Equal("C C.Create(System.Int32 arg)", semanticInfo.Symbol.ToTestDisplayString()); - Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); + Assert.Equal(CandidateReason.LateBound, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); - Assert.Equal(0, semanticInfo.MethodGroup.Length); + Assert.Equal(1, semanticInfo.MethodGroup.Length); Assert.False(semanticInfo.IsCompileTimeConstant); string sourceCode2 = @" @@ -552,7 +552,7 @@ public int this[int a] Assert.True(semanticInfo.ConvertedType.IsDynamic()); Assert.Equal(ConversionKind.Identity, semanticInfo.ImplicitConversion.Kind); - Assert.Equal(CandidateReason.None, semanticInfo.CandidateReason); + Assert.Equal(CandidateReason.LateBound, semanticInfo.CandidateReason); Assert.Equal(0, semanticInfo.CandidateSymbols.Length); Assert.Equal("System.Int32 C.this[System.Int32 a] { get; set; }", semanticInfo.Symbol.ToTestDisplayString()); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs index bf23e1d535416..f40628bbb009d 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/DefaultInterfaceImplementationTests.cs @@ -49419,7 +49419,7 @@ static explicit operator byte(I1 x) public void RuntimeFeature_01() { var compilation1 = CreateCompilation("", options: TestOptions.DebugDll, - references: new[] { Net461.mscorlib }, + references: new[] { Net461.References.mscorlib }, targetFramework: TargetFramework.Empty); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); @@ -49430,7 +49430,7 @@ public void RuntimeFeature_01() public void RuntimeFeature_02() { var compilation1 = CreateCompilation("", options: TestOptions.DebugDll, - references: new[] { Net70.SystemRuntime }, + references: new[] { Net70.References.SystemRuntime }, targetFramework: TargetFramework.Empty); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); @@ -49730,7 +49730,7 @@ public static class RuntimeFeature "; var compilation1 = CreateCompilation(source, options: TestOptions.DebugDll, - references: new[] { Net461.mscorlib }, + references: new[] { Net461.References.mscorlib }, targetFramework: TargetFramework.Empty); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs index 132f3bcfa02b7..42b3d2083af4e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/MissingSpecialMember.cs @@ -564,6 +564,7 @@ public void AllSpecialTypeMembers() || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__UnmanagedSignatureCallingConvention || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__ByRefFields + || special == SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics || special == SpecialMember.System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor || special == SpecialMember.System_Runtime_CompilerServices_InlineArrayAttribute__ctor || special == SpecialMember.System_ReadOnlySpan_T__ctor_Reference @@ -1071,6 +1072,8 @@ public void AllWellKnownTypeMembers() case WellKnownMember.System_Span_T__CopyTo_Span_T: case WellKnownMember.System_ReadOnlySpan_T__CopyTo_Span_T: case WellKnownMember.System_Collections_Immutable_ImmutableArray_T__AsSpan: + case WellKnownMember.System_Span_T__ctor_ref_T: + case WellKnownMember.System_ReadOnlySpan_T__ctor_ref_readonly_T: // Not always available. continue; } diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs index 587107287652c..9f5490d05adac 100644 --- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs +++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs @@ -471,6 +471,10 @@ public void WarningLevel_2() // These are the warnings introduced with the warning "wave" shipped with dotnet 8 and C# 12. Assert.Equal(8, ErrorFacts.GetWarningLevel(errorCode)); break; + case ErrorCode.WRN_BadYieldInLock: + // These are the warnings introduced with the warning "wave" shipped with dotnet 9 and C# 13. + Assert.Equal(9, ErrorFacts.GetWarningLevel(errorCode)); + break; default: // If a new warning is added, this test will fail // and whoever is adding the new warning will have to update it with the expected error level. @@ -2979,6 +2983,7 @@ public void TestIsBuildOnlyDiagnostic() case ErrorCode.ERR_InterceptableMethodMustBeOrdinary: case ErrorCode.ERR_PossibleAsyncIteratorWithoutYield: case ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait: + case ErrorCode.ERR_RefLocalAcrossAwait: Assert.True(isBuildOnly, $"Check failed for ErrorCode.{errorCode}"); break; diff --git a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs index fe0d6a3f15fbf..6edb119c630fa 100644 --- a/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs +++ b/src/Compilers/CSharp/Test/Syntax/Generated/Syntax.Test.xml.Generated.cs @@ -541,6 +541,12 @@ private static Syntax.InternalSyntax.TypeConstraintSyntax GenerateTypeConstraint private static Syntax.InternalSyntax.DefaultConstraintSyntax GenerateDefaultConstraint() => InternalSyntaxFactory.DefaultConstraint(InternalSyntaxFactory.Token(SyntaxKind.DefaultKeyword)); + private static Syntax.InternalSyntax.AllowsConstraintClauseSyntax GenerateAllowsConstraintClause() + => InternalSyntaxFactory.AllowsConstraintClause(InternalSyntaxFactory.Token(SyntaxKind.AllowsKeyword), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList()); + + private static Syntax.InternalSyntax.RefStructConstraintSyntax GenerateRefStructConstraint() + => InternalSyntaxFactory.RefStructConstraint(InternalSyntaxFactory.Token(SyntaxKind.RefKeyword), InternalSyntaxFactory.Token(SyntaxKind.StructKeyword)); + private static Syntax.InternalSyntax.FieldDeclarationSyntax GenerateFieldDeclaration() => InternalSyntaxFactory.FieldDeclaration(new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), new Microsoft.CodeAnalysis.Syntax.InternalSyntax.SyntaxList(), GenerateVariableDeclaration(), InternalSyntaxFactory.Token(SyntaxKind.SemicolonToken)); @@ -2960,6 +2966,28 @@ public void TestDefaultConstraintFactoryAndProperties() AttachAndCheckDiagnostics(node); } + [Fact] + public void TestAllowsConstraintClauseFactoryAndProperties() + { + var node = GenerateAllowsConstraintClause(); + + Assert.Equal(SyntaxKind.AllowsKeyword, node.AllowsKeyword.Kind); + Assert.Equal(default, node.Constraints); + + AttachAndCheckDiagnostics(node); + } + + [Fact] + public void TestRefStructConstraintFactoryAndProperties() + { + var node = GenerateRefStructConstraint(); + + Assert.Equal(SyntaxKind.RefKeyword, node.RefKeyword.Kind); + Assert.Equal(SyntaxKind.StructKeyword, node.StructKeyword.Kind); + + AttachAndCheckDiagnostics(node); + } + [Fact] public void TestFieldDeclarationFactoryAndProperties() { @@ -8438,6 +8466,58 @@ public void TestDefaultConstraintIdentityRewriter() Assert.Same(oldNode, newNode); } + [Fact] + public void TestAllowsConstraintClauseTokenDeleteRewriter() + { + var oldNode = GenerateAllowsConstraintClause(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestAllowsConstraintClauseIdentityRewriter() + { + var oldNode = GenerateAllowsConstraintClause(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + + [Fact] + public void TestRefStructConstraintTokenDeleteRewriter() + { + var oldNode = GenerateRefStructConstraint(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestRefStructConstraintIdentityRewriter() + { + var oldNode = GenerateRefStructConstraint(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + [Fact] public void TestFieldDeclarationTokenDeleteRewriter() { @@ -10638,6 +10718,12 @@ private static TypeConstraintSyntax GenerateTypeConstraint() private static DefaultConstraintSyntax GenerateDefaultConstraint() => SyntaxFactory.DefaultConstraint(SyntaxFactory.Token(SyntaxKind.DefaultKeyword)); + private static AllowsConstraintClauseSyntax GenerateAllowsConstraintClause() + => SyntaxFactory.AllowsConstraintClause(SyntaxFactory.Token(SyntaxKind.AllowsKeyword), new SeparatedSyntaxList()); + + private static RefStructConstraintSyntax GenerateRefStructConstraint() + => SyntaxFactory.RefStructConstraint(SyntaxFactory.Token(SyntaxKind.RefKeyword), SyntaxFactory.Token(SyntaxKind.StructKeyword)); + private static FieldDeclarationSyntax GenerateFieldDeclaration() => SyntaxFactory.FieldDeclaration(new SyntaxList(), new SyntaxTokenList(), GenerateVariableDeclaration(), SyntaxFactory.Token(SyntaxKind.SemicolonToken)); @@ -13057,6 +13143,28 @@ public void TestDefaultConstraintFactoryAndProperties() Assert.Equal(node, newNode); } + [Fact] + public void TestAllowsConstraintClauseFactoryAndProperties() + { + var node = GenerateAllowsConstraintClause(); + + Assert.Equal(SyntaxKind.AllowsKeyword, node.AllowsKeyword.Kind()); + Assert.Equal(default, node.Constraints); + var newNode = node.WithAllowsKeyword(node.AllowsKeyword).WithConstraints(node.Constraints); + Assert.Equal(node, newNode); + } + + [Fact] + public void TestRefStructConstraintFactoryAndProperties() + { + var node = GenerateRefStructConstraint(); + + Assert.Equal(SyntaxKind.RefKeyword, node.RefKeyword.Kind()); + Assert.Equal(SyntaxKind.StructKeyword, node.StructKeyword.Kind()); + var newNode = node.WithRefKeyword(node.RefKeyword).WithStructKeyword(node.StructKeyword); + Assert.Equal(node, newNode); + } + [Fact] public void TestFieldDeclarationFactoryAndProperties() { @@ -18535,6 +18643,58 @@ public void TestDefaultConstraintIdentityRewriter() Assert.Same(oldNode, newNode); } + [Fact] + public void TestAllowsConstraintClauseTokenDeleteRewriter() + { + var oldNode = GenerateAllowsConstraintClause(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestAllowsConstraintClauseIdentityRewriter() + { + var oldNode = GenerateAllowsConstraintClause(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + + [Fact] + public void TestRefStructConstraintTokenDeleteRewriter() + { + var oldNode = GenerateRefStructConstraint(); + var rewriter = new TokenDeleteRewriter(); + var newNode = rewriter.Visit(oldNode); + + if(!oldNode.IsMissing) + { + Assert.NotEqual(oldNode, newNode); + } + + Assert.NotNull(newNode); + Assert.True(newNode.IsMissing, "No tokens => missing"); + } + + [Fact] + public void TestRefStructConstraintIdentityRewriter() + { + var oldNode = GenerateRefStructConstraint(); + var rewriter = new IdentityRewriter(); + var newNode = rewriter.Visit(oldNode); + + Assert.Same(oldNode, newNode); + } + [Fact] public void TestFieldDeclarationTokenDeleteRewriter() { diff --git a/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalErrorTests.cs b/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalErrorTests.cs index 64fc656f659fb..fa74f7a8895d2 100644 --- a/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalErrorTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalErrorTests.cs @@ -573,48 +573,48 @@ public static int Main () } [Fact] - public void CS1035AtColonParsedAsComment_01() + public void CS1035AtColonParsedAsBadRazorContent_01() { var test = """ var x = @:; """; ParsingTests.ParseAndValidate(test, - // (1,9): error CS1056: Unexpected character '@' + // (1,9): error CS1525: Invalid expression term '' // var x = @:; - Diagnostic(ErrorCode.ERR_UnexpectedCharacter, "@").WithArguments("@").WithLocation(1, 9), - // (1,12): error CS1733: Expected expression + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "@:;").WithArguments("").WithLocation(1, 9), + // (1,10): error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ // var x = @:; - Diagnostic(ErrorCode.ERR_ExpressionExpected, "").WithLocation(1, 12), + Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral, ":").WithLocation(1, 10), // (1,12): error CS1002: ; expected // var x = @:; Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(1, 12)); } [Fact] - public void CS1035AtColonParsedAsComment_02() + public void CS1035AtColonParsedAsBadRazorContent_02() { var test = """ @:
test
"""; ParsingTests.ParseAndValidate(test, - // (1,1): error CS1056: Unexpected character '@' + // (1,2): error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ // @:
test
- Diagnostic(ErrorCode.ERR_UnexpectedCharacter, "@").WithArguments("@").WithLocation(1, 1)); + Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral, ":").WithLocation(1, 2)); } [Fact] - public void CS1035AtColonParsedAsComment_03() + public void CS1035AtColonParsedAsBadRazorContent_03() { var test = """ @: M() {} """; ParsingTests.ParseAndValidate(test, - // (1,1): error CS1056: Unexpected character '@' + // (1,2): error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ // @: M() {} - Diagnostic(ErrorCode.ERR_UnexpectedCharacter, "@").WithArguments("@").WithLocation(1, 1)); + Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral, ":").WithLocation(1, 2)); } [Fact, WorkItem(526993, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/526993")] diff --git a/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalTests.cs b/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalTests.cs index 462c92901099f..8c9baa9d69028 100644 --- a/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/LexicalTests.cs @@ -441,28 +441,26 @@ public void TestMixedMultiLineCommentTerminators_01(char outsideDelimiter, char } [Fact] - [Trait("Feature", "Comments")] - public void TestAtColonTreatedAsComment_RazorRecovery() + [Trait("Feature", "Razor")] + public void TestAtColonTreatedAsBadRazorContentToken_RazorRecovery() { var text = "@: More text"; var token = LexToken(text); Assert.NotEqual(default, token); - Assert.Equal(SyntaxKind.EndOfFileToken, token.Kind()); + Assert.Equal(SyntaxKind.RazorContentToken, token.Kind()); Assert.Equal(text, token.ToFullString()); var errors = token.Errors(); errors.Verify( - // error CS1056: Unexpected character '@' - TestBase.Diagnostic(ErrorCode.ERR_UnexpectedCharacter).WithArguments("@").WithLocation(1, 1)); - var trivia = token.GetLeadingTrivia().ToArray(); - Assert.Equal(1, trivia.Length); - Assert.NotEqual(default, trivia[0]); - Assert.Equal(SyntaxKind.SingleLineCommentTrivia, trivia[0].Kind()); + // error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ + TestBase.Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral).WithLocation(1, 1)); + Assert.Empty(token.LeadingTrivia); + Assert.Empty(token.TrailingTrivia); } [Fact] - [Trait("Feature", "Comments")] - public void TestAtColonTreatedAsCommentAsTrailingTrivia_RazorRecovery() + [Trait("Feature", "Razor")] + public void TestAtColonTreatedAsBadRazorContentTokenEndOfLine_RazorRecovery() { var text = """ Identifier @: More text @@ -474,19 +472,21 @@ public void TestAtColonTreatedAsCommentAsTrailingTrivia_RazorRecovery() Assert.NotEqual(default, token); Assert.Equal(SyntaxKind.IdentifierToken, token.Kind()); + Assert.Empty(token.Errors()); + + token = tokens[1]; + Assert.NotEqual(default, token); + Assert.Equal(SyntaxKind.RazorContentToken, token.Kind()); var errors = token.Errors(); errors.Verify( - // error CS1056: Unexpected character '@' - TestBase.Diagnostic(ErrorCode.ERR_UnexpectedCharacter).WithArguments("@").WithLocation(1, 1)); - var trivia = token.GetLeadingTrivia().ToArray(); - Assert.Equal(0, trivia.Length); - trivia = token.GetTrailingTrivia().ToArray(); - Assert.Equal(3, trivia.Length); - Assert.NotEqual(default, trivia[1]); - Assert.Equal(SyntaxKind.SingleLineCommentTrivia, trivia[1].Kind()); - Assert.Equal("@: More text", trivia[1].ToFullString()); + // error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ + TestBase.Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral).WithLocation(1, 1)); + Assert.Empty(token.LeadingTrivia); + Assert.Single(token.TrailingTrivia); + Assert.Equal(SyntaxKind.EndOfLineTrivia, token.TrailingTrivia[0].Kind()); + Assert.Equal("@: More text", token.Text); - token = tokens[1]; + token = tokens[2]; Assert.NotEqual(default, token); Assert.Equal(SyntaxKind.IdentifierToken, token.Kind()); Assert.Equal(""" @@ -496,8 +496,8 @@ public void TestAtColonTreatedAsCommentAsTrailingTrivia_RazorRecovery() } [Fact] - [Trait("Feature", "Comments")] - public void TestAtColonTreatedAsComment_TrailingMultiLine_RazorRecovery() + [Trait("Feature", "Razor")] + public void TestAtColonTreatedAsBadRazorContentToken_TrailingMultiLine_RazorRecovery() { var text = """ @: /* @@ -509,26 +509,24 @@ public void TestAtColonTreatedAsComment_TrailingMultiLine_RazorRecovery() var token = tokens[0]; Assert.NotEqual(default, token); - Assert.Equal(SyntaxKind.IdentifierToken, token.Kind()); - Assert.Equal(""" - @: /* - Identifier - - """, token.ToFullString()); + Assert.Equal(SyntaxKind.RazorContentToken, token.Kind()); + Assert.Equal("@: /*", token.ToString()); var errors = token.Errors(); errors.Verify( - // error CS1056: Unexpected character '@' - TestBase.Diagnostic(ErrorCode.ERR_UnexpectedCharacter).WithArguments("@").WithLocation(1, 1)); - var trivia = token.GetLeadingTrivia().ToArray(); - Assert.Equal(2, trivia.Length); - Assert.NotEqual(default, trivia[0]); - Assert.Equal(SyntaxKind.SingleLineCommentTrivia, trivia[0].Kind()); - Assert.Equal("@: /*", trivia[0].ToFullString()); + // error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ + TestBase.Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral).WithLocation(1, 1)); + Assert.Empty(token.LeadingTrivia); + Assert.Single(token.TrailingTrivia); + Assert.Equal(SyntaxKind.EndOfLineTrivia, token.TrailingTrivia[0].Kind()); + + token = tokens[1]; + Assert.Equal(SyntaxKind.IdentifierToken, token.Kind()); + Assert.Equal("Identifier", token.Text); } [Fact] - [Trait("Feature", "Comments")] - public void TestAtColonTreatedAsComment_PreprocessorDisabled_RazorRecovery() + [Trait("Feature", "Razor")] + public void TestAtColonTreatedAsBadRazorContentToken_PreprocessorDisabled_RazorRecovery() { var text = """ #if false @@ -551,8 +549,8 @@ public void TestAtColonTreatedAsComment_PreprocessorDisabled_RazorRecovery() } [Fact] - [Trait("Feature", "Comments")] - public void TestAtColonTreatedAsComment_PreprocessorEnabled_RazorRecovery() + [Trait("Feature", "Razor")] + public void TestAtColonTreatedAsBadRazorContentToken_PreprocessorEnabled_RazorRecovery() { var text = """ #if true @@ -560,21 +558,30 @@ public void TestAtColonTreatedAsComment_PreprocessorEnabled_RazorRecovery() #endif """; - var token = LexToken(text); + var tokens = Lex(text).ToArray(); + Assert.Equal(2, tokens.Length); + var token = tokens[0]; Assert.NotEqual(default, token); - Assert.Equal(SyntaxKind.EndOfFileToken, token.Kind()); - Assert.Equal(text, token.ToFullString()); + Assert.Equal(SyntaxKind.RazorContentToken, token.Kind()); + Assert.Equal(""" + #if true + @: + + """, token.ToFullString()); var errors = token.Errors(); errors.Verify( - // error CS1056: Unexpected character '@' - TestBase.Diagnostic(ErrorCode.ERR_UnexpectedCharacter).WithArguments("@").WithLocation(1, 1)); - var trivia = token.GetLeadingTrivia().ToArray(); - Assert.Equal(4, trivia.Length); - Assert.Equal(SyntaxKind.IfDirectiveTrivia, trivia[0].Kind()); - Assert.Equal(SyntaxKind.SingleLineCommentTrivia, trivia[1].Kind()); - Assert.Equal(SyntaxKind.EndOfLineTrivia, trivia[2].Kind()); - Assert.Equal(SyntaxKind.EndIfDirectiveTrivia, trivia[3].Kind()); + // error CS1646: Keyword, identifier, or string expected after verbatim specifier: @ + TestBase.Diagnostic(ErrorCode.ERR_ExpectedVerbatimLiteral).WithLocation(1, 1)); + Assert.Single(token.GetLeadingTrivia()); + Assert.Equal(SyntaxKind.IfDirectiveTrivia, token.GetLeadingTrivia()[0].Kind()); + + token = tokens[1]; + Assert.Equal(SyntaxKind.EndOfFileToken, token.Kind()); + Assert.Equal("#endif", token.ToFullString()); + Assert.Single(token.GetLeadingTrivia()); + Assert.Equal(SyntaxKind.EndIfDirectiveTrivia, token.GetLeadingTrivia()[0].Kind()); + Assert.Empty(token.GetTrailingTrivia()); } [Fact] diff --git a/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/SyntaxTokenParserTests.cs b/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/SyntaxTokenParserTests.cs index a943d55c7d1d5..7a3ae5b79fff7 100644 --- a/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/SyntaxTokenParserTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/LexicalAndXml/SyntaxTokenParserTests.cs @@ -10,6 +10,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.LexicalAndXml; +#pragma warning disable RSEXPERIMENTAL003 // SyntaxTokenParser public class SyntaxTokenParserTests { [Fact] @@ -265,6 +266,144 @@ public void ResultContextualKind() AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(16, 5), "class", parser.ParseNextToken()); } + [Fact] + public void ParseLeadingTrivia_Empty() + { + var sourceText = SourceText.From("class C { }"); + var parser = SyntaxFactory.CreateTokenParser(sourceText, TestOptions.Regular); + + var result = parser.ParseLeadingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 0), "", result); + Assert.Empty(result.Token.LeadingTrivia); + Assert.Empty(result.Token.TrailingTrivia); + + result = parser.ParseTrailingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 0), "", result); + Assert.Empty(result.Token.LeadingTrivia); + Assert.Empty(result.Token.TrailingTrivia); + + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 6), "class ", parser.ParseNextToken()); + } + + [Fact] + public void ParseLeadingTrivia_SameLine() + { + var sourceText = SourceText.From("/* test */ class C { }"); + var parser = SyntaxFactory.CreateTokenParser(sourceText, TestOptions.Regular); + + var result = parser.ParseLeadingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 11), "/* test */ ", result); + AssertTrivia(result.Token.LeadingTrivia, + (SyntaxKind.MultiLineCommentTrivia, "/* test */"), + (SyntaxKind.WhitespaceTrivia, " ")); + Assert.Empty(result.Token.TrailingTrivia); + + var intermediateResult = parser.ParseLeadingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(11, 0), "", intermediateResult); + Assert.Empty(intermediateResult.Token.LeadingTrivia); + Assert.Empty(intermediateResult.Token.TrailingTrivia); + + intermediateResult = parser.ParseTrailingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(11, 0), "", intermediateResult); + Assert.Empty(intermediateResult.Token.LeadingTrivia); + Assert.Empty(intermediateResult.Token.TrailingTrivia); + + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(11, 6), "class ", parser.ParseNextToken()); + + parser.ResetTo(result); + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 17), "/* test */ class ", parser.ParseNextToken()); + } + + [Fact] + public void ParseLeadingTrivia_MultiLine() + { + var sourceText = SourceText.From(""" + /* test */ + + class C { } + """.NormalizeLineEndings()); + var parser = SyntaxFactory.CreateTokenParser(sourceText, TestOptions.Regular); + + var result = parser.ParseLeadingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 14), $"/* test */\r\n\r\n", result); + AssertTrivia(result.Token.LeadingTrivia, + (SyntaxKind.MultiLineCommentTrivia, "/* test */"), + (SyntaxKind.EndOfLineTrivia, "\r\n"), + (SyntaxKind.EndOfLineTrivia, "\r\n")); + Assert.Empty(result.Token.TrailingTrivia); + + var intermediateResult = parser.ParseLeadingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(14, 0), "", intermediateResult); + Assert.Empty(intermediateResult.Token.LeadingTrivia); + Assert.Empty(intermediateResult.Token.TrailingTrivia); + + intermediateResult = parser.ParseTrailingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(14, 0), "", intermediateResult); + Assert.Empty(intermediateResult.Token.LeadingTrivia); + Assert.Empty(intermediateResult.Token.TrailingTrivia); + + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(14, 6), "class ", parser.ParseNextToken()); + + parser.ResetTo(result); + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 20), "/* test */\r\n\r\nclass ", parser.ParseNextToken()); + } + + [Fact] + public void ParseTrailingTrivia_Empty() + { + var sourceText = SourceText.From("class C { }"); + var parser = SyntaxFactory.CreateTokenParser(sourceText, TestOptions.Regular); + + var result = parser.ParseTrailingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 0), "", result); + Assert.Empty(result.Token.LeadingTrivia); + Assert.Empty(result.Token.TrailingTrivia); + + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 6), "class ", parser.ParseNextToken()); + } + + [Fact] + public void ParseTrailingTrivia_SameLine() + { + var sourceText = SourceText.From("/* test */ class C { }"); + var parser = SyntaxFactory.CreateTokenParser(sourceText, TestOptions.Regular); + + var result = parser.ParseTrailingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 11), "/* test */ ", result); + Assert.Empty(result.Token.LeadingTrivia); + AssertTrivia(result.Token.TrailingTrivia, + (SyntaxKind.MultiLineCommentTrivia, "/* test */"), + (SyntaxKind.WhitespaceTrivia, " ")); + + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(11, 6), "class ", parser.ParseNextToken()); + + parser.ResetTo(result); + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 17), "/* test */ class ", parser.ParseNextToken()); + } + + [Fact] + public void ParseTrailingTrivia_MultiLine() + { + var sourceText = SourceText.From(""" + /* test */ + + class C { } + """.NormalizeLineEndings()); + var parser = SyntaxFactory.CreateTokenParser(sourceText, TestOptions.Regular); + + var result = parser.ParseTrailingTrivia(); + AssertToken(expectedKind: SyntaxKind.None, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 12), $"/* test */\r\n", result); + Assert.Empty(result.Token.LeadingTrivia); + AssertTrivia(result.Token.TrailingTrivia, + (SyntaxKind.MultiLineCommentTrivia, "/* test */"), + (SyntaxKind.EndOfLineTrivia, "\r\n")); + + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(12, 8), "\r\nclass ", parser.ParseNextToken()); + + parser.ResetTo(result); + AssertToken(expectedKind: SyntaxKind.ClassKeyword, expectedContextualKind: SyntaxKind.None, new TextSpan(0, 20), "/* test */\r\n\r\nclass ", parser.ParseNextToken()); + } + private static void AssertToken(SyntaxKind expectedKind, SyntaxKind expectedContextualKind, TextSpan expectedFullSpan, string expectedText, SyntaxTokenParser.Result result) { Assert.Equal(expectedKind, result.Token.Kind()); @@ -273,4 +412,15 @@ private static void AssertToken(SyntaxKind expectedKind, SyntaxKind expectedCont Assert.Null(result.Token.Parent); Assert.Equal(expectedFullSpan, result.Token.FullSpan); } + + private static void AssertTrivia(SyntaxTriviaList leadingTrivia, params (SyntaxKind kind, string text)[] expectedTrivia) + { + Assert.Equal(expectedTrivia.Length, leadingTrivia.Count); + for (int i = 0; i < expectedTrivia.Length; i++) + { + var (kind, text) = expectedTrivia[i]; + Assert.Equal(kind, leadingTrivia[i].Kind()); + Assert.Equal(text, leadingTrivia[i].ToFullString()); + } + } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/AllowsConstraintParsing.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/AllowsConstraintParsing.cs new file mode 100644 index 0000000000000..3e8ed3675fe38 --- /dev/null +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/AllowsConstraintParsing.cs @@ -0,0 +1,1893 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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 Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; +using Xunit.Abstractions; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + public sealed class AllowsConstraintParsing : ParsingTests + { + private new SyntaxTree UsingTree(string text, params DiagnosticDescription[] expectedErrors) + => UsingTree(text, options: null, expectedErrors); + + public AllowsConstraintParsing(ITestOutputHelper output) : base(output) { } + + [Fact] + public void RefStruct_Single() + { + var text = @" +class C where T : allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_Single_MissingRef() + { + var text = @" +class C where T : allows struct +{}"; + UsingTree(text, + // (2,29): error CS1003: Syntax error, ',' expected + // class C where T : allows struct + Diagnostic(ErrorCode.ERR_SyntaxError, "struct").WithArguments(",").WithLocation(2, 29) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "allows"); + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_Single_MissingStruct() + { + var text = @" +class C where T : allows ref +{}"; + UsingTree(text, + // (2,32): error CS1003: Syntax error, 'struct' expected + // class C where T : allows ref + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("struct").WithLocation(2, 32) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + M(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_Single_MissingRefAndStruct() + { + var text = @" +class C where T : allows +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "allows"); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_Single_EscapedAllows() + { + var text = @" +class C where T : @allows ref struct +{}"; + UsingTree(text, + // (2,30): error CS1003: Syntax error, ',' expected + // class C where T : @allows ref struct + Diagnostic(ErrorCode.ERR_SyntaxError, "ref").WithArguments(",").WithLocation(2, 30), + // (2,34): error CS1003: Syntax error, ',' expected + // class C where T : @allows ref struct + Diagnostic(ErrorCode.ERR_SyntaxError, "struct").WithArguments(",").WithLocation(2, 34) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "@allows"); + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_Single_EscapedRef() + { + var text = @" +class C where T : allows @ref struct +{}"; + UsingTree(text, + // (2,29): error CS1003: Syntax error, ',' expected + // class C where T : allows @ref struct + Diagnostic(ErrorCode.ERR_SyntaxError, "@ref").WithArguments(",").WithLocation(2, 29), + // (2,34): error CS1003: Syntax error, ',' expected + // class C where T : allows @ref struct + Diagnostic(ErrorCode.ERR_SyntaxError, "struct").WithArguments(",").WithLocation(2, 34) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "allows"); + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "@ref"); + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_Single_EscapedStruct() + { + var text = @" +class C where T : allows ref @struct +{}"; + UsingTree(text, + // (2,33): error CS1003: Syntax error, 'struct' expected + // class C where T : allows ref @struct + Diagnostic(ErrorCode.ERR_SyntaxError, "@struct").WithArguments("struct").WithLocation(2, 33), + // (2,33): error CS1003: Syntax error, ',' expected + // class C where T : allows ref @struct + Diagnostic(ErrorCode.ERR_SyntaxError, "@struct").WithArguments(",").WithLocation(2, 33) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + M(SyntaxKind.StructKeyword); + } + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "@struct"); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_TwoInARow() + { + var text = @" +class C where T : allows ref struct, ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_TwoInARow_MissingRef() + { + var text = @" +class C where T : allows ref struct, struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_TwoInARow_MissingStruct() + { + var text = @" +class C where T : allows ref struct, ref +{}"; + UsingTree(text, + // (2,44): error CS1003: Syntax error, 'struct' expected + // class C where T : allows ref struct, ref + Diagnostic(ErrorCode.ERR_SyntaxError, "").WithArguments("struct").WithLocation(2, 44) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + M(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_TwoAllowsInARow() + { + var text = @" +class C where T : allows ref struct, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_FollowedByAComma_01() + { + var text = @" +class C where T : allows ref struct, +{}"; + UsingTree(text, + // (2,39): error CS1073: Unexpected token ',' + // class C where T : allows ref struct, + Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 39) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_FollowedByAComma_02() + { + var text = @" +class C where T : struct, allows ref struct, +{}"; + UsingTree(text, + // (2,47): error CS1073: Unexpected token ',' + // class C where T : struct, allows ref struct, + Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 47) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_FollowedByACommaAndWhere_01() + { + var text = @" +class C where T : allows ref struct, where S : class +{}"; + UsingTree(text, + // (2,42): error CS1073: Unexpected token ',' + // class C where T : allows ref struct, where S : class + Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 42) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.ClassConstraint); + { + N(SyntaxKind.ClassKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_FollowedByACommaAndWhere_02() + { + var text = @" +class C where T : struct, allows ref struct, where S : class +{}"; + UsingTree(text, + // (2,50): error CS1073: Unexpected token ',' + // class C where T : struct, allows ref struct, where S : class + Diagnostic(ErrorCode.ERR_UnexpectedToken, ",").WithArguments(",").WithLocation(2, 50) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.ClassConstraint); + { + N(SyntaxKind.ClassKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_FollowedByWhere_01() + { + var text = @" +class C where T : allows ref struct where S : class +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.ClassConstraint); + { + N(SyntaxKind.ClassKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_FollowedByWhere_02() + { + var text = @" +class C where T : struct, allows ref struct where S : class +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "S"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.ClassConstraint); + { + N(SyntaxKind.ClassKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterStruct() + { + var text = @" +class C where T : struct, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterStructAndMissingComma() + { + var text = @" +class C where T : struct allows ref struct +{}"; + UsingTree(text, + // (2,29): error CS1003: Syntax error, ',' expected + // class C where T : struct allows ref struct + Diagnostic(ErrorCode.ERR_SyntaxError, "allows").WithArguments(",").WithLocation(2, 29) + ); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + M(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterClass() + { + var text = @" +class C where T : class, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.ClassConstraint); + { + N(SyntaxKind.ClassKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterDefault() + { + var text = @" +class C where T : default, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.DefaultConstraint); + { + N(SyntaxKind.DefaultKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterUnmanaged() + { + var text = @" +class C where T : unmanaged, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "unmanaged"); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterNotNull() + { + var text = @" +class C where T : notnull, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "notnull"); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterTypeConstraint() + { + var text = @" +class C where T : SomeType, allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "SomeType"); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterNew() + { + var text = @" +class C where T : new(), allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.ConstructorConstraint); + { + N(SyntaxKind.NewKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_AfterMultiple() + { + var text = @" +class C where T : struct, SomeType, new(), allows ref struct +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.StructConstraint); + { + N(SyntaxKind.StructKeyword); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "SomeType"); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.ConstructorConstraint); + { + N(SyntaxKind.NewKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_BeforeClass() + { + var text = @" +class C where T : allows ref struct, class +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.ClassConstraint); + { + N(SyntaxKind.ClassKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_BeforeDefault() + { + var text = @" +class C where T : allows ref struct, default +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.DefaultConstraint); + { + N(SyntaxKind.DefaultKeyword); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_BeforeUnmanaged() + { + var text = @" +class C where T : allows ref struct, unmanaged +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "unmanaged"); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_BeforeNotNull() + { + var text = @" +class C where T : allows ref struct, notnull +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "notnull"); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_BeforeTypeConstraint() + { + var text = @" +class C where T : allows ref struct, SomeType +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.TypeConstraint); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "SomeType"); + } + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + + [Fact] + public void RefStruct_BeforeNew() + { + var text = @" +class C where T : allows ref struct, new() +{}"; + UsingTree(text); + + N(SyntaxKind.CompilationUnit); + { + N(SyntaxKind.ClassDeclaration); + { + N(SyntaxKind.ClassKeyword); + N(SyntaxKind.IdentifierToken, "C"); + N(SyntaxKind.TypeParameterList); + { + N(SyntaxKind.LessThanToken); + N(SyntaxKind.TypeParameter); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.GreaterThanToken); + } + N(SyntaxKind.TypeParameterConstraintClause); + { + N(SyntaxKind.WhereKeyword); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "T"); + } + N(SyntaxKind.ColonToken); + N(SyntaxKind.AllowsConstraintClause); + { + N(SyntaxKind.AllowsKeyword); + N(SyntaxKind.RefStructConstraint); + { + N(SyntaxKind.RefKeyword); + N(SyntaxKind.StructKeyword); + } + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.ConstructorConstraint); + { + N(SyntaxKind.NewKeyword); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.CloseParenToken); + } + } + N(SyntaxKind.OpenBraceToken); + N(SyntaxKind.CloseBraceToken); + } + N(SyntaxKind.EndOfFileToken); + } + EOF(); + } + } +} diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs index 108878af7c079..51342e36cb491 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/ParserErrorMessageTests.cs @@ -791,7 +791,7 @@ public static int Main () } "; CreateCompilation(test).VerifyDiagnostics( - // (5,22): error CS0401: The new() constraint must be the last constraint specified + // (5,22): error CS0401: The new() constraint must be the last restrictive constraint specified // class C where T : new(), IA // CS0401 - should be T : IA, new() Diagnostic(ErrorCode.ERR_NewBoundMustBeLast, "new").WithLocation(5, 22)); } diff --git a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs index d98debc243bf9..bcb044788b178 100644 --- a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs @@ -3408,7 +3408,7 @@ private static void TestNormalizeDeclaration(string text, string expected) var node = SyntaxFactory.ParseCompilationUnit(text.NormalizeLineEndings()); Assert.Equal(text.NormalizeLineEndings(), node.ToFullString().NormalizeLineEndings()); var actual = node.NormalizeWhitespace(" ").ToFullString(); - Assert.Equal(expected.NormalizeLineEndings(), actual.NormalizeLineEndings()); + AssertEx.Equal(expected.NormalizeLineEndings(), actual.NormalizeLineEndings()); } [Fact] @@ -5979,5 +5979,95 @@ public void TestNormalizeParseExpressionLiteralCharacter(string expression) var syntaxNode = SyntaxFactory.ParseExpression(expression).NormalizeWhitespace(); Assert.Equal(expression, syntaxNode.ToFullString()); } + + [Fact] + public void TestNormalizeAllowsRefStructConstraint_01() + { + TestNormalizeDeclaration(""" + class C1 where T:allows ref struct ; + class C2 where T:allows ref struct,where S:struct ; + class C3 where T:struct,allows ref struct ; + class C4 where T:new(),allows ref struct ; + class C5 + where + T + : + allows + ref + struct + ; + class C6 where T:allows ref struct where S:struct ; + """, """ + class C1 + where T : allows ref struct; + class C2 + where T : allows ref struct , where S : struct; + class C3 + where T : struct, allows ref struct; + class C4 + where T : new(), allows ref struct; + class C5 + where T : allows ref struct; + class C6 + where T : allows ref struct where S : struct; + """); + } + + [Fact] + public void TestNormalizeAllowsRefStructConstraint_02() + { + TestNormalizeDeclaration(""" + class C + { + void M1() where T:allows ref struct {} + void M2() where T:allows ref struct,where S:struct {} + void M3() where T:struct,allows ref struct {} + void M4() where T:new(),allows ref struct {} + void M5() + where + T + : + allows + ref + struct + { + } + void M6() where T:allows ref struct where S:struct {} + } + """, """ + class C + { + void M1() + where T : allows ref struct + { + } + + void M2() + where T : allows ref struct , where S : struct + { + } + + void M3() + where T : struct, allows ref struct + { + } + + void M4() + where T : new(), allows ref struct + { + } + + void M5() + where T : allows ref struct + { + } + + void M6() + where T : allows ref struct where S : struct + { + } + } + """); + } } } diff --git a/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs b/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs index 5c47171fb8a6f..4f8554738f2b2 100644 --- a/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs @@ -54,7 +54,7 @@ public enum AnalyzerTestKind /// /// Limitation 1: .NET Framework probing path. /// - /// The .NET Framework assembly loader will only call AppDomain.AssemblyResolve when it cannot satifisfy a load + /// The .NET Framework assembly loader will only call AppDomain.AssemblyResolve when it cannot satisfy a load /// request. One of the places the assembly loader will always consider when looking for dependencies of A.dll /// is the directory that A.dll was loading from (it's added to the probing path). That means if B.dll is in the /// same directory then the runtime will silently load it without a way for us to intervene. @@ -95,17 +95,19 @@ public AnalyzerAssemblyLoaderTests(ITestOutputHelper testOutputHelper, AssemblyL #if NETCOREAPP - private void Run(AnalyzerTestKind kind, Action testAction, [CallerMemberName] string? memberName = null) => + private void Run(AnalyzerTestKind kind, Action testAction, IAnalyzerAssemblyResolver[]? externalResolvers = null, [CallerMemberName] string? memberName = null) => Run( kind, static (_, _) => { }, testAction, + externalResolvers, memberName); private void Run( AnalyzerTestKind kind, Action prepLoadContextAction, Action testAction, + IAnalyzerAssemblyResolver[]? externalResolvers = null, [CallerMemberName] string? memberName = null) { var alc = new AssemblyLoadContext($"Test {memberName}", isCollectible: true); @@ -113,7 +115,7 @@ private void Run( { prepLoadContextAction(alc, TestFixture); var util = new InvokeUtil(); - util.Exec(TestOutputHelper, alc, TestFixture, kind, testAction.Method.DeclaringType!.FullName!, testAction.Method.Name); + util.Exec(TestOutputHelper, alc, TestFixture, kind, testAction.Method.DeclaringType!.FullName!, testAction.Method.Name, externalResolvers ?? []); } finally { @@ -126,6 +128,7 @@ private void Run( private void Run( AnalyzerTestKind kind, Action testAction, + IAnalyzerAssemblyResolver[]? externalResolvers = null, [CallerMemberName] string? memberName = null) { AppDomain? appDomain = null; @@ -135,7 +138,7 @@ private void Run( var testOutputHelper = new AppDomainTestOutputHelper(TestOutputHelper); var type = typeof(InvokeUtil); var util = (InvokeUtil)appDomain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName); - util.Exec(testOutputHelper, TestFixture, kind, testAction.Method.DeclaringType.FullName, testAction.Method.Name); + util.Exec(testOutputHelper, TestFixture, kind, testAction.Method.DeclaringType.FullName, testAction.Method.Name, externalResolvers ?? []); } finally { @@ -1421,5 +1424,115 @@ public void AssemblyLoadingInNonDefaultContext_AnalyzerReferencesSystemCollectio }); } #endif + + [Theory] + [CombinatorialData] + public void ExternalResolver_CanIntercept_ReturningNull(AnalyzerTestKind kind) + { + var resolver = new TestAnalyzerAssemblyResolver(n => null); + Run(kind, (AnalyzerAssemblyLoader loader, AssemblyLoadTestFixture testFixture) => + { + loader.AddDependencyLocation(testFixture.Delta1); + Assembly delta = loader.LoadFromPath(testFixture.Delta1); + Assert.NotNull(delta); + VerifyDependencyAssemblies(loader, testFixture.Delta1); + + }, externalResolvers: [resolver]); + Assert.Collection(resolver.CalledFor, (a => Assert.Equal("Delta", a.Name))); + } + + [Theory] + [CombinatorialData] + public void ExternalResolver_CanIntercept_ReturningAssembly(AnalyzerTestKind kind) + { + var resolver = new TestAnalyzerAssemblyResolver(n => GetType().Assembly); + Run(kind, (AnalyzerAssemblyLoader loader, AssemblyLoadTestFixture testFixture) => + { + // net core assembly loader checks that the resolved assembly name is the same as the requested one + // so we use the assembly the tests are contained in as its already be loaded + var thisAssembly = typeof(AnalyzerAssemblyLoaderTests).Assembly; + loader.AddDependencyLocation(thisAssembly.Location); + Assembly loaded = loader.LoadFromPath(thisAssembly.Location); + Assert.Equal(thisAssembly, loaded); + + }, externalResolvers: [resolver]); + Assert.Collection(resolver.CalledFor, (a => Assert.Equal(GetType().Assembly.GetName().Name, a.Name))); + } + + [Theory] + [CombinatorialData] + public void ExternalResolver_CanIntercept_ReturningAssembly_Or_Null(AnalyzerTestKind kind) + { + var thisAssemblyName = GetType().Assembly.GetName(); + var resolver = new TestAnalyzerAssemblyResolver(n => n == thisAssemblyName ? GetType().Assembly : null); + Run(kind, (AnalyzerAssemblyLoader loader, AssemblyLoadTestFixture testFixture) => + { + var thisAssembly = typeof(AnalyzerAssemblyLoaderTests).Assembly; + + loader.AddDependencyLocation(testFixture.Alpha); + Assembly alpha = loader.LoadFromPath(testFixture.Alpha); + Assert.NotNull(alpha); + + loader.AddDependencyLocation(thisAssembly.Location); + Assembly loaded = loader.LoadFromPath(thisAssembly.Location); + Assert.Equal(thisAssembly, loaded); + + loader.AddDependencyLocation(testFixture.Delta1); + Assembly delta = loader.LoadFromPath(testFixture.Delta1); + Assert.NotNull(delta); + + }, externalResolvers: [resolver]); + Assert.Collection(resolver.CalledFor, (a => Assert.Equal("Alpha", a.Name)), a => Assert.Equal(thisAssemblyName.Name, a.Name), a => Assert.Equal("Delta", a.Name)); + } + + [Theory] + [CombinatorialData] + public void ExternalResolver_MultipleResolvers_CanIntercept_ReturningNull(AnalyzerTestKind kind) + { + var resolver1 = new TestAnalyzerAssemblyResolver(n => null); + var resolver2 = new TestAnalyzerAssemblyResolver(n => null); + Run(kind, (AnalyzerAssemblyLoader loader, AssemblyLoadTestFixture testFixture) => + { + loader.AddDependencyLocation(testFixture.Delta1); + Assembly delta = loader.LoadFromPath(testFixture.Delta1); + Assert.NotNull(delta); + VerifyDependencyAssemblies(loader, testFixture.Delta1); + + }, externalResolvers: [resolver1, resolver2]); + Assert.Collection(resolver1.CalledFor, (a => Assert.Equal("Delta", a.Name))); + Assert.Collection(resolver2.CalledFor, (a => Assert.Equal("Delta", a.Name))); + } + + [Theory] + [CombinatorialData] + public void ExternalResolver_MultipleResolvers_ResolutionStops_AfterFirstResolve(AnalyzerTestKind kind) + { + var resolver1 = new TestAnalyzerAssemblyResolver(n => GetType().Assembly); + var resolver2 = new TestAnalyzerAssemblyResolver(n => null); + Run(kind, (AnalyzerAssemblyLoader loader, AssemblyLoadTestFixture testFixture) => + { + var thisAssembly = typeof(AnalyzerAssemblyLoaderTests).Assembly; + loader.AddDependencyLocation(thisAssembly.Location); + Assembly loaded = loader.LoadFromPath(thisAssembly.Location); + Assert.Equal(thisAssembly, loaded); + + }, externalResolvers: [resolver1, resolver2]); + Assert.Collection(resolver1.CalledFor, (a => Assert.Equal(GetType().Assembly.GetName().Name, a.Name))); + Assert.Empty(resolver2.CalledFor); + } + + [Serializable] + private class TestAnalyzerAssemblyResolver(Func func) : MarshalByRefObject, IAnalyzerAssemblyResolver + { + private readonly Func _func = func; + + public List CalledFor { get; } = []; + + public Assembly? ResolveAssembly(AssemblyName assemblyName) + { + CalledFor.Add(assemblyName); + return _func(assemblyName); + } + } } } diff --git a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerConfigTests.cs b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerConfigTests.cs index 0fb4efa394de5..862e18b9ff69f 100644 --- a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerConfigTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerConfigTests.cs @@ -10,6 +10,7 @@ using System.Linq; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Test.Utilities; +using Roslyn.Utilities; using Xunit; using static Microsoft.CodeAnalysis.AnalyzerConfig; using static Roslyn.Test.Utilities.TestHelpers; @@ -63,30 +64,30 @@ public void ConfigWithEscapedValues() { var config = ParseConfigFile(@"is_global = true -[c:/\{f\*i\?le1\}.cs] +[C:/\{f\*i\?le1\}.cs] build_metadata.Compile.ToRetrieve = abc123 -[c:/f\,ile\#2.cs] +[C:/f\,ile\#2.cs] build_metadata.Compile.ToRetrieve = def456 -[c:/f\;i\!le\[3\].cs] +[C:/f\;i\!le\[3\].cs] build_metadata.Compile.ToRetrieve = ghi789 "); var namedSections = config.NamedSections; - Assert.Equal("c:/\\{f\\*i\\?le1\\}.cs", namedSections[0].Name); + Assert.Equal("C:/\\{f\\*i\\?le1\\}.cs", namedSections[0].Name); AssertEx.Equal( new[] { KeyValuePair.Create("build_metadata.compile.toretrieve", "abc123") }, namedSections[0].Properties ); - Assert.Equal("c:/f\\,ile\\#2.cs", namedSections[1].Name); + Assert.Equal("C:/f\\,ile\\#2.cs", namedSections[1].Name); AssertEx.Equal( new[] { KeyValuePair.Create("build_metadata.compile.toretrieve", "def456") }, namedSections[1].Properties ); - Assert.Equal("c:/f\\;i\\!le\\[3\\].cs", namedSections[2].Name); + Assert.Equal("C:/f\\;i\\!le\\[3\\].cs", namedSections[2].Name); AssertEx.Equal( new[] { KeyValuePair.Create("build_metadata.compile.toretrieve", "ghi789") }, namedSections[2].Properties @@ -115,6 +116,40 @@ public void CanGetSectionsWithSpecialCharacters() Assert.Equal("def456", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); } + [ConditionalFact(typeof(WindowsOnly))] + public void CanGetSectionsWithDifferentDriveCasing() + { + var config = Parse(@"is_global = true +build_metadata.compile.toretrieve = global + +[c:/goo/file.cs] +build_metadata.compile.toretrieve = abc123 + +[C:/goo/other.cs] +build_metadata.compile.toretrieve = def456 +", pathToFile: @"C:/.editorconfig"); + + var set = AnalyzerConfigSet.Create(ImmutableArray.Create(config)); + + var sectionOptions = set.GetOptionsForSourcePath(@"c:\goo\file.cs"); + Assert.Equal("abc123", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); + + sectionOptions = set.GetOptionsForSourcePath(@"C:\goo\file.cs"); + Assert.Equal("abc123", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); + + sectionOptions = set.GetOptionsForSourcePath(@"C:\goo\other.cs"); + Assert.Equal("def456", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); + + sectionOptions = set.GetOptionsForSourcePath(@"c:\goo\other.cs"); + Assert.Equal("def456", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); + + sectionOptions = set.GetOptionsForSourcePath(@"c:\global.cs"); + Assert.Equal("global", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); + + sectionOptions = set.GetOptionsForSourcePath(@"C:\global.cs"); + Assert.Equal("global", sectionOptions.AnalyzerOptions["build_metadata.compile.toretrieve"]); + } + [ConditionalFact(typeof(WindowsOnly))] public void WindowsPath() { @@ -932,6 +967,33 @@ public void EditorConfigToDiagnostics() }, options.Select(o => o.TreeOptions).ToArray()); } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/72657")] + [InlineData("/", "/")] + [InlineData("/a/b/c/", "/a/b/c/")] + [InlineData("/a/b//c/", "/a/b/c/")] + [InlineData("/a/b/c/", "/a/b//c/")] + [InlineData("/a/b//c/", "/a/b//c/")] + [InlineData("/a/b/c//", "/a/b/c/")] + [InlineData("/a/b/c/", "/a/b/c//")] + [InlineData("/a/b/c//", "/a/b/c//")] + [InlineData("/a/b//c/", "/a/b///c/")] + public void EditorConfigToDiagnostics_DoubleSlash(string prefixEditorConfig, string prefixSource) + { + var configs = ArrayBuilder.GetInstance(); + configs.Add(Parse(""" + [*.cs] + dotnet_diagnostic.cs000.severity = none + """, + prefixEditorConfig + ".editorconfig")); + + var options = GetAnalyzerConfigOptions([prefixSource + "test.cs"], configs); + configs.Free(); + + Assert.Equal([ + CreateImmutableDictionary(("cs000", ReportDiagnostic.Suppress)) + ], options.Select(o => o.TreeOptions).ToArray()); + } + [Fact] public void LaterSectionOverrides() { @@ -2199,7 +2261,7 @@ public void GlobalConfigOptionsAreEmptyWhenNoGlobalConfig() [InlineData(@"\", false)] //invalid: editorconfig sees a single escape character [InlineData(@"\\", false)] //invalid: editorconfig sees an escaped, literal backslash [InlineData(@"/\{\}\,\[\]\*", true)] - [InlineData(@"c:\my\file.cs", false)] // invalid: editorconfig sees a single file called 'c:(\m)y(\f)ile.cs' (i.e. \m and \f are escape chars) + [InlineData(@"C:\my\file.cs", false)] // invalid: editorconfig sees a single file called 'c:(\m)y(\f)ile.cs' (i.e. \m and \f are escape chars) [InlineData(@"\my\file.cs", false)] // invalid: editorconfig sees a single file called '(\m)y(\f)ile.cs' [InlineData(@"\\my\\file.cs", false)] // invalid: editorconfig sees a single file called '\my\file.cs' with literal backslashes [InlineData(@"\\\\my\\file.cs", false)] // invalid: editorconfig sees a single file called '\\my\file.cs' not a UNC path @@ -2234,20 +2296,20 @@ public void GlobalConfigIssuesWarningWithInvalidSectionNames(string sectionName, } [Theory] - [InlineData("c:/myfile.cs", true, false)] + [InlineData("C:/myfile.cs", true, false)] [InlineData("cd:/myfile.cs", false, false)] // windows only allows a single character as a drive specifier [InlineData(@"\c\:\/myfile.cs", true, false)] // allow escaped characters [InlineData("/myfile.cs", true, true)] //absolute, with a relative drive root [InlineData("c:myfile.cs", false, false)] //relative, wit2h an absolute drive root - [InlineData(@"c:\myfile.cs", false, false)] //not a valid editorconfig path + [InlineData(@"C:\myfile.cs", false, false)] //not a valid editorconfig path [InlineData("//?/C:/Test/Foo.txt", false, false)] // ? is a special char in editorconfig [InlineData(@"//\?/C:/Test/Foo.txt", true, true)] [InlineData(@"\\?\C:\Test\Foo.txt", false, false)] - [InlineData(@"c:", false, false)] - [InlineData(@"c\", false, false)] + [InlineData(@"C:", false, false)] + [InlineData(@"C\", false, false)] [InlineData(@"\c\:", false, false)] - [InlineData("c:/", true, false)] - [InlineData("c:/*.cs", false, false)] + [InlineData("C:/", true, false)] + [InlineData("C:/*.cs", false, false)] public void GlobalConfigIssuesWarningWithInvalidSectionNames_PlatformSpecific(string sectionName, bool isValidWindows, bool isValidOther) => GlobalConfigIssuesWarningWithInvalidSectionNames(sectionName, ExecutionConditionUtil.IsWindows ? isValidWindows : isValidOther); diff --git a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceAppDomainTests.cs b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceAppDomainTests.cs index 7d679f73ad6e9..f79eaa292b2c4 100644 --- a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceAppDomainTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceAppDomainTests.cs @@ -94,9 +94,9 @@ public class TestAnalyzer : DiagnosticAnalyzer new SyntaxTree[] { CSharp.SyntaxFactory.ParseSyntaxTree(analyzerSource) }, new MetadataReference[] { - NetStandard20.mscorlib, - NetStandard20.netstandard, - NetStandard20.SystemRuntime, + NetStandard20.References.mscorlib, + NetStandard20.References.netstandard, + NetStandard20.References.SystemRuntime, MetadataReference.CreateFromFile(immutable.Path), MetadataReference.CreateFromFile(analyzer.Path) }, diff --git a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs index db7d81f653b48..ee5884433c796 100644 --- a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs @@ -749,5 +749,6 @@ public class TestSourceAndIncrementalGenerator : IIncrementalGenerator, ISourceG public void AddDependencyLocation(string fullPath) { } public bool IsHostAssembly(Assembly assembly) => false; public Assembly LoadFromPath(string fullPath) => throw new Exception(); + public string? GetOriginalDependencyLocation(AssemblyName assembly) => throw new Exception(); } } diff --git a/src/Compilers/Core/CodeAnalysisTest/FileSystem/PathUtilitiesTests.cs b/src/Compilers/Core/CodeAnalysisTest/FileSystem/PathUtilitiesTests.cs index 123f0ba58d5d1..9107a9af4f3c1 100644 --- a/src/Compilers/Core/CodeAnalysisTest/FileSystem/PathUtilitiesTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/FileSystem/PathUtilitiesTests.cs @@ -420,5 +420,44 @@ public void GetRelativePath_EnsureNo_IndexOutOfRangeException_Unix() var result = PathUtilities.GetRelativePath(@"/A/B/", @"/A/B"); Assert.Equal(expected, result); } + + [Theory] + [InlineData(@"//a/b/c", @"//a/b/c")] + [InlineData(@"/a\b/c/", @"/a/b/c/")] + [InlineData(@"\a\b/c/", @"/a/b/c/")] + [InlineData(@"C:\\a", @"C:/a")] + [InlineData(@"C:\a\b\c\", @"C:/a/b/c/")] + [InlineData(@"/\a", @"//a")] + [InlineData(@"a\\\b", @"a/b")] + [InlineData(@"\\\a\b\c", @"///a/b/c")] + [InlineData(@"\\\\a\b\c", @"///a/b/c")] + public void CollapseWithForwardSlash(string input, string output) + { + AssertEx.Equal(output, PathUtilities.CollapseWithForwardSlash(input.AsSpan())); + } + + [ConditionalTheory(typeof(WindowsOnly))] + [InlineData(@"//a/b/c", @"//a/b/c")] + [InlineData(@"/a\b/c/", @"/a\b/c/")] + [InlineData(@"C:B", @"C:B")] + [InlineData(@"c:b", @"c:b")] + [InlineData(@"c:\b", @"C:\b")] + [InlineData(@"c:/b", @"C:/b")] + public void NormalizeDriveLetter_Windows(string input, string output) + { + AssertEx.Equal(output, PathUtilities.NormalizeDriveLetter(input)); + } + + [ConditionalTheory(typeof(UnixLikeOnly))] + [InlineData(@"//a/b/c")] + [InlineData(@"/a\b/c/")] + [InlineData(@"C:B")] + [InlineData(@"c:b")] + [InlineData(@"c:\b")] + [InlineData(@"c:/b")] + public void NormalizeDriveLetter_UnixLike(string input) + { + AssertEx.Equal(input, PathUtilities.NormalizeDriveLetter(input)); + } } } diff --git a/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs b/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs index 3dc9fec60ed45..ef1aae7ebd9d8 100644 --- a/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs +++ b/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs @@ -35,7 +35,7 @@ namespace Microsoft.CodeAnalysis.UnitTests public sealed class InvokeUtil { - public void Exec(ITestOutputHelper testOutputHelper, AssemblyLoadContext compilerContext, AssemblyLoadTestFixture fixture, AnalyzerTestKind kind, string typeName, string methodName) + internal void Exec(ITestOutputHelper testOutputHelper, AssemblyLoadContext compilerContext, AssemblyLoadTestFixture fixture, AnalyzerTestKind kind, string typeName, string methodName, IAnalyzerAssemblyResolver[] externalResolvers) { // Ensure that the test did not load any of the test fixture assemblies into // the default load context. That should never happen. Assemblies should either @@ -48,9 +48,9 @@ public void Exec(ITestOutputHelper testOutputHelper, AssemblyLoadContext compile using var tempRoot = new TempRoot(); AnalyzerAssemblyLoader loader = kind switch { - AnalyzerTestKind.LoadDirect => new DefaultAnalyzerAssemblyLoader(compilerContext, AnalyzerLoadOption.LoadFromDisk), - AnalyzerTestKind.LoadStream => new DefaultAnalyzerAssemblyLoader(compilerContext, AnalyzerLoadOption.LoadFromStream), - AnalyzerTestKind.ShadowLoad => new ShadowCopyAnalyzerAssemblyLoader(compilerContext, tempRoot.CreateDirectory().Path), + AnalyzerTestKind.LoadDirect => new DefaultAnalyzerAssemblyLoader(compilerContext, AnalyzerLoadOption.LoadFromDisk, externalResolvers.ToImmutableArray()), + AnalyzerTestKind.LoadStream => new DefaultAnalyzerAssemblyLoader(compilerContext, AnalyzerLoadOption.LoadFromStream, externalResolvers.ToImmutableArray()), + AnalyzerTestKind.ShadowLoad => new ShadowCopyAnalyzerAssemblyLoader(compilerContext, tempRoot.CreateDirectory().Path, externalResolvers.ToImmutableArray()), _ => throw ExceptionUtilities.Unreachable() }; @@ -93,13 +93,13 @@ public void Exec(ITestOutputHelper testOutputHelper, AssemblyLoadContext compile public sealed class InvokeUtil : MarshalByRefObject { - public void Exec(ITestOutputHelper testOutputHelper, AssemblyLoadTestFixture fixture, AnalyzerTestKind kind, string typeName, string methodName) + internal void Exec(ITestOutputHelper testOutputHelper, AssemblyLoadTestFixture fixture, AnalyzerTestKind kind, string typeName, string methodName, IAnalyzerAssemblyResolver[] externalResolvers) { using var tempRoot = new TempRoot(); AnalyzerAssemblyLoader loader = kind switch { - AnalyzerTestKind.LoadDirect => new DefaultAnalyzerAssemblyLoader(), - AnalyzerTestKind.ShadowLoad => new ShadowCopyAnalyzerAssemblyLoader(tempRoot.CreateDirectory().Path), + AnalyzerTestKind.LoadDirect => new DefaultAnalyzerAssemblyLoader(externalResolvers.ToImmutableArray()), + AnalyzerTestKind.ShadowLoad => new ShadowCopyAnalyzerAssemblyLoader(tempRoot.CreateDirectory().Path, externalResolvers.ToImmutableArray()), _ => throw ExceptionUtilities.Unreachable() }; diff --git a/src/Compilers/Core/CodeAnalysisTest/Microsoft.CodeAnalysis.UnitTests.csproj b/src/Compilers/Core/CodeAnalysisTest/Microsoft.CodeAnalysis.UnitTests.csproj index e80335a1d132f..f3d038eafe202 100644 --- a/src/Compilers/Core/CodeAnalysisTest/Microsoft.CodeAnalysis.UnitTests.csproj +++ b/src/Compilers/Core/CodeAnalysisTest/Microsoft.CodeAnalysis.UnitTests.csproj @@ -5,7 +5,7 @@ Library Microsoft.CodeAnalysis.UnitTests true - $(NetRoslyn);net472 + $(NetRoslynNext);net472 diff --git a/src/Compilers/Core/Portable/CaseInsensitiveComparison.cs b/src/Compilers/Core/Portable/CaseInsensitiveComparison.cs index 5a739d0a75d40..51853095dc121 100644 --- a/src/Compilers/Core/Portable/CaseInsensitiveComparison.cs +++ b/src/Compilers/Core/Portable/CaseInsensitiveComparison.cs @@ -15,7 +15,12 @@ namespace Microsoft.CodeAnalysis /// /// Case-insensitive operations (mostly comparison) on unicode strings. /// - public static class CaseInsensitiveComparison +#if COMPILERCORE + public +#else + internal +#endif + static class CaseInsensitiveComparison { // PERF: Cache a TextInfo for Unicode ToLower since this will be accessed very frequently private static readonly TextInfo s_unicodeCultureTextInfo = GetUnicodeCulture().TextInfo; diff --git a/src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs b/src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs index 71c3b0d7f5b23..9b57ad3e7bb43 100644 --- a/src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs +++ b/src/Compilers/Core/Portable/CodeGen/SwitchIntegralJumpTableEmitter.cs @@ -194,7 +194,7 @@ private ImmutableArray GenerateSwitchBuckets(int startLabelIndex, // merge top bucket on stack into newBucket, and pop bucket from stack // End While - while (!switchBucketsStack.IsEmpty()) + while (!switchBucketsStack.IsEmpty) { // get the bucket at top of the stack SwitchBucket prevBucket = switchBucketsStack.Peek(); @@ -217,7 +217,7 @@ private ImmutableArray GenerateSwitchBuckets(int startLabelIndex, curStartLabelIndex++; } - Debug.Assert(!switchBucketsStack.IsEmpty()); + Debug.Assert(!switchBucketsStack.IsEmpty); // crumble leaf buckets into degenerate buckets where possible var crumbled = ArrayBuilder.GetInstance(); diff --git a/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs b/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs index 51ccab0fd9398..2fbb864964308 100644 --- a/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs +++ b/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs @@ -764,19 +764,6 @@ public static ImmutableArray Distinct(this ImmutableArray array, IEqual return result; } - internal static bool HasAnyErrors(this ImmutableArray diagnostics) where T : Diagnostic - { - foreach (var diagnostic in diagnostics) - { - if (diagnostic.Severity == DiagnosticSeverity.Error) - { - return true; - } - } - - return false; - } - // In DEBUG, swap the first and last elements of a read-only array, yielding a new read only array. // This helps to avoid depending on accidentally sorted arrays. internal static ImmutableArray ConditionallyDeOrder(this ImmutableArray array) @@ -1034,8 +1021,8 @@ internal static void CreateNameToMembersMap> GetTypesFromM var dictionary = new Dictionary>(capacity, comparer); - foreach (var (name, members) in map) + foreach (var entry in map) { - var namedTypes = getOrCreateNamedTypes(members); + var namedTypes = getOrCreateNamedTypes(entry.Value); if (namedTypes.Length > 0) - dictionary.Add(name, namedTypes); + dictionary.Add(entry.Key, namedTypes); } return dictionary; diff --git a/src/Compilers/Core/Portable/Collections/TemporaryArrayExtensions.cs b/src/Compilers/Core/Portable/Collections/TemporaryArrayExtensions.cs index 62ef11b4bb4d0..8efb7283e366f 100644 --- a/src/Compilers/Core/Portable/Collections/TemporaryArrayExtensions.cs +++ b/src/Compilers/Core/Portable/Collections/TemporaryArrayExtensions.cs @@ -107,6 +107,17 @@ private static void ThrowSequenceContainsMoreThanOneElement() return result; } + public static T? FirstOrDefault(this in TemporaryArray array, Func predicate, TArg arg) + { + foreach (var item in array) + { + if (predicate(item, arg)) + return item; + } + + return default; + } + public static void AddIfNotNull(this ref TemporaryArray array, T? value) where T : struct { diff --git a/src/Compilers/Core/Portable/Collections/TemporaryArray`1.cs b/src/Compilers/Core/Portable/Collections/TemporaryArray`1.cs index 72e9ac3c8196b..cb06950e4a2e3 100644 --- a/src/Compilers/Core/Portable/Collections/TemporaryArray`1.cs +++ b/src/Compilers/Core/Portable/Collections/TemporaryArray`1.cs @@ -265,11 +265,29 @@ public readonly Enumerator GetEnumerator() return new Enumerator(in this); } + /// + /// Create an with the elements currently held in the temporary array, and clear the + /// array. + /// + public OneOrMany ToOneOrManyAndClear() + { + switch (this.Count) + { + case 0: + return OneOrMany.Empty; + case 1: + var result = OneOrMany.Create(this[0]); + this.Clear(); + return result; + default: + return new(this.ToImmutableAndClear()); + } + } + /// /// Create an with the elements currently held in the temporary array, and clear /// the array. /// - /// public ImmutableArray ToImmutableAndClear() { if (_builder is not null) diff --git a/src/Compilers/Core/Portable/CommandLine/AnalyzerConfig.cs b/src/Compilers/Core/Portable/CommandLine/AnalyzerConfig.cs index c287620e679a9..46a89ceeaad0d 100644 --- a/src/Compilers/Core/Portable/CommandLine/AnalyzerConfig.cs +++ b/src/Compilers/Core/Portable/CommandLine/AnalyzerConfig.cs @@ -256,12 +256,17 @@ public static AnalyzerConfig Parse(SourceText text, string? pathToFile) // Add the last section addNewSection(); + // Normalize the path to file the same way named sections are + pathToFile = PathUtilities.NormalizeDriveLetter(pathToFile); + return new AnalyzerConfig(globalSection!, namedSectionBuilder.ToImmutable(), pathToFile); void addNewSection() { + var sectionName = PathUtilities.NormalizeDriveLetter(activeSectionName); + // Close out the previous section - var previousSection = new Section(activeSectionName, activeSectionProperties.ToImmutable()); + var previousSection = new Section(sectionName, activeSectionProperties.ToImmutable()); if (activeSectionName == "") { // This is the global section diff --git a/src/Compilers/Core/Portable/CommandLine/AnalyzerConfigSet.cs b/src/Compilers/Core/Portable/CommandLine/AnalyzerConfigSet.cs index 2296b51ec33ce..7daa31f64d97f 100644 --- a/src/Compilers/Core/Portable/CommandLine/AnalyzerConfigSet.cs +++ b/src/Compilers/Core/Portable/CommandLine/AnalyzerConfigSet.cs @@ -183,8 +183,9 @@ public AnalyzerConfigOptionsResult GetOptionsForSourcePath(string sourcePath) var sectionKey = _sectionKeyPool.Allocate(); - var normalizedPath = PathUtilities.NormalizeWithForwardSlash(sourcePath); + var normalizedPath = PathUtilities.CollapseWithForwardSlash(sourcePath.AsSpan()); normalizedPath = PathUtilities.ExpandAbsolutePathWithRelativeParts(normalizedPath); + normalizedPath = PathUtilities.NormalizeDriveLetter(normalizedPath); // If we have a global config, add any sections that match the full path. We can have at most one section since // we would have merged them earlier. diff --git a/src/Compilers/Core/Portable/InternalUtilities/NoThrowStreamDisposer.cs b/src/Compilers/Core/Portable/CommandLine/NoThrowStreamDisposer.cs similarity index 100% rename from src/Compilers/Core/Portable/InternalUtilities/NoThrowStreamDisposer.cs rename to src/Compilers/Core/Portable/CommandLine/NoThrowStreamDisposer.cs diff --git a/src/Compilers/Core/Portable/Diagnostic/DiagnosticArrayExtensions.cs b/src/Compilers/Core/Portable/Diagnostic/DiagnosticArrayExtensions.cs new file mode 100644 index 0000000000000..c22f86921e8ac --- /dev/null +++ b/src/Compilers/Core/Portable/Diagnostic/DiagnosticArrayExtensions.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Collections.Immutable; + +namespace Microsoft.CodeAnalysis; + +internal static class DiagnosticArrayExtensions +{ + internal static bool HasAnyErrors(this ImmutableArray diagnostics) where T : Diagnostic + { + foreach (var diagnostic in diagnostics) + { + if (diagnostic.Severity == DiagnosticSeverity.Error) + { + return true; + } + } + + return false; + } +} diff --git a/src/Compilers/Core/Portable/InternalUtilities/AdditionalTextComparer.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AdditionalTextComparer.cs similarity index 100% rename from src/Compilers/Core/Portable/InternalUtilities/AdditionalTextComparer.cs rename to src/Compilers/Core/Portable/DiagnosticAnalyzer/AdditionalTextComparer.cs diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Core.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Core.cs index 5e2a1d99f08dc..c18b863c37250 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Core.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Core.cs @@ -43,15 +43,16 @@ internal partial class AnalyzerAssemblyLoader internal AssemblyLoadContext CompilerLoadContext => _compilerLoadContext; internal AnalyzerLoadOption AnalyzerLoadOption => _loadOption; - internal AnalyzerAssemblyLoader() - : this(null, AnalyzerLoadOption.LoadFromDisk) + internal AnalyzerAssemblyLoader(ImmutableArray externalResolvers) + : this(null, AnalyzerLoadOption.LoadFromDisk, externalResolvers) { } - internal AnalyzerAssemblyLoader(AssemblyLoadContext? compilerLoadContext, AnalyzerLoadOption loadOption) + internal AnalyzerAssemblyLoader(AssemblyLoadContext? compilerLoadContext, AnalyzerLoadOption loadOption, ImmutableArray externalResolvers) { _loadOption = loadOption; _compilerLoadContext = compilerLoadContext ?? AssemblyLoadContext.GetLoadContext(typeof(AnalyzerAssemblyLoader).GetTypeInfo().Assembly)!; + _externalResolvers = [.. externalResolvers, new CompilerAnalyzerAssemblyResolver(_compilerLoadContext)]; } public bool IsHostAssembly(Assembly assembly) @@ -69,7 +70,7 @@ private partial Assembly Load(AssemblyName assemblyName, string assemblyOriginal { if (!_loadContextByDirectory.TryGetValue(fullDirectoryPath, out loadContext)) { - loadContext = new DirectoryLoadContext(fullDirectoryPath, this, _compilerLoadContext); + loadContext = new DirectoryLoadContext(fullDirectoryPath, this); _loadContextByDirectory[fullDirectoryPath] = loadContext; } } @@ -107,33 +108,23 @@ internal sealed class DirectoryLoadContext : AssemblyLoadContext { internal string Directory { get; } private readonly AnalyzerAssemblyLoader _loader; - private readonly AssemblyLoadContext _compilerLoadContext; - public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader, AssemblyLoadContext compilerLoadContext) + public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader) : base(isCollectible: true) { Directory = directory; _loader = loader; - _compilerLoadContext = compilerLoadContext; } protected override Assembly? Load(AssemblyName assemblyName) { - var simpleName = assemblyName.Name!; - try + if (_loader.ResolveAssemblyExternally(assemblyName) is { } externallyResolvedAssembly) { - if (_compilerLoadContext.LoadFromAssemblyName(assemblyName) is { } compilerAssembly) - { - return compilerAssembly; - } - } - catch - { - // Expected to happen when the assembly cannot be resolved in the compiler / host - // AssemblyLoadContext. + return externallyResolvedAssembly; } // Prefer registered dependencies in the same directory first. + var simpleName = assemblyName.Name!; var assemblyPath = Path.Combine(Directory, simpleName + ".dll"); if (_loader.IsAnalyzerDependencyPath(assemblyPath)) { @@ -147,7 +138,7 @@ public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader, Ass // Note: when loading from disk the .NET runtime has a fallback step that will handle // satellite assembly loading if the call to Load(satelliteAssemblyName) fails. This // loader has a mode where it loads from Stream though and the runtime will not handle - // that automatically. Rather than bifurate our loading behavior between Disk and + // that automatically. Rather than bifurcate our loading behavior between Disk and // Stream both modes just handle satellite loading directly if (assemblyName.CultureInfo is not null && simpleName.EndsWith(".resources", StringComparison.Ordinal)) { @@ -201,6 +192,27 @@ protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) return IntPtr.Zero; } } + + /// + /// A resolver which allows a passed in from the compiler + /// to control assembly resolution. This is important because there are many exchange types + /// that need to unify across the multiple analyzer ALCs. These include common types from + /// Microsoft.CodeAnalysis.dll etc, as well as platform assemblies provided by a + /// host such as visual studio. + /// + /// + /// This resolver essentially forces any assembly that was loaded as a 'core' part of the + /// compiler to be shared across analyzers, and not loaded multiple times into each individual + /// analyzer ALC, even if the analyzer itself shipped a copy of said assembly. + /// + /// The that the core + /// compiler assemblies are already loaded into. + internal sealed class CompilerAnalyzerAssemblyResolver(AssemblyLoadContext compilerContext) : IAnalyzerAssemblyResolver + { + private readonly AssemblyLoadContext _compilerAlc = compilerContext; + + public Assembly? ResolveAssembly(AssemblyName assemblyName) => _compilerAlc.LoadFromAssemblyName(assemblyName); + } } } diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Desktop.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Desktop.cs index b4d000e335a9d..75d6271100354 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Desktop.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.Desktop.cs @@ -5,6 +5,7 @@ #if !NETCOREAPP using System; +using System.Collections.Immutable; using System.Globalization; using System.IO; using System.Reflection; @@ -28,8 +29,9 @@ internal partial class AnalyzerAssemblyLoader { private bool _hookedAssemblyResolve; - internal AnalyzerAssemblyLoader() + internal AnalyzerAssemblyLoader(ImmutableArray externalResolvers) { + _externalResolvers = externalResolvers; } public bool IsHostAssembly(Assembly assembly) @@ -57,6 +59,10 @@ public bool IsHostAssembly(Assembly assembly) private partial Assembly? Load(AssemblyName assemblyName, string assemblyOriginalPath) { EnsureResolvedHooked(); + if (ResolveAssemblyExternally(assemblyName) is { } externallyResolvedAssembly) + { + return externallyResolvedAssembly; + } return AppDomain.CurrentDomain.Load(assemblyName); } diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs index 6ec884ede8396..9b35df57eee87 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerAssemblyLoader.cs @@ -20,6 +20,13 @@ internal interface IAnalyzerAssemblyLoaderInternal : IAnalyzerAssemblyLoader /// process. Either part of the compiler itself or the process hosting the compiler. /// bool IsHostAssembly(Assembly assembly); + + /// + /// For a given return the location it was originally added + /// from. This will return null for any value that was not directly added through the + /// loader. + /// + string? GetOriginalDependencyLocation(AssemblyName assembly); } /// @@ -61,6 +68,14 @@ internal abstract partial class AnalyzerAssemblyLoader : IAnalyzerAssemblyLoader /// private readonly Dictionary> _knownAssemblyPathsBySimpleName = new(StringComparer.OrdinalIgnoreCase); + /// + /// A collection of s that can be used to override the assembly resolution process. + /// + /// + /// When multiple resolvers are present they are consulted in-order, with the first resolver to return a non-null + /// winning. + private readonly ImmutableArray _externalResolvers; + /// /// The implementation needs to load an with the specified . The /// parameter is the original path. It may be different than @@ -235,6 +250,9 @@ public Assembly LoadFromPath(string originalAnalyzerPath) } } + public string? GetOriginalDependencyLocation(AssemblyName assemblyName) => + GetBestPath(assemblyName).BestOriginalPath; + /// /// Return the best (original, real) path information for loading an assembly with the specified . /// @@ -330,5 +348,33 @@ internal string GetRealAnalyzerLoadPath(string originalFullPath) .ToArray(); } } + + /// + /// Iterates the if any, to see if any of them can resolve + /// the given to an . + /// + /// The name of the assembly to resolve + /// An if one of the resolvers is successful, or + internal Assembly? ResolveAssemblyExternally(AssemblyName assemblyName) + { + if (!_externalResolvers.IsDefaultOrEmpty) + { + foreach (var resolver in _externalResolvers) + { + try + { + if (resolver.ResolveAssembly(assemblyName) is { } resolvedAssembly) + { + return resolvedAssembly; + } + } + catch + { + // Ignore if the external resolver throws + } + } + } + return null; + } } } diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/DefaultAnalyzerAssemblyLoader.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/DefaultAnalyzerAssemblyLoader.cs index 624768168d521..b6233d02a6d36 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/DefaultAnalyzerAssemblyLoader.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/DefaultAnalyzerAssemblyLoader.cs @@ -17,13 +17,19 @@ namespace Microsoft.CodeAnalysis internal sealed class DefaultAnalyzerAssemblyLoader : AnalyzerAssemblyLoader { internal DefaultAnalyzerAssemblyLoader() + : base([]) + { + } + + internal DefaultAnalyzerAssemblyLoader(ImmutableArray externalResolvers) + : base(externalResolvers) { } #if NETCOREAPP - internal DefaultAnalyzerAssemblyLoader(System.Runtime.Loader.AssemblyLoadContext? compilerLoadContext = null, AnalyzerLoadOption loadOption = AnalyzerLoadOption.LoadFromDisk) - : base(compilerLoadContext, loadOption) + internal DefaultAnalyzerAssemblyLoader(System.Runtime.Loader.AssemblyLoadContext? compilerLoadContext = null, AnalyzerLoadOption loadOption = AnalyzerLoadOption.LoadFromDisk, ImmutableArray? externalResolvers = null) + : base(compilerLoadContext, loadOption, externalResolvers ?? []) { } @@ -51,12 +57,12 @@ protected override string PrepareSatelliteAssemblyToLoad(string assemblyFilePath /// /// A shadow copy path will be created on Windows and this value /// will be the base directory where shadow copy assemblies are stored. - internal static IAnalyzerAssemblyLoaderInternal CreateNonLockingLoader(string windowsShadowPath) + internal static IAnalyzerAssemblyLoaderInternal CreateNonLockingLoader(string windowsShadowPath, ImmutableArray? externalResolvers = null) { #if NETCOREAPP if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - return new DefaultAnalyzerAssemblyLoader(loadOption: AnalyzerLoadOption.LoadFromStream); + return new DefaultAnalyzerAssemblyLoader(loadOption: AnalyzerLoadOption.LoadFromStream, externalResolvers: externalResolvers); } #endif @@ -68,7 +74,7 @@ internal static IAnalyzerAssemblyLoaderInternal CreateNonLockingLoader(string wi throw new ArgumentException("Must be a full path.", nameof(windowsShadowPath)); } - return new ShadowCopyAnalyzerAssemblyLoader(windowsShadowPath); + return new ShadowCopyAnalyzerAssemblyLoader(windowsShadowPath, externalResolvers); } } } diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/IAnalyzerAssemblyResolver.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/IAnalyzerAssemblyResolver.cs new file mode 100644 index 0000000000000..b6bf2b029de28 --- /dev/null +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/IAnalyzerAssemblyResolver.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Reflection; + +namespace Microsoft.CodeAnalysis +{ + /// + /// Allows a host to override how assembly resolution is performed by the . + /// + internal interface IAnalyzerAssemblyResolver + { + /// + /// Attempts to resolve an assembly by name. + /// + /// The assembly to resolve + /// The resolved assembly, or + Assembly? ResolveAssembly(AssemblyName assemblyName); + } +} diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/ShadowCopyAnalyzerAssemblyLoader.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/ShadowCopyAnalyzerAssemblyLoader.cs index 40592947a8ac4..9cc9ed5b29a33 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/ShadowCopyAnalyzerAssemblyLoader.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/ShadowCopyAnalyzerAssemblyLoader.cs @@ -9,6 +9,8 @@ using System.Threading; using System.Threading.Tasks; using Roslyn.Utilities; +using System.Collections.Immutable; +using System.Reflection; #if NETCOREAPP using System.Runtime.Loader; @@ -42,15 +44,16 @@ internal sealed class ShadowCopyAnalyzerAssemblyLoader : AnalyzerAssemblyLoader internal int CopyCount => _mvidPathMap.Count; #if NETCOREAPP - public ShadowCopyAnalyzerAssemblyLoader(string baseDirectory) - : this(null, baseDirectory) + public ShadowCopyAnalyzerAssemblyLoader(string baseDirectory, ImmutableArray? externalResolvers = null) + : this(null, baseDirectory, externalResolvers) { } - public ShadowCopyAnalyzerAssemblyLoader(AssemblyLoadContext? compilerLoadContext, string baseDirectory) - : base(compilerLoadContext, AnalyzerLoadOption.LoadFromDisk) + public ShadowCopyAnalyzerAssemblyLoader(AssemblyLoadContext? compilerLoadContext, string baseDirectory, ImmutableArray? externalResolvers = null) + : base(compilerLoadContext, AnalyzerLoadOption.LoadFromDisk, externalResolvers ?? []) #else - public ShadowCopyAnalyzerAssemblyLoader(string baseDirectory) + public ShadowCopyAnalyzerAssemblyLoader(string baseDirectory, ImmutableArray? externalResolvers = null) + : base(externalResolvers ?? []) #endif { if (baseDirectory is null) diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinue/DeletedSourceGenericParameter.cs b/src/Compilers/Core/Portable/Emit/EditAndContinue/DeletedSourceGenericParameter.cs index 8ed894662a4de..76d5fd31f9dd1 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinue/DeletedSourceGenericParameter.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinue/DeletedSourceGenericParameter.cs @@ -26,6 +26,8 @@ public DeletedSourceGenericParameter(IGenericMethodParameter oldParameter, Delet public bool MustBeValueType => OldDefinition.MustBeValueType; + public bool AllowsRefLikeType => OldDefinition.AllowsRefLikeType; + public bool MustHaveDefaultConstructor => OldDefinition.MustHaveDefaultConstructor; public TypeParameterVariance Variance => OldDefinition.Variance; diff --git a/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedTypeParameter.cs b/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedTypeParameter.cs index a3f39d6dbcdb3..1898e994606ea 100644 --- a/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedTypeParameter.cs +++ b/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedTypeParameter.cs @@ -52,6 +52,7 @@ public bool IsEncDeleted protected abstract IEnumerable GetConstraints(EmitContext context); protected abstract bool MustBeReferenceType { get; } protected abstract bool MustBeValueType { get; } + protected abstract bool AllowsRefLikeType { get; } protected abstract bool MustHaveDefaultConstructor { get; } protected abstract string Name { get; } protected abstract ushort Index { get; } @@ -85,6 +86,14 @@ bool Cci.IGenericParameter.MustBeValueType } } + bool Cci.IGenericParameter.AllowsRefLikeType + { + get + { + return AllowsRefLikeType; + } + } + bool Cci.IGenericParameter.MustHaveDefaultConstructor { get diff --git a/src/Compilers/Core/Portable/EncodedStringText.cs b/src/Compilers/Core/Portable/EncodedStringText.cs index 71ddfe9c398b0..61fa6f128e688 100644 --- a/src/Compilers/Core/Portable/EncodedStringText.cs +++ b/src/Compilers/Core/Portable/EncodedStringText.cs @@ -139,7 +139,7 @@ private static SourceText Decode( data.Seek(0, SeekOrigin.Begin); // For small streams, see if we can read the byte buffer directly. - if (encoding.GetMaxCharCountOrThrowIfHuge(data) < LargeObjectHeapLimitInChars) + if (encoding.TryGetMaxCharCount(data.Length, out int maxCharCount) && maxCharCount < LargeObjectHeapLimitInChars) { if (TryGetBytesFromStream(data, out ArraySegment bytes) && bytes.Offset == 0 && bytes.Array is object) { diff --git a/src/Compilers/Core/Portable/FileSystem/PathUtilities.cs b/src/Compilers/Core/Portable/FileSystem/PathUtilities.cs index 570121ad3d3bb..715d35d3e1663 100644 --- a/src/Compilers/Core/Portable/FileSystem/PathUtilities.cs +++ b/src/Compilers/Core/Portable/FileSystem/PathUtilities.cs @@ -9,6 +9,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.PooledObjects; @@ -734,6 +735,16 @@ public static string NormalizePathPrefix(string filePath, ImmutableArray /// Unfortunately, we cannot depend on Path.GetInvalidPathChars() or Path.GetInvalidFileNameChars() /// From MSDN: The array returned from this method is not guaranteed to contain the complete set of characters @@ -780,6 +791,42 @@ public static bool IsValidFilePath([NotNullWhen(true)] string? fullPath) public static string NormalizeWithForwardSlash(string p) => DirectorySeparatorChar == '/' ? p : p.Replace(DirectorySeparatorChar, '/'); + /// + /// Replaces all sequences of '\' or '/' with a single '/' but preserves UNC prefix '//'. + /// + public static string CollapseWithForwardSlash(ReadOnlySpan path) + { + var sb = new StringBuilder(path.Length); + + int start = 0; + if (path.Length > 1 && IsAnyDirectorySeparator(path[0]) && IsAnyDirectorySeparator(path[1])) + { + // Preserve UNC paths. + sb.Append("//"); + start = 2; + } + + bool wasDirectorySeparator = false; + for (int i = start; i < path.Length; i++) + { + if (IsAnyDirectorySeparator(path[i])) + { + if (!wasDirectorySeparator) + { + sb.Append('/'); + } + wasDirectorySeparator = true; + } + else + { + sb.Append(path[i]); + wasDirectorySeparator = false; + } + } + + return sb.ToString(); + } + /// /// Takes an absolute path and attempts to expand any '..' or '.' into their equivalent representation. /// diff --git a/src/Compilers/Core/Portable/InternalUtilities/EncodingExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/EncodingExtensions.cs index 799070e325d4a..91acd015a8eb6 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/EncodingExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/EncodingExtensions.cs @@ -2,39 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis; using System; -using System.Diagnostics; -using System.IO; using System.Text; namespace Microsoft.CodeAnalysis { internal static partial class EncodingExtensions { - /// - /// Get maximum char count needed to decode the entire stream. - /// - /// Stream is so big that max char count can't fit in . - internal static int GetMaxCharCountOrThrowIfHuge(this Encoding encoding, Stream stream) - { - Debug.Assert(stream.CanSeek); - long length = stream.Length; - - if (encoding.TryGetMaxCharCount(length, out int maxCharCount)) - { - return maxCharCount; - } - -#if CODE_STYLE - throw new IOException(CodeStyleResources.Stream_is_too_long); -#elif WORKSPACE - throw new IOException(WorkspacesResources.Stream_is_too_long); -#else - throw new IOException(CodeAnalysisResources.StreamIsTooLong); -#endif - } - internal static bool TryGetMaxCharCount(this Encoding encoding, long length, out int maxCharCount) { maxCharCount = 0; diff --git a/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs b/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs index 8e0d40e161b1c..a39b43bf02f2b 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/EnumUtilties.cs @@ -11,45 +11,6 @@ namespace Roslyn.Utilities { internal static class EnumUtilities { - /// - /// Convert a boxed primitive (generally of the backing type of an enum) into a ulong. - /// - /// - /// - internal static ulong ConvertEnumUnderlyingTypeToUInt64(object value, SpecialType specialType) - { - RoslynDebug.Assert(value != null); - Debug.Assert(value.GetType().GetTypeInfo().IsPrimitive); - - unchecked - { - switch (specialType) - { - case SpecialType.System_SByte: - return (ulong)(sbyte)value; - case SpecialType.System_Int16: - return (ulong)(short)value; - case SpecialType.System_Int32: - return (ulong)(int)value; - case SpecialType.System_Int64: - return (ulong)(long)value; - case SpecialType.System_Byte: - return (byte)value; - case SpecialType.System_UInt16: - return (ushort)value; - case SpecialType.System_UInt32: - return (uint)value; - case SpecialType.System_UInt64: - return (ulong)value; - - default: - // not using ExceptionUtilities.UnexpectedValue() because this is used by the Services layer - // which doesn't have those utilities. - throw new InvalidOperationException(string.Format("{0} is not a valid underlying type for an enum", specialType)); - } - } - } - internal static T[] GetValues() where T : struct { return (T[])Enum.GetValues(typeof(T)); diff --git a/src/Compilers/Core/Portable/InternalUtilities/RoslynExperiments.cs b/src/Compilers/Core/Portable/InternalUtilities/RoslynExperiments.cs index 75e810ab03512..47827c416f072 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/RoslynExperiments.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/RoslynExperiments.cs @@ -14,4 +14,7 @@ internal static class RoslynExperiments internal const string Interceptors = "RSEXPERIMENTAL002"; internal const string Interceptors_Url = "https://github.com/dotnet/csharplang/issues/7009"; + + internal const string SyntaxTokenParser = "RSEXPERIMENTAL003"; + internal const string SyntaxTokenParser_Url = "https://github.com/dotnet/roslyn/issues/73002"; } diff --git a/src/Compilers/Core/Portable/InternalUtilities/StringTable.cs b/src/Compilers/Core/Portable/InternalUtilities/StringTable.cs index ae51191090a91..6d7bea21b1829 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/StringTable.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/StringTable.cs @@ -6,7 +6,7 @@ using System.Text; using System.Threading; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Collections; #if DEBUG using System.Diagnostics; @@ -63,7 +63,7 @@ private struct Entry // slightly slower than local cache // we read this cache when having a miss in local cache // writes to local cache will update shared cache as well. - private static readonly Entry[] s_sharedTable = new Entry[SharedSize]; + private static readonly SegmentedArray s_sharedTable = new SegmentedArray(SharedSize); // essentially a random number // the usage pattern will randomly use and increment this diff --git a/src/Compilers/Core/Portable/InternalUtilities/TextKeyedCache.cs b/src/Compilers/Core/Portable/InternalUtilities/TextKeyedCache.cs index 9164416313002..b1cafb1babf32 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/TextKeyedCache.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/TextKeyedCache.cs @@ -3,16 +3,8 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; using System.Threading; +using Microsoft.CodeAnalysis.PooledObjects; namespace Roslyn.Utilities { diff --git a/src/Compilers/Core/Portable/MetadataReader/MetadataHelpers.cs b/src/Compilers/Core/Portable/MetadataReader/MetadataHelpers.cs index c940072347ad8..29c428581833d 100644 --- a/src/Compilers/Core/Portable/MetadataReader/MetadataHelpers.cs +++ b/src/Compilers/Core/Portable/MetadataReader/MetadataHelpers.cs @@ -20,6 +20,11 @@ namespace Microsoft.CodeAnalysis { internal static class MetadataHelpers { + // https://github.com/dotnet/roslyn/issues/73548: + // Remove this constant and refer to GenericParameterAttributes.AllowByRefLike directly once the new enum member becomes available. + // See // https://github.com/dotnet/runtime/issues/68002#issuecomment-1942166436 for more details. + public const System.Reflection.GenericParameterAttributes GenericParameterAttributesAllowByRefLike = (System.Reflection.GenericParameterAttributes)0x0020; + public const char DotDelimiter = '.'; public const string DotDelimiterString = "."; public const char GenericTypeNameManglingChar = '`'; diff --git a/src/Compilers/Core/Portable/InternalUtilities/AssemblyIdentityUtils.cs b/src/Compilers/Core/Portable/MetadataReference/AssemblyIdentityUtils.cs similarity index 100% rename from src/Compilers/Core/Portable/InternalUtilities/AssemblyIdentityUtils.cs rename to src/Compilers/Core/Portable/MetadataReference/AssemblyIdentityUtils.cs diff --git a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs index 43c5435d0d2d7..1d16642e7b7f9 100644 --- a/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs +++ b/src/Compilers/Core/Portable/Operations/ControlFlowGraphBuilder.cs @@ -4106,6 +4106,7 @@ void processResource(IOperation resource, ArrayBuilder<(IVariableDeclarationOper private void AddDisposingFinally(IOperation resource, bool requiresRuntimeConversion, ITypeSymbol iDisposable, IMethodSymbol? disposeMethod, ImmutableArray disposeArguments, bool isAsynchronous) { Debug.Assert(CurrentRegionRequired.Kind == ControlFlowRegionKind.TryAndFinally); + Debug.Assert(resource.Type is not null); var endOfFinally = new BasicBlockBuilder(BasicBlockKind.Block); endOfFinally.FallThrough.Kind = ControlFlowBranchSemantics.StructuredExceptionHandling; @@ -4121,6 +4122,7 @@ private void AddDisposingFinally(IOperation resource, bool requiresRuntimeConver int captureId = GetNextCaptureId(finallyRegion); AddStatement(new FlowCaptureOperation(captureId, resource.Syntax, resource)); resource = GetCaptureReference(captureId, resource); + Debug.Assert(resource.Type is not null); } if (requiresRuntimeConversion || !isNotNullableValueType(resource.Type)) @@ -4132,7 +4134,14 @@ private void AddDisposingFinally(IOperation resource, bool requiresRuntimeConver if (!iDisposable.Equals(resource.Type) && disposeMethod is null) { - resource = ConvertToIDisposable(resource, iDisposable); + if (resource.Type.IsReferenceType) + { + resource = ConvertToIDisposable(resource, iDisposable); + } + else if (ITypeSymbolHelpers.IsNullableType(resource.Type)) + { + resource = CallNullableMember(resource, SpecialMember.System_Nullable_T_GetValueOrDefault); + } } EvalStackFrame disposeFrame = PushStackFrame(); @@ -4150,7 +4159,8 @@ private void AddDisposingFinally(IOperation resource, bool requiresRuntimeConver IOperation? tryDispose(IOperation value) { - Debug.Assert((disposeMethod is object && !disposeArguments.IsDefault) || (value.Type!.Equals(iDisposable) && disposeArguments.IsDefaultOrEmpty)); + Debug.Assert((disposeMethod is object && !disposeArguments.IsDefault) || + ((value.Type!.Equals(iDisposable) || (!value.Type.IsReferenceType && !ITypeSymbolHelpers.IsNullableType(value.Type))) && disposeArguments.IsDefaultOrEmpty)); var method = disposeMethod ?? (isAsynchronous ? (IMethodSymbol?)_compilation.CommonGetWellKnownTypeMember(WellKnownMember.System_IAsyncDisposable__DisposeAsync)?.GetISymbol() @@ -4170,7 +4180,7 @@ private void AddDisposingFinally(IOperation resource, bool requiresRuntimeConver args = ImmutableArray.Empty; } - var invocation = new InvocationOperation(method, constrainedToType: null, value, isVirtual: disposeMethod?.IsVirtual ?? true, + var invocation = new InvocationOperation(method, constrainedToType: null, value, isVirtual: disposeMethod is (null or { IsVirtual: true } or { IsAbstract: true }), args, semanticModel: null, value.Syntax, method.ReturnType, isImplicit: true); diff --git a/src/Compilers/Core/Portable/PEWriter/InheritedTypeParameter.cs b/src/Compilers/Core/Portable/PEWriter/InheritedTypeParameter.cs index fc67f52c55cee..a988641b3ca32 100644 --- a/src/Compilers/Core/Portable/PEWriter/InheritedTypeParameter.cs +++ b/src/Compilers/Core/Portable/PEWriter/InheritedTypeParameter.cs @@ -49,6 +49,11 @@ public bool MustBeValueType get { return _parentParameter.MustBeValueType; } } + public bool AllowsRefLikeType + { + get { return _parentParameter.AllowsRefLikeType; } + } + public bool MustHaveDefaultConstructor { get { return _parentParameter.MustHaveDefaultConstructor; } diff --git a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs index e3791fc94ce01..1efe1c74d0602 100644 --- a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs +++ b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs @@ -876,6 +876,11 @@ private static GenericParameterAttributes GetGenericParameterAttributes(IGeneric result |= GenericParameterAttributes.NotNullableValueTypeConstraint; } + if (genPar.AllowsRefLikeType) + { + result |= MetadataHelpers.GenericParameterAttributesAllowByRefLike; + } + if (genPar.MustHaveDefaultConstructor) { result |= GenericParameterAttributes.DefaultConstructorConstraint; diff --git a/src/Compilers/Core/Portable/PEWriter/Types.cs b/src/Compilers/Core/Portable/PEWriter/Types.cs index 9e907240b654e..4a842e9521f60 100644 --- a/src/Compilers/Core/Portable/PEWriter/Types.cs +++ b/src/Compilers/Core/Portable/PEWriter/Types.cs @@ -151,6 +151,11 @@ bool MustBeValueType // ^ ensures result ==> !this.MustBeReferenceType; } + bool AllowsRefLikeType + { + get; + } + /// /// True if all type arguments matching this parameter are constrained to be value types or concrete classes with visible default constructors. /// diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index e5fe82d74f013..2168ea24ba522 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -57,3 +57,5 @@ static Microsoft.CodeAnalysis.DocumentationCommentId.CreateDeclarationId(Microso [RSEXPERIMENTAL001]Microsoft.CodeAnalysis.SemanticModelOptions.DisableNullableAnalysis = 2 -> Microsoft.CodeAnalysis.SemanticModelOptions [RSEXPERIMENTAL001]Microsoft.CodeAnalysis.Compilation.GetSemanticModel(Microsoft.CodeAnalysis.SyntaxTree! syntaxTree, Microsoft.CodeAnalysis.SemanticModelOptions options) -> Microsoft.CodeAnalysis.SemanticModel! abstract Microsoft.CodeAnalysis.SemanticModel.NullableAnalysisIsDisabled.get -> bool +Microsoft.CodeAnalysis.ITypeParameterSymbol.AllowsRefLikeType.get -> bool +Microsoft.CodeAnalysis.RuntimeCapability.ByRefLikeGenerics = 8 -> Microsoft.CodeAnalysis.RuntimeCapability diff --git a/src/Compilers/Core/Portable/RuntimeCapability.cs b/src/Compilers/Core/Portable/RuntimeCapability.cs index b1502cff4867c..21bb31cc1b23e 100644 --- a/src/Compilers/Core/Portable/RuntimeCapability.cs +++ b/src/Compilers/Core/Portable/RuntimeCapability.cs @@ -43,6 +43,11 @@ public enum RuntimeCapability /// /// Indicates that this version of runtime supports inline array types. /// - InlineArrayTypes = 7 + InlineArrayTypes = 7, + + /// + /// Indicates that this version of runtime supports generic type parameters allowing substitution with a ref struct. + /// + ByRefLikeGenerics = 8, } } diff --git a/src/Compilers/Core/Portable/InternalUtilities/GeneratedCodeUtilities.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratedCodeUtilities.cs similarity index 100% rename from src/Compilers/Core/Portable/InternalUtilities/GeneratedCodeUtilities.cs rename to src/Compilers/Core/Portable/SourceGeneration/GeneratedCodeUtilities.cs diff --git a/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs b/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs index e51c2e58e7320..907119830a76f 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/Nodes/SyntaxValueProvider_ForAttributeWithSimpleName.cs @@ -205,9 +205,8 @@ void processCompilationOrNamespaceMembers(SyntaxNode node) foreach (var child in node.ChildNodesAndTokens()) { - if (child.IsNode) + if (child.AsNode(out var childNode)) { - var childNode = child.AsNode()!; if (syntaxHelper.IsAnyNamespaceBlock(childNode)) processNamespaceBlock(childNode); else @@ -283,8 +282,8 @@ void processMember(SyntaxNode member) // means having to dive deep into statements and expressions. foreach (var child in node.ChildNodesAndTokens().Reverse()) { - if (child.IsNode) - nodeStack.Push(child.AsNode()!); + if (child.AsNode(out var childNode)) + nodeStack.Push(childNode); } } diff --git a/src/Compilers/Core/Portable/SpecialMember.cs b/src/Compilers/Core/Portable/SpecialMember.cs index 639018f55b7c9..d0448904afae2 100644 --- a/src/Compilers/Core/Portable/SpecialMember.cs +++ b/src/Compilers/Core/Portable/SpecialMember.cs @@ -164,6 +164,7 @@ internal enum SpecialMember System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces, System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr, System_Runtime_CompilerServices_RuntimeFeature__ByRefFields, + System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics, System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor, System_Runtime_CompilerServices_InlineArrayAttribute__ctor, diff --git a/src/Compilers/Core/Portable/SpecialMembers.cs b/src/Compilers/Core/Portable/SpecialMembers.cs index 887f7aa8f6960..227d60d38cf33 100644 --- a/src/Compilers/Core/Portable/SpecialMembers.cs +++ b/src/Compilers/Core/Portable/SpecialMembers.cs @@ -1135,6 +1135,12 @@ static SpecialMembers() 0, // Arity (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, // Field Signature + // System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics + (byte)(MemberFlags.Field | MemberFlags.Static), // Flags + (byte)SpecialType.System_Runtime_CompilerServices_RuntimeFeature, // DeclaringTypeId + 0, // Arity + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, // Field Signature + // System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor (byte)MemberFlags.Constructor, // Flags (byte)SpecialType.System_Runtime_CompilerServices_PreserveBaseOverridesAttribute, // DeclaringTypeId @@ -1445,6 +1451,7 @@ static SpecialMembers() "VirtualStaticsInInterfaces", // System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces "NumericIntPtr", // System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr "ByRefFields", // System_Runtime_CompilerServices_RuntimeFeature__ByRefFields + "ByRefLikeGenerics", // System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics ".ctor", // System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor ".ctor", // System_Runtime_CompilerServices_InlineArrayAttribute__ctor ".ctor", // System_ReadOnlySpan_T__ctor_Reference diff --git a/src/Compilers/Core/Portable/SpecialTypeExtensions.cs b/src/Compilers/Core/Portable/SpecialTypeExtensions.cs index 553126db2e869..93d075bf02263 100644 --- a/src/Compilers/Core/Portable/SpecialTypeExtensions.cs +++ b/src/Compilers/Core/Portable/SpecialTypeExtensions.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis @@ -364,5 +365,31 @@ public static SpecialType FromRuntimeTypeOfLiteralValue(object value) /// public static bool CanOptimizeBehavior(this SpecialType specialType) => specialType is >= SpecialType.System_Object and <= SpecialType.System_Runtime_CompilerServices_InlineArrayAttribute; + + /// + /// Convert a boxed primitive (generally of the backing type of an enum) into a ulong. + /// + internal static ulong ConvertUnderlyingValueToUInt64(this SpecialType enumUnderlyingType, object value) + { + RoslynDebug.Assert(value != null); + Debug.Assert(value.GetType().IsPrimitive); + + unchecked + { + return enumUnderlyingType switch + { + SpecialType.System_SByte => (ulong)(sbyte)value, + SpecialType.System_Int16 => (ulong)(short)value, + SpecialType.System_Int32 => (ulong)(int)value, + SpecialType.System_Int64 => (ulong)(long)value, + SpecialType.System_Byte => (byte)value, + SpecialType.System_UInt16 => (ushort)value, + SpecialType.System_UInt32 => (uint)value, + SpecialType.System_UInt64 => (ulong)value, + _ => throw ExceptionUtilities.UnexpectedValue(enumUnderlyingType), + }; + } + } + } } diff --git a/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs b/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs index bb75846ec1e50..34c2c27a48c1f 100644 --- a/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs +++ b/src/Compilers/Core/Portable/SymbolDisplay/AbstractSymbolDisplayVisitor.cs @@ -235,7 +235,7 @@ private void AddFlagsEnumConstantValue( { Debug.Assert(enumType.EnumUnderlyingType is not null); var underlyingSpecialType = enumType.EnumUnderlyingType.SpecialType; - var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType); + var constantValueULong = underlyingSpecialType.ConvertUnderlyingValueToUInt64(constantValue); var result = constantValueULong; @@ -321,7 +321,7 @@ private static void GetSortedEnumFields( var field = (IFieldSymbol)member; if (field.HasConstantValue) { - var enumField = new EnumField(field.Name, EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(field.ConstantValue, underlyingSpecialType), field); + var enumField = new EnumField(field.Name, underlyingSpecialType.ConvertUnderlyingValueToUInt64(field.ConstantValue), field); enumFields.Add(enumField); } } @@ -334,7 +334,7 @@ private void AddNonFlagsEnumConstantValue(INamedTypeSymbol enumType, object cons { Debug.Assert(enumType.EnumUnderlyingType is not null); var underlyingSpecialType = enumType.EnumUnderlyingType.SpecialType; - var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType); + var constantValueULong = underlyingSpecialType.ConvertUnderlyingValueToUInt64(constantValue); var enumFields = ArrayBuilder.GetInstance(); GetSortedEnumFields(enumType, enumFields); diff --git a/src/Compilers/Core/Portable/Symbols/ITypeParameterSymbol.cs b/src/Compilers/Core/Portable/Symbols/ITypeParameterSymbol.cs index 1ee93e8b5d76e..c3639ede53e8f 100644 --- a/src/Compilers/Core/Portable/Symbols/ITypeParameterSymbol.cs +++ b/src/Compilers/Core/Portable/Symbols/ITypeParameterSymbol.cs @@ -59,6 +59,11 @@ public interface ITypeParameterSymbol : ITypeSymbol /// bool HasValueTypeConstraint { get; } + /// + /// True if the 'allows ref struct' constraint was specified for the type parameter. + /// + bool AllowsRefLikeType { get; } + /// /// True if the value type constraint (unmanaged) was specified for the type parameter. /// diff --git a/src/Compilers/Core/Portable/Symbols/LanguageNames.cs b/src/Compilers/Core/Portable/Symbols/LanguageNames.cs index e69fb57e6d8cd..485be822a4643 100644 --- a/src/Compilers/Core/Portable/Symbols/LanguageNames.cs +++ b/src/Compilers/Core/Portable/Symbols/LanguageNames.cs @@ -7,7 +7,12 @@ namespace Microsoft.CodeAnalysis /// /// A class that provides constants for common language names. /// - public static class LanguageNames +#if COMPILERCORE + public +#else + internal +#endif + static class LanguageNames { /// /// The common name used for the C# language. diff --git a/src/Compilers/Core/Portable/Syntax/SyntaxNode.cs b/src/Compilers/Core/Portable/Syntax/SyntaxNode.cs index ba5ab7ed1b3dc..dc8bddd5e1dc0 100644 --- a/src/Compilers/Core/Portable/Syntax/SyntaxNode.cs +++ b/src/Compilers/Core/Portable/Syntax/SyntaxNode.cs @@ -325,9 +325,9 @@ public virtual void WriteTo(TextWriter writer) /// is not supported. public SourceText GetText(Encoding? encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithm.Sha1) { - var builder = new StringBuilder(this.Green.FullWidth); - this.WriteTo(new StringWriter(builder)); - return new StringBuilderText(builder, encoding, checksumAlgorithm); + var writer = SourceTextWriter.Create(encoding, checksumAlgorithm, this.Green.FullWidth); + this.WriteTo(writer); + return writer.ToSourceText(); } /// diff --git a/src/Compilers/Core/Portable/Text/LargeText.cs b/src/Compilers/Core/Portable/Text/LargeText.cs index 293623460eaef..9fc77a99eb920 100644 --- a/src/Compilers/Core/Portable/Text/LargeText.cs +++ b/src/Compilers/Core/Portable/Text/LargeText.cs @@ -62,7 +62,7 @@ internal static SourceText Decode(Stream stream, Encoding encoding, SourceHashAl return SourceText.From(string.Empty, encoding, checksumAlgorithm); } - var maxCharRemainingGuess = encoding.GetMaxCharCountOrThrowIfHuge(stream); + var maxCharRemainingGuess = GetMaxCharCountOrThrowIfHuge(encoding, stream); Debug.Assert(longLength > 0 && longLength <= int.MaxValue); // GetMaxCharCountOrThrowIfHuge should have thrown. int length = (int)longLength; diff --git a/src/Compilers/Core/Portable/Text/SourceText.cs b/src/Compilers/Core/Portable/Text/SourceText.cs index 4f5421e1c0053..0dac9ac001d04 100644 --- a/src/Compilers/Core/Portable/Text/SourceText.cs +++ b/src/Compilers/Core/Portable/Text/SourceText.cs @@ -201,7 +201,7 @@ public static SourceText From( if (stream.CanSeek) { // If the resulting string would end up on the large object heap, then use LargeEncodedText. - if (encoding.GetMaxCharCountOrThrowIfHuge(stream) >= LargeObjectHeapLimitInChars) + if (GetMaxCharCountOrThrowIfHuge(encoding, stream) >= LargeObjectHeapLimitInChars) { return LargeText.Decode(stream, encoding, checksumAlgorithm, throwIfBinaryDetected, canBeEmbedded); } @@ -1260,5 +1260,21 @@ public override event EventHandler TextChanged } } } + + /// + /// Get maximum char count needed to decode the entire stream. + /// + /// Stream is so big that max char count can't fit in . + internal static int GetMaxCharCountOrThrowIfHuge(Encoding encoding, Stream stream) + { + Debug.Assert(stream.CanSeek); + + if (encoding.TryGetMaxCharCount(stream.Length, out int maxCharCount)) + { + return maxCharCount; + } + + throw new IOException(CodeAnalysisResources.StreamIsTooLong); + } } } diff --git a/src/Compilers/Core/Portable/InternalUtilities/TextChangeRangeExtensions.cs b/src/Compilers/Core/Portable/Text/TextChangeRangeExtensions.cs similarity index 100% rename from src/Compilers/Core/Portable/InternalUtilities/TextChangeRangeExtensions.cs rename to src/Compilers/Core/Portable/Text/TextChangeRangeExtensions.cs diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs index dbcb737b52e09..1cdddef0d9097 100644 --- a/src/Compilers/Core/Portable/WellKnownMember.cs +++ b/src/Compilers/Core/Portable/WellKnownMember.cs @@ -479,6 +479,7 @@ internal enum WellKnownMember System_Span_T__ctor_Pointer, System_Span_T__ctor_Array, + System_Span_T__ctor_ref_T, System_Span_T__get_Item, System_Span_T__get_Length, System_Span_T__Slice_Int_Int, @@ -486,6 +487,7 @@ internal enum WellKnownMember System_ReadOnlySpan_T__ctor_Pointer, System_ReadOnlySpan_T__ctor_Array, System_ReadOnlySpan_T__ctor_Array_Start_Length, + System_ReadOnlySpan_T__ctor_ref_readonly_T, System_ReadOnlySpan_T__get_Item, System_ReadOnlySpan_T__get_Length, System_ReadOnlySpan_T__Slice_Int_Int, diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs index 351d772afc467..0fd77f299f9c2 100644 --- a/src/Compilers/Core/Portable/WellKnownMembers.cs +++ b/src/Compilers/Core/Portable/WellKnownMembers.cs @@ -3333,6 +3333,14 @@ static WellKnownMembers() 1, // Method Signature (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type (byte)SignatureTypeCode.SZArray, (byte)SignatureTypeCode.GenericTypeParameter, 0, + + // System_Span_T__ctor_ref_T + (byte)(MemberFlags.Constructor), // Flags + (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Span_T - WellKnownType.ExtSentinel), // DeclaringTypeId + 0, // Arity + 1, // Method Signature + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type + (byte)SignatureTypeCode.ByReference, (byte)SignatureTypeCode.GenericTypeParameter, 0, // System_Span_T__get_Item (byte)(MemberFlags.PropertyGet), // Flags @@ -3388,6 +3396,14 @@ static WellKnownMembers() (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Int32, (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Int32, + // System_ReadOnlySpan_T__ctor_ref_readonly_T + (byte)(MemberFlags.Constructor), // Flags + (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_ReadOnlySpan_T - WellKnownType.ExtSentinel), // DeclaringTypeId + 0, // Arity + 1, // Method Signature + (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, // Return Type + (byte)SignatureTypeCode.ByReference, (byte)SignatureTypeCode.GenericTypeParameter, 0, + // System_ReadOnlySpan_T__get_Item (byte)(MemberFlags.PropertyGet), // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_ReadOnlySpan_T - WellKnownType.ExtSentinel), // DeclaringTypeId @@ -4722,12 +4738,14 @@ static WellKnownMembers() ".ctor", // System_Runtime_CompilerServices_ObsoleteAttribute__ctor ".ctor", // System_Span_T__ctor_Pointer ".ctor", // System_Span_T__ctor_Array + ".ctor", // System_Span_T__ctor_ref_T "get_Item", // System_Span_T__get_Item "get_Length", // System_Span_T__get_Length "Slice", // System_Span_T__Slice_Int_Int ".ctor", // System_ReadOnlySpan_T__ctor_Pointer ".ctor", // System_ReadOnlySpan_T__ctor_Array ".ctor", // System_ReadOnlySpan_T__ctor_Array_Start_Length + ".ctor", // System_ReadOnlySpan_T__ctor_ref_readonly_T "get_Item", // System_ReadOnlySpan_T__get_Item "get_Length", // System_ReadOnlySpan_T__get_Length "Slice", // System_ReadOnlySpan_T__Slice_Int_Int diff --git a/src/Compilers/Server/VBCSCompiler/AnalyzerConsistencyChecker.cs b/src/Compilers/Server/VBCSCompiler/AnalyzerConsistencyChecker.cs index 5c83c240d529c..2fdf0b39c7355 100644 --- a/src/Compilers/Server/VBCSCompiler/AnalyzerConsistencyChecker.cs +++ b/src/Compilers/Server/VBCSCompiler/AnalyzerConsistencyChecker.cs @@ -128,7 +128,8 @@ private static bool CheckCore( var loadedAssemblyMvid = loadedAssembly.ManifestModule.ModuleVersionId; if (resolvedPathMvid != loadedAssemblyMvid) { - var message = $"analyzer assembly '{resolvedPath}' has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssembly.Location}' has MVID '{loadedAssemblyMvid}'"; + var loadedAssemblyLocation = loader.GetOriginalDependencyLocation(loadedAssembly.GetName()) ?? loadedAssembly.Location; + var message = $"analyzer assembly '{resolvedPath}' has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssemblyLocation}' has MVID '{loadedAssemblyMvid}'"; errorMessages ??= new List(); errorMessages.Add(message); logger.LogError(message); diff --git a/src/Compilers/Server/VBCSCompilerTests/AnalyzerConsistencyCheckerTests.cs b/src/Compilers/Server/VBCSCompilerTests/AnalyzerConsistencyCheckerTests.cs index 7cdf7cc9c9287..8bb31b511dfb6 100644 --- a/src/Compilers/Server/VBCSCompilerTests/AnalyzerConsistencyCheckerTests.cs +++ b/src/Compilers/Server/VBCSCompilerTests/AnalyzerConsistencyCheckerTests.cs @@ -65,7 +65,7 @@ private TempFile CreateNetStandardDll(TempDirectory directory, string assemblyNa var comp = CSharpCompilation.Create( assemblyName, sources, - references: NetStandard20.All, + references: NetStandard20.References.All, options: options); var file = directory.CreateFile($"{assemblyName}.dll"); @@ -112,7 +112,7 @@ public void DifferingMvidsDifferentDirectory() var directory = Temp.CreateDirectory(); var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(directory.CreateDirectory("shadow").Path); - var key = NetStandard20.netstandard.GetAssemblyIdentity().PublicKey; + var key = NetStandard20.References.netstandard.GetAssemblyIdentity().PublicKey; var mvidAlpha1 = CreateNetStandardDll(directory.CreateDirectory("mvid1"), "MvidAlpha", "1.0.0.0", key, "class C { }"); var mvidAlpha2 = CreateNetStandardDll(directory.CreateDirectory("mvid2"), "MvidAlpha", "1.0.0.0", key, "class D { }"); @@ -137,7 +137,7 @@ public void DifferingMvidsSameDirectory() var directory = Temp.CreateDirectory(); var assemblyLoader = DefaultAnalyzerAssemblyLoader.CreateNonLockingLoader(directory.CreateDirectory("shadow").Path); - var key = NetStandard20.netstandard.GetAssemblyIdentity().PublicKey; + var key = NetStandard20.References.netstandard.GetAssemblyIdentity().PublicKey; var mvidAlpha1 = CreateNetStandardDll(directory, "MvidAlpha", "1.0.0.0", key, "class C { }"); var result = AnalyzerConsistencyChecker.Check( @@ -154,8 +154,16 @@ public void DifferingMvidsSameDirectory() directory.Path, ImmutableArray.Create(new CommandLineAnalyzerReference(mvidAlpha2.Path)), assemblyLoader, - Logger); + Logger, + out List? errorMessages); Assert.False(result); + Assert.NotNull(errorMessages); + + // Both the original and failed paths need to appear in the message, not the shadow copy + // paths + var errorMessage = errorMessages!.Single(); + Assert.Contains(mvidAlpha1.Path, errorMessage); + Assert.Contains(mvidAlpha2.Path, errorMessage); } /// @@ -168,7 +176,7 @@ public void DifferingMvidsSameDirectory() public void LoadingLibraryFromCompiler() { var directory = Temp.CreateDirectory(); - _ = CreateNetStandardDll(directory, "System.Memory", "2.0.0.0", NetStandard20.netstandard.GetAssemblyIdentity().PublicKey); + _ = CreateNetStandardDll(directory, "System.Memory", "2.0.0.0", NetStandard20.References.netstandard.GetAssemblyIdentity().PublicKey); // This test must use the DefaultAnalyzerAssemblyLoader as we want assembly binding redirects // to take affect here. @@ -226,7 +234,7 @@ public void AssemblyLoadException() public void LoadingSimpleLibrary() { var directory = Temp.CreateDirectory(); - var key = NetStandard20.netstandard.GetAssemblyIdentity().PublicKey; + var key = NetStandard20.References.netstandard.GetAssemblyIdentity().PublicKey; var compFile = CreateNetStandardDll(directory, "netstandardRef", "1.0.0.0", key); var analyzerReferences = ImmutableArray.Create(new CommandLineAnalyzerReference(compFile.Path)); @@ -242,5 +250,6 @@ public void LoadingSimpleLibrary() public void AddDependencyLocation(string fullPath) { } public bool IsHostAssembly(Assembly assembly) => false; public Assembly LoadFromPath(string fullPath) => throw new Exception(); + public string? GetOriginalDependencyLocation(AssemblyName assembly) => throw new Exception(); } } diff --git a/src/Compilers/Test/Core/AssemblyLoadTestFixture.cs b/src/Compilers/Test/Core/AssemblyLoadTestFixture.cs index 1dc56963a68c2..b86840383740d 100644 --- a/src/Compilers/Test/Core/AssemblyLoadTestFixture.cs +++ b/src/Compilers/Test/Core/AssemblyLoadTestFixture.cs @@ -522,9 +522,9 @@ private static string GenerateDll(string assemblyName, TempDirectory directory, syntaxTrees: new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(SourceText.From(csSource, encoding: null, SourceHashAlgorithms.Default)) }, references: (new MetadataReference[] { - NetStandard20.mscorlib, - NetStandard20.netstandard, - NetStandard20.SystemRuntime + NetStandard20.References.mscorlib, + NetStandard20.References.netstandard, + NetStandard20.References.SystemRuntime }).Concat(additionalReferences), options: options); diff --git a/src/Compilers/Test/Core/Assert/AssertEx.cs b/src/Compilers/Test/Core/Assert/AssertEx.cs index e5a4e66119b49..f254328b52e3a 100644 --- a/src/Compilers/Test/Core/Assert/AssertEx.cs +++ b/src/Compilers/Test/Core/Assert/AssertEx.cs @@ -674,6 +674,14 @@ public static string GetAssertMessage( var expectedString = string.Join(itemSeparator, expected.Take(10).Select(itemInspector)); var actualString = string.Join(itemSeparator, actual.Select(itemInspector)); + var diffString = DiffUtil.DiffReport(expected, actual, itemSeparator, comparer, itemInspector); + + if (DifferOnlyInWhitespace(expectedString, actualString)) + { + expectedString = VisualizeWhitespace(expectedString); + actualString = VisualizeWhitespace(actualString); + diffString = VisualizeWhitespace(diffString); + } var message = new StringBuilder(); @@ -693,7 +701,7 @@ public static string GetAssertMessage( message.AppendLine("Actual:"); message.AppendLine(actualString); message.AppendLine("Differences:"); - message.AppendLine(DiffUtil.DiffReport(expected, actual, itemSeparator, comparer, itemInspector)); + message.AppendLine(diffString); if (TryGenerateExpectedSourceFileAndGetDiffLink(actualString, expected.Count(), expectedValueSourcePath, expectedValueSourceLine, out var link)) { @@ -703,6 +711,38 @@ public static string GetAssertMessage( return message.ToString(); } + private static bool DifferOnlyInWhitespace(IEnumerable expected, IEnumerable actual) + => expected.Where(c => !char.IsWhiteSpace(c)).SequenceEqual(actual.Where(c => !char.IsWhiteSpace(c))); + + private static string VisualizeWhitespace(string str) + { + var result = new StringBuilder(str.Length); + + var i = 0; + while (i < str.Length) + { + var c = str[i++]; + if (c == '\r' && i < str.Length && str[i] == '\n') + { + result.Append("␍␊\r\n"); + i++; + } + else + { + result.Append(c switch + { + ' ' => "·", + '\t' => "→", + '\r' => "␍\r", + '\n' => "␊\n", + _ => c, + }); + } + } + + return result.ToString(); + } + public static string GetAssertMessage( ReadOnlySpan expected, ReadOnlySpan actual, diff --git a/src/Compilers/Test/Core/Compilation/RuntimeUtilities.cs b/src/Compilers/Test/Core/Compilation/RuntimeUtilities.cs index 57825e1362a3f..6e29d5625fc80 100644 --- a/src/Compilers/Test/Core/Compilation/RuntimeUtilities.cs +++ b/src/Compilers/Test/Core/Compilation/RuntimeUtilities.cs @@ -27,14 +27,19 @@ public static partial class RuntimeUtilities #endif internal static bool IsCoreClrRuntime => !IsDesktopRuntime; + private static int? CoreClrRuntimeVersion { get; } = IsDesktopRuntime + ? null + : typeof(object).Assembly.GetName().Version.Major; + internal static bool IsCoreClr6Runtime => IsCoreClrRuntime && RuntimeInformation.FrameworkDescription.StartsWith(".NET 6.", StringComparison.Ordinal); internal static bool IsCoreClr8OrHigherRuntime - => IsCoreClrRuntime && RuntimeInformation.FrameworkDescription.StartsWith(".NET 8.", StringComparison.Ordinal); + => CoreClrRuntimeVersion is { } v && v >= 8; internal static bool IsCoreClr9OrHigherRuntime - => IsCoreClrRuntime && RuntimeInformation.FrameworkDescription.StartsWith(".NET 9.", StringComparison.Ordinal); + => CoreClrRuntimeVersion is { } v && v >= 9; + #if NET9_0_OR_GREATER #error Make the above check be an #if NET9_OR_GREATER when we add net8 support to build #endif diff --git a/src/Compilers/Test/Core/Platform/Desktop/TestHelpers.cs b/src/Compilers/Test/Core/Platform/Desktop/TestHelpers.cs index fc864457cf320..c00cc71683579 100644 --- a/src/Compilers/Test/Core/Platform/Desktop/TestHelpers.cs +++ b/src/Compilers/Test/Core/Platform/Desktop/TestHelpers.cs @@ -83,9 +83,9 @@ public class TestAnalyzer : DiagnosticAnalyzer new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(SourceText.From(analyzerSource, encoding: null, SourceHashAlgorithms.Default)) }, new MetadataReference[] { - NetStandard20.mscorlib, - NetStandard20.netstandard, - NetStandard20.SystemRuntime, + NetStandard20.References.mscorlib, + NetStandard20.References.netstandard, + NetStandard20.References.SystemRuntime, MetadataReference.CreateFromFile(immutable.Path), MetadataReference.CreateFromFile(analyzer.Path) }, diff --git a/src/Compilers/Test/Core/TargetFrameworkUtil.cs b/src/Compilers/Test/Core/TargetFrameworkUtil.cs index 6f9ea4264263a..592cdb613b90f 100644 --- a/src/Compilers/Test/Core/TargetFrameworkUtil.cs +++ b/src/Compilers/Test/Core/TargetFrameworkUtil.cs @@ -91,7 +91,8 @@ public enum TargetFramework Net50, Net60, Net70, - Net80 + Net80, + Net90, } /// @@ -101,12 +102,12 @@ public enum TargetFramework /// public static class NetCoreApp { - public static ImmutableArray AllReferenceInfos { get; } = ImmutableArray.CreateRange(Net70.References.All); - public static ImmutableArray References { get; } = ImmutableArray.CreateRange(Net70.All); + public static ImmutableArray AllReferenceInfos { get; } = ImmutableArray.CreateRange(Net70.ReferenceInfos.All); + public static ImmutableArray References { get; } = ImmutableArray.CreateRange(Net70.References.All); - public static PortableExecutableReference netstandard { get; } = Net70.netstandard; - public static PortableExecutableReference mscorlib { get; } = Net70.mscorlib; - public static PortableExecutableReference SystemRuntime { get; } = Net70.SystemRuntime; + public static PortableExecutableReference netstandard { get; } = Net70.References.netstandard; + public static PortableExecutableReference mscorlib { get; } = Net70.References.mscorlib; + public static PortableExecutableReference SystemRuntime { get; } = Net70.References.SystemRuntime; } /// @@ -124,7 +125,7 @@ public static class NetFramework /// public static ImmutableArray References { get; } = ImmutableArray - .CreateRange(Net461.All) + .CreateRange(Net461.References.All) .Add(NetFx.ValueTuple.tuplelib); /// @@ -136,19 +137,19 @@ public static class NetFramework /// public static ImmutableArray Standard { get; } = ImmutableArray.Create( - Net461.mscorlib, - Net461.System, - Net461.SystemCore, + Net461.References.mscorlib, + Net461.References.System, + Net461.References.SystemCore, NetFx.ValueTuple.tuplelib, - Net461.SystemRuntime); - - public static PortableExecutableReference mscorlib { get; } = Net461.mscorlib; - public static PortableExecutableReference System { get; } = Net461.System; - public static PortableExecutableReference SystemRuntime { get; } = Net461.SystemRuntime; - public static PortableExecutableReference SystemCore { get; } = Net461.SystemCore; - public static PortableExecutableReference SystemThreadingTasks { get; } = Net461.SystemThreadingTasks; - public static PortableExecutableReference MicrosoftCSharp { get; } = Net461.MicrosoftCSharp; - public static PortableExecutableReference MicrosoftVisualBasic { get; } = Net461.MicrosoftVisualBasic; + Net461.References.SystemRuntime); + + public static PortableExecutableReference mscorlib { get; } = Net461.References.mscorlib; + public static PortableExecutableReference System { get; } = Net461.References.System; + public static PortableExecutableReference SystemRuntime { get; } = Net461.References.SystemRuntime; + public static PortableExecutableReference SystemCore { get; } = Net461.References.SystemCore; + public static PortableExecutableReference SystemThreadingTasks { get; } = Net461.References.SystemThreadingTasks; + public static PortableExecutableReference MicrosoftCSharp { get; } = Net461.References.MicrosoftCSharp; + public static PortableExecutableReference MicrosoftVisualBasic { get; } = Net461.References.MicrosoftVisualBasic; } public static class TargetFrameworkUtil @@ -168,24 +169,108 @@ public static class TargetFrameworkUtil * for a TypeLoadException are missing important information for resolving problems if/when they occur. * https://github.com/dotnet/roslyn/issues/25961 */ + public static ImmutableArray WinRTReferences => + [ + .. TestBase.WinRtRefs + ]; + public static ImmutableArray MinimalReferences => + [ + TestBase.MinCorlibRef + ]; + public static ImmutableArray MinimalAsyncReferences => + [ + TestBase.MinAsyncCorlibRef + ]; + public static ImmutableArray Mscorlib45ExtendedReferences => + [ + Net451.mscorlib, + Net451.System, + Net451.SystemCore, + TestBase.ValueTupleRef, + Net451.SystemRuntime + ]; + public static ImmutableArray Mscorlib46ExtendedReferences => + [ + Net461.References.mscorlib, + Net461.References.System, + Net461.References.SystemCore, + TestBase.ValueTupleRef, + Net461.References.SystemRuntime + ]; + /* + * ⚠ Dev note ⚠: TestBase properties end here. + */ - public static ImmutableArray Mscorlib40References => ImmutableArray.Create(Net40.mscorlib); - public static ImmutableArray Mscorlib40ExtendedReferences => ImmutableArray.Create(Net40.mscorlib, Net40.System, Net40.SystemCore); - public static ImmutableArray Mscorlib40andSystemCoreReferences => ImmutableArray.Create(Net40.mscorlib, Net40.SystemCore); - public static ImmutableArray Mscorlib40andVBRuntimeReferences => ImmutableArray.Create(Net40.mscorlib, Net40.System, Net40.MicrosoftVisualBasic); - public static ImmutableArray Mscorlib45References => ImmutableArray.Create(Net451.mscorlib); - public static ImmutableArray Mscorlib45ExtendedReferences => ImmutableArray.Create(Net451.mscorlib, Net451.System, Net451.SystemCore, TestBase.ValueTupleRef, Net451.SystemRuntime); - public static ImmutableArray Mscorlib45AndCSharpReferences => ImmutableArray.Create(Net451.mscorlib, Net451.SystemCore, Net451.MicrosoftCSharp); - public static ImmutableArray Mscorlib45AndVBRuntimeReferences => ImmutableArray.Create(Net451.mscorlib, Net451.System, Net451.MicrosoftVisualBasic); - public static ImmutableArray Mscorlib46References => ImmutableArray.Create(Net461.mscorlib); - public static ImmutableArray Mscorlib46ExtendedReferences => ImmutableArray.Create(Net461.mscorlib, Net461.System, Net461.SystemCore, TestBase.ValueTupleRef, Net461.SystemRuntime); - public static ImmutableArray Mscorlib461References => ImmutableArray.Create(Net461.mscorlib); - public static ImmutableArray Mscorlib461ExtendedReferences => ImmutableArray.Create(Net461.mscorlib, Net461.System, Net461.SystemCore, NetFx.ValueTuple.tuplelib, Net461.SystemRuntime); - public static ImmutableArray NetStandard20References => ImmutableArray.Create(NetStandard20.netstandard, NetStandard20.mscorlib, NetStandard20.SystemRuntime, NetStandard20.SystemCore, NetStandard20.SystemDynamicRuntime, NetStandard20.SystemLinq, NetStandard20.SystemLinqExpressions); - public static ImmutableArray WinRTReferences => ImmutableArray.Create(TestBase.WinRtRefs); - public static ImmutableArray DefaultVbReferences => ImmutableArray.Create(Net451.mscorlib, Net451.System, Net451.SystemCore, Net451.MicrosoftVisualBasic); - public static ImmutableArray MinimalReferences => ImmutableArray.Create(TestBase.MinCorlibRef); - public static ImmutableArray MinimalAsyncReferences => ImmutableArray.Create(TestBase.MinAsyncCorlibRef); + public static ImmutableArray Mscorlib40References { get; } = + [ + Net40.mscorlib + ]; + public static ImmutableArray Mscorlib40ExtendedReferences { get; } = + [ + Net40.mscorlib, + Net40.System, + Net40.SystemCore + ]; + public static ImmutableArray Mscorlib40andSystemCoreReferences { get; } = + [ + Net40.mscorlib, + Net40.SystemCore + ]; + public static ImmutableArray Mscorlib40andVBRuntimeReferences { get; } = + [ + Net40.mscorlib, + Net40.System, + Net40.MicrosoftVisualBasic + ]; + public static ImmutableArray Mscorlib45References { get; } = + [ + Net451.mscorlib + ]; + public static ImmutableArray Mscorlib45AndCSharpReferences { get; } = + [ + Net451.mscorlib, + Net451.SystemCore, + Net451.MicrosoftCSharp + ]; + public static ImmutableArray Mscorlib45AndVBRuntimeReferences { get; } = + [ + Net451.mscorlib, + Net451.System, + Net451.MicrosoftVisualBasic + ]; + public static ImmutableArray Mscorlib46References { get; } = + [ + Net461.References.mscorlib + ]; + public static ImmutableArray Mscorlib461References { get; } = + [ + Net461.References.mscorlib + ]; + public static ImmutableArray Mscorlib461ExtendedReferences { get; } = + [ + Net461.References.mscorlib, + Net461.References.System, + Net461.References.SystemCore, + NetFx.ValueTuple.tuplelib, + Net461.References.SystemRuntime + ]; + public static ImmutableArray NetStandard20References { get; } = + [ + NetStandard20.References.netstandard, + NetStandard20.References.mscorlib, + NetStandard20.References.SystemRuntime, + NetStandard20.References.SystemCore, + NetStandard20.References.SystemDynamicRuntime, + NetStandard20.References.SystemLinq, + NetStandard20.References.SystemLinqExpressions + ]; + public static ImmutableArray DefaultVbReferences { get; } = + [ + Net451.mscorlib, + Net451.System, + Net451.SystemCore, + Net451.MicrosoftVisualBasic + ]; #if DEBUG @@ -206,8 +291,9 @@ static TargetFrameworkUtil() TargetFramework.NetStandard20 => NetStandard20References, TargetFramework.Net50 => ImmutableArray.CreateRange(LoadDynamicReferences("Net50")), TargetFramework.Net60 => ImmutableArray.CreateRange(LoadDynamicReferences("Net60")), - TargetFramework.NetCoreApp or TargetFramework.Net70 => ImmutableArray.CreateRange(Net70.All), + TargetFramework.NetCoreApp or TargetFramework.Net70 => ImmutableArray.CreateRange(Net70.References.All), TargetFramework.Net80 => ImmutableArray.CreateRange(LoadDynamicReferences("Net80")), + TargetFramework.Net90 => ImmutableArray.CreateRange(LoadDynamicReferences("Net90")), TargetFramework.NetFramework => NetFramework.References, TargetFramework.NetLatest => NetLatest, TargetFramework.Standard => StandardReferences, diff --git a/src/Compilers/Test/Core/TestBase.cs b/src/Compilers/Test/Core/TestBase.cs index d4de9c7e3d829..fe864fc970d5f 100644 --- a/src/Compilers/Test/Core/TestBase.cs +++ b/src/Compilers/Test/Core/TestBase.cs @@ -163,7 +163,7 @@ public virtual void Dispose() public static MetadataReference SystemRuntimeSerializationRef_v4_0_30319_17929 => s_systemRuntimeSerializationRef_v4_0_30319_17929.Value; private static readonly Lazy s_systemCoreRef_v46 = new Lazy( - () => AssemblyMetadata.CreateFromImage(Net461.References.SystemCore.ImageBytes).GetReference(display: "System.Core.v4_6_1038_0.dll"), + () => AssemblyMetadata.CreateFromImage(Net461.ReferenceInfos.SystemCore.ImageBytes).GetReference(display: "System.Core.v4_6_1038_0.dll"), LazyThreadSafetyMode.PublicationOnly); public static MetadataReference SystemCoreRef_v46 => s_systemCoreRef_v4_0_30319_17929.Value; @@ -220,7 +220,7 @@ public virtual void Dispose() public static MetadataReference MscorlibRef_v4_0_30316_17626 => Net451.mscorlib; private static readonly Lazy s_mscorlibRef_v46 = new Lazy( - () => AssemblyMetadata.CreateFromImage(Net461.References.mscorlib.ImageBytes).GetReference(display: "mscorlib.v4_6_1038_0.dll", filePath: @"Z:\FxReferenceAssembliesUri"), + () => AssemblyMetadata.CreateFromImage(Net461.ReferenceInfos.mscorlib.ImageBytes).GetReference(display: "mscorlib.v4_6_1038_0.dll", filePath: @"Z:\FxReferenceAssembliesUri"), LazyThreadSafetyMode.PublicationOnly); public static MetadataReference MscorlibRef_v46 => s_mscorlibRef_v46.Value; @@ -267,7 +267,7 @@ public virtual void Dispose() public static MetadataReference SystemRef => s_systemRef.Value; private static readonly Lazy s_systemRef_v46 = new Lazy( - () => AssemblyMetadata.CreateFromImage(Net461.References.System.ImageBytes).GetReference(display: "System.v4_6_1038_0.dll"), + () => AssemblyMetadata.CreateFromImage(Net461.ReferenceInfos.System.ImageBytes).GetReference(display: "System.v4_6_1038_0.dll"), LazyThreadSafetyMode.PublicationOnly); public static MetadataReference SystemRef_v46 => s_systemRef_v46.Value; diff --git a/src/Compilers/Test/Core/TestResource.resx b/src/Compilers/Test/Core/TestResource.resx index 4779683e017fb..22f413935ce41 100644 --- a/src/Compilers/Test/Core/TestResource.resx +++ b/src/Compilers/Test/Core/TestResource.resx @@ -554,7 +554,7 @@ namespace My [Obsolete] private volatile int f2; public abstract int m<T>(T t) - where T : struct + where T : struct, allows ref struct { return 1; } diff --git a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs index 7e37c631b3766..8388968457fb4 100644 --- a/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs +++ b/src/Compilers/Test/Utilities/CSharp/CSharpTestBase.cs @@ -1204,7 +1204,7 @@ public static CSharpCompilation CreateCompilationWithTasksExtensions( else { allReferences = TargetFrameworkUtil.Mscorlib461ExtendedReferences; - allReferences = allReferences.Concat(new[] { Net461.SystemThreadingTasks, SystemThreadingTasksExtensions.PortableLib }); + allReferences = allReferences.Concat(new[] { Net461.References.SystemThreadingTasks, SystemThreadingTasksExtensions.PortableLib }); } if (references != null) diff --git a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb index 92bf462abb3cc..f14fa7854ca66 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicSymbolMatcher.vb @@ -475,6 +475,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit ' edit. Furthermore, comparing constraint types might lead to a cycle. Debug.Assert(type.HasConstructorConstraint = other.HasConstructorConstraint) Debug.Assert(type.HasValueTypeConstraint = other.HasValueTypeConstraint) + Debug.Assert(type.AllowsRefLikeType = other.AllowsRefLikeType) Debug.Assert(type.HasReferenceTypeConstraint = other.HasReferenceTypeConstraint) Debug.Assert(type.ConstraintTypesNoUseSiteDiagnostics.Length = other.ConstraintTypesNoUseSiteDiagnostics.Length) Return True diff --git a/src/Compilers/VisualBasic/Portable/Emit/NoPia/EmbeddedTypeParameter.vb b/src/Compilers/VisualBasic/Portable/Emit/NoPia/EmbeddedTypeParameter.vb index b1a7e93fb422c..a32c6ed429e72 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/NoPia/EmbeddedTypeParameter.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/NoPia/EmbeddedTypeParameter.vb @@ -35,6 +35,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit.NoPia End Get End Property + Protected Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return UnderlyingTypeParameter.AdaptedTypeParameterSymbol.AllowsRefLikeType + End Get + End Property + Protected Overrides ReadOnly Property MustHaveDefaultConstructor As Boolean Get Return UnderlyingTypeParameter.AdaptedTypeParameterSymbol.HasConstructorConstraint diff --git a/src/Compilers/VisualBasic/Portable/Emit/TypeParameterSymbolAdapter.vb b/src/Compilers/VisualBasic/Portable/Emit/TypeParameterSymbolAdapter.vb index b9eb1ac5c5de2..65503987b6cda 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/TypeParameterSymbolAdapter.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/TypeParameterSymbolAdapter.vb @@ -233,6 +233,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Private ReadOnly Property IGenericParameterAllowByRefLike As Boolean Implements IGenericParameter.AllowsRefLikeType + Get + Return AdaptedTypeParameterSymbol.AllowsRefLikeType + End Get + End Property + Private ReadOnly Property IGenericParameterMustHaveDefaultConstructor As Boolean Implements IGenericParameter.MustHaveDefaultConstructor Get ' add constructor constraint for value type constrained diff --git a/src/Compilers/VisualBasic/Portable/Semantics/CompileTimeCalculations.vb b/src/Compilers/VisualBasic/Portable/Semantics/CompileTimeCalculations.vb index d30639cf12746..79d119f11bf1f 100644 --- a/src/Compilers/VisualBasic/Portable/Semantics/CompileTimeCalculations.vb +++ b/src/Compilers/VisualBasic/Portable/Semantics/CompileTimeCalculations.vb @@ -603,7 +603,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic If sourceValue > &H7000000000000000L Then Dim temporary As Double = (sourceValue - &H7000000000000000L) - If temporary < &H7000000000000000L AndAlso UncheckedCLng(temporary) > &H1000000000000000L Then + If temporary < &H7000000000000000L AndAlso UncheckedCLng(temporary) < &H1000000000000000L Then Return False End If Else diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTypeParameterSymbol.vb index 2c64a421fd8e0..f8571dbac4861 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AnonymousTypes/SynthesizedSymbols/AnonymousTypeOrDelegateTypeParameterSymbol.vb @@ -93,6 +93,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return False + End Get + End Property + Public Overrides ReadOnly Property Variance As VarianceKind Get Return VarianceKind.None diff --git a/src/Compilers/VisualBasic/Portable/Symbols/AssemblySymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/AssemblySymbol.vb index fa196d7309f64..08f8394987164 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/AssemblySymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/AssemblySymbol.vb @@ -347,6 +347,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Return Me.RuntimeSupportsVirtualStaticsInInterfaces Case RuntimeCapability.InlineArrayTypes Return Me.RuntimeSupportsInlineArrayTypes + Case RuntimeCapability.ByRefLikeGenerics + Return Me.RuntimeSupportsByRefLikeGenerics End Select Return False @@ -409,6 +411,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Private ReadOnly Property RuntimeSupportsByRefLikeGenerics As Boolean + Get + ' Keep in sync with C#'s AssemblySymbol.RuntimeSupportsByRefLikeGenerics + ' CorLibrary should never be null, but that invariant Is broken in some cases for MissingAssemblySymbol. + ' Tracked by https://github.com/dotnet/roslyn/issues/61262 + Return CorLibrary IsNot Nothing AndAlso + RuntimeSupportsFeature(SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics) + End Get + End Property + Private Function RuntimeSupportsFeature(feature As SpecialMember) As Boolean Debug.Assert(SpecialMembers.GetDescriptor(feature).DeclaringSpecialType = SpecialType.System_Runtime_CompilerServices_RuntimeFeature) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/IndexedTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/IndexedTypeParameterSymbol.vb index 18b403c6252a0..dca460d7f317d 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/IndexedTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/IndexedTypeParameterSymbol.vb @@ -116,6 +116,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return False + End Get + End Property + Public Overrides ReadOnly Property HasReferenceTypeConstraint As Boolean Get Return False diff --git a/src/Compilers/VisualBasic/Portable/Symbols/InstanceErrorTypeSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/InstanceErrorTypeSymbol.vb index 985579c078721..dd6486d1d2839 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/InstanceErrorTypeSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/InstanceErrorTypeSymbol.vb @@ -233,6 +233,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return False + End Get + End Property + Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Return ImmutableArray(Of Location).Empty diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.vb index 1ecc93c7051df..fa89f737d2d97 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PETypeParameterSymbol.vb @@ -245,6 +245,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return (_flags And MetadataHelpers.GenericParameterAttributesAllowByRefLike) <> 0 + End Get + End Property + Public Overrides ReadOnly Property Variance As VarianceKind Get Return CType((_flags And GenericParameterAttributes.VarianceMask), VarianceKind) diff --git a/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb b/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb index 449d48c014410..39e5fbc32563e 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/MethodSignatureComparer.vb @@ -863,6 +863,7 @@ Done: If (typeParameter1.HasConstructorConstraint <> typeParameter2.HasConstructorConstraint) OrElse (typeParameter1.HasReferenceTypeConstraint <> typeParameter2.HasReferenceTypeConstraint) OrElse (typeParameter1.HasValueTypeConstraint <> typeParameter2.HasValueTypeConstraint) OrElse + (typeParameter1.AllowsRefLikeType <> typeParameter2.AllowsRefLikeType) OrElse (typeParameter1.Variance <> typeParameter2.Variance) Then Return False End If diff --git a/src/Compilers/VisualBasic/Portable/Symbols/ReducedExtensionMethodSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/ReducedExtensionMethodSymbol.vb index 8dfaf13e7f301..7cad34b2202d4 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/ReducedExtensionMethodSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/ReducedExtensionMethodSymbol.vb @@ -749,6 +749,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return _curriedFromTypeParameter.AllowsRefLikeType + End Get + End Property + Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Return _curriedFromTypeParameter.Locations diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingTypeParameterSymbol.vb index 18a5c44aafd78..b814ac65952a1 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingTypeParameterSymbol.vb @@ -98,6 +98,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return _underlyingTypeParameter.AllowsRefLikeType + End Get + End Property + Public Overrides ReadOnly Property Variance As VarianceKind Get Return _underlyingTypeParameter.Variance diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Source/CrefTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Source/CrefTypeParameterSymbol.vb index 902b992e69b1d..dd14245f73a15 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Source/CrefTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Source/CrefTypeParameterSymbol.vb @@ -67,6 +67,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return False + End Get + End Property + Friend Overrides ReadOnly Property ConstraintTypesNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol) Get Return ImmutableArray(Of TypeSymbol).Empty diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceTypeParameterSymbol.vb index 2ca688c612858..126b2ef5c1ab5 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceTypeParameterSymbol.vb @@ -77,6 +77,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return False + End Get + End Property + Friend Overrides ReadOnly Property ConstraintTypesNoUseSiteDiagnostics As ImmutableArray(Of TypeSymbol) Get EnsureAllConstraintsAreResolved() diff --git a/src/Compilers/VisualBasic/Portable/Symbols/SubstitutedTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/SubstitutedTypeParameterSymbol.vb index e511e0cebe764..475be49ff2a2c 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/SubstitutedTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/SubstitutedTypeParameterSymbol.vb @@ -126,6 +126,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return _originalDefinition.AllowsRefLikeType + End Get + End Property + Public Overrides ReadOnly Property IsImplicitlyDeclared As Boolean Get Return _originalDefinition.IsImplicitlyDeclared diff --git a/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb index d7a9a545059da..e6a1a352fbd6d 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb @@ -100,6 +100,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return _correspondingMethodTypeParameter.AllowsRefLikeType + End Get + End Property + Public Overrides ReadOnly Property Locations As ImmutableArray(Of Location) Get Return _correspondingMethodTypeParameter.Locations diff --git a/src/Compilers/VisualBasic/Portable/Symbols/TypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/TypeParameterSymbol.vb index 7f76621542b37..184a1c7286655 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/TypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/TypeParameterSymbol.vb @@ -317,6 +317,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Public MustOverride ReadOnly Property HasValueTypeConstraint As Boolean Implements ITypeParameterSymbol.HasValueTypeConstraint + Public MustOverride ReadOnly Property AllowsRefLikeType As Boolean Implements ITypeParameterSymbol.AllowsRefLikeType + Private ReadOnly Property HasUnmanagedTypeConstraint As Boolean Implements ITypeParameterSymbol.HasUnmanagedTypeConstraint Get Return False diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb index a98e82937f542..9717a11ff47d7 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb @@ -61,6 +61,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols End Get End Property + Public Overrides ReadOnly Property AllowsRefLikeType As Boolean + Get + Return Me._underlyingTypeParameter.AllowsRefLikeType + End Get + End Property + Public Overrides ReadOnly Property Variance As VarianceKind Get Return Me._underlyingTypeParameter.Variance diff --git a/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.vb b/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.vb index d92b66727fa56..65eb74a05db7f 100644 --- a/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.vb +++ b/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IForEachLoopStatement.vb @@ -1820,11 +1820,7 @@ Block[B0] - Entry Statements (1) IInvocationOperation (virtual Sub System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'x') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 'x') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (WideningValue) - Operand: - IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: Enumerator, IsImplicit) (Syntax: 'x') + IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: Enumerator, IsImplicit) (Syntax: 'x') Arguments(0) Next (StructuredExceptionHandling) Block[null] diff --git a/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IUsingStatement.vb b/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IUsingStatement.vb index 1a8e05fe90a02..a03fb4dcb8d46 100644 --- a/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IUsingStatement.vb +++ b/src/Compilers/VisualBasic/Test/IOperation/IOperation/IOperationTests_IUsingStatement.vb @@ -1101,11 +1101,7 @@ Block[B0] - Entry Statements (1) IInvocationOperation (virtual Sub System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 's2') Instance Receiver: - IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 's2') - Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) - (WideningValue) - Operand: - ILocalReferenceOperation: s2 (OperationKind.LocalReference, Type: S2, IsImplicit) (Syntax: 's2') + ILocalReferenceOperation: s2 (OperationKind.LocalReference, Type: S2, IsImplicit) (Syntax: 's2') Arguments(0) Next (StructuredExceptionHandling) Block[null] diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingObjectInitializerTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingObjectInitializerTests.vb index aa9e152b4d414..c008d8dd5f120 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingObjectInitializerTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingObjectInitializerTests.vb @@ -2073,6 +2073,52 @@ Console.writeline( cust2.e.ToString) CompileAndVerify(compilation) End Sub + + Public Sub RefReturningProperty() + Dim cSharpSource = ref _f; + } +}]]>.Value + Dim cSharpCompilation = CreateCSharpCompilation(cSharpSource).VerifyDiagnostics() + Dim cSharpRef = cSharpCompilation.EmitToPortableExecutableReference() + + Dim source = .Value + + Dim expectedOperationTree = .Value + + Dim expectedDiagnostics = String.Empty + + VerifyOperationTreeAndDiagnosticsForTest(Of ObjectCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics, references:={cSharpRef}) + + CompileAndVerify(CreateCompilation(source, {cSharpRef}, TestOptions.ReleaseExe), expectedOutput:=).VerifyDiagnostics() + End Sub + End Class End Namespace diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions.vb index d7d6b1d6070b9..25b3ddd15a495 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions.vb @@ -605,7 +605,8 @@ End Class New TypeAndValue(uint64Type, CULng(18)), New TypeAndValue(decimalType, CDec(-11.3)), New TypeAndValue(doubleType, CDbl(&HF000000000000000UL)), - New TypeAndValue(doubleType, CDbl(&H70000000000000F0L)), + New TypeAndValue(doubleType, CDbl(&H8000000000000000L)), + New TypeAndValue(doubleType, CDbl(&H7FFFFFFFFFFFFC00L)), New TypeAndValue(typeCodeType, Int32.MinValue), New TypeAndValue(typeCodeType, Int32.MaxValue), New TypeAndValue(typeCodeType, CInt(-3)), @@ -1165,7 +1166,8 @@ End Class New TypeAndValue(uint64Type, CULng(18)), New TypeAndValue(decimalType, CDec(-11.3)), New TypeAndValue(doubleType, CDbl(&HF000000000000000UL)), - New TypeAndValue(doubleType, CDbl(&H70000000000000F0L)), + New TypeAndValue(doubleType, CDbl(&H8000000000000000L)), + New TypeAndValue(doubleType, CDbl(&H7FFFFFFFFFFFFC00L)), New TypeAndValue(typeCodeType, Int32.MinValue), New TypeAndValue(typeCodeType, Int32.MaxValue), New TypeAndValue(typeCodeType, CInt(-3)), @@ -5095,5 +5097,46 @@ End Module ]]>) End Sub + + + Public Sub ConvertLargeDoubleConstantsAndLiteralsToLong() + Dim compilation = CreateCompilationWithMscorlib40AndVBRuntime( + + + , options:=TestOptions.ReleaseExe.WithOverflowChecks(True)) + + Dim expectedOutput = + + CompileAndVerify(compilation, expectedOutput:=expectedOutput).VerifyDiagnostics() + End Sub + End Class End Namespace diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb index d71521c1d7937..f7abc9ccd3903 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/RequiredMembersTests.vb @@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Inherits BasicTestBase Private Function CreateCSharpCompilationWithRequiredMembers(source As String) As CSharpCompilation - Return CreateCSharpCompilation(source, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Return CreateCSharpCompilation(source, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) End Function @@ -424,14 +424,14 @@ End Module" Public Sub EnforcedRequiredMembers_ThroughRetargeting_NoneSet() Dim retargetedCode = GetCDefinition(hasSetsRequiredMembers:=False) - Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim originalBasic = CreateCompilation(" Public Class Base Public Property C As C End Class", {originalC.EmitToImageReference()}) - Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim comp = CreateCompilation(" Module M @@ -455,14 +455,14 @@ BC37321: Required member 'Public Overloads Property Prop As Integer' must be set Public Sub EnforcedRequiredMembers_ThroughRetargeting_AllSet( constructor As String) Dim retargetedCode = GetCDefinition(hasSetsRequiredMembers:=False) - Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim originalBasic = CreateCompilation(" Public Class Base Public Property C As C End Class", {originalC.EmitToImageReference()}) - Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim comp = CreateCompilation(" Module M @@ -480,14 +480,14 @@ End Module", {originalBasic.ToMetadataReference(), retargetedC.EmitToImageRefere Dim retargetedCode = GetCDefinition(hasSetsRequiredMembers:=True) - Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim originalBasic = CreateCompilation(" Public Class Base Public Property C As C End Class", {originalC.EmitToImageReference()}) - Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), retargetedCode, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim comp = CreateCompilation(" Module M @@ -504,14 +504,14 @@ End Module", {originalBasic.ToMetadataReference(), retargetedC.EmitToImageRefere Dim codeWithRequired = GetCDefinition(hasSetsRequiredMembers:=False) Dim codeWithoutRequired = codeWithRequired.Replace("required ", "") - Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), codeWithoutRequired, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim originalC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(1, 0, 0, 0), isRetargetable:=True), codeWithoutRequired, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim originalBasic = CreateCompilation(" Public Class Derived Inherits C End Class", {originalC.EmitToImageReference()}) - Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), codeWithRequired, referencedAssemblies:=Basic.Reference.Assemblies.Net70.All) + Dim retargetedC = CreateCSharpCompilation(New AssemblyIdentity("Ret", New Version(2, 0, 0, 0), isRetargetable:=True), codeWithRequired, referencedAssemblies:=Basic.Reference.Assemblies.Net70.References.All) Dim comp = CreateCompilation(" Module M @@ -543,7 +543,7 @@ End Class", targetFramework:=TargetFramework.Net70) public class Derived : Base { public required int Prop { get; set; } -}", referencedAssemblies:=DirectCast(Basic.Reference.Assemblies.Net70.All, IEnumerable(Of MetadataReference)).Append(originalVbComp.EmitToImageReference())) +}", referencedAssemblies:=DirectCast(Basic.Reference.Assemblies.Net70.References.All, IEnumerable(Of MetadataReference)).Append(originalVbComp.EmitToImageReference())) Dim comp = CreateCompilation($" Module M @@ -1952,7 +1952,7 @@ namespace System } } } -", referencedAssemblies:=Basic.Reference.Assemblies.Net461.All) +", referencedAssemblies:=Basic.Reference.Assemblies.Net461.References.All) Dim csharpCompReference As MetadataReference = csharpComp.EmitToImageReference() ' Using Net461 to get a framework without ValueTuple @@ -2143,7 +2143,7 @@ namespace System } } } -", referencedAssemblies:=Basic.Reference.Assemblies.Net461.All) +", referencedAssemblies:=Basic.Reference.Assemblies.Net461.References.All) ' Using Net461 to get a framework without ValueTuple diff --git a/src/Compilers/VisualBasic/Test/Symbol/Microsoft.CodeAnalysis.VisualBasic.Symbol.UnitTests.vbproj b/src/Compilers/VisualBasic/Test/Symbol/Microsoft.CodeAnalysis.VisualBasic.Symbol.UnitTests.vbproj index 72c9595f4978b..9184a955feb6a 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/Microsoft.CodeAnalysis.VisualBasic.Symbol.UnitTests.vbproj +++ b/src/Compilers/VisualBasic/Test/Symbol/Microsoft.CodeAnalysis.VisualBasic.Symbol.UnitTests.vbproj @@ -3,7 +3,7 @@ Library - $(NetRoslyn);net472 + $(NetRoslynNext);net472 @@ -16,9 +16,11 @@ - + + + diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/RefStructInterfacesTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/RefStructInterfacesTests.vb new file mode 100644 index 0000000000000..4d4b71b8779b6 --- /dev/null +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/RefStructInterfacesTests.vb @@ -0,0 +1,245 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.CodeAnalysis.VisualBasic.Symbols +Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE +Imports Roslyn.Test.Utilities + +Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests + + Public Class RefStructInterfacesTests + Inherits BasicTestBase + + Private Shared ReadOnly s_targetFrameworkSupportingByRefLikeGenerics As TargetFramework = TargetFramework.Net90 + + + Public Sub RuntimeCapability_01() + + Dim comp = CreateCompilation("", targetFramework:=s_targetFrameworkSupportingByRefLikeGenerics) + Assert.True(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)) + + comp = CreateCompilation("", targetFramework:=TargetFramework.DesktopLatestExtended) + Assert.False(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)) + + comp = CreateCompilation("", targetFramework:=TargetFramework.Net80) + Assert.False(comp.SupportsRuntimeCapability(RuntimeCapability.ByRefLikeGenerics)) + End Sub + + + Public Sub AllowsConstraint_01() + + Dim csSource = +" +public class A; + +public class C + where T : allows ref struct +{ +} + +public class D +{ + static public void M() where T : allows ref struct + { + System.Console.WriteLine(typeof(T)); + } +} +" + + Dim csCompilation = CreateCSharpCompilation(csSource, + parseOptions:=CSharp.CSharpParseOptions.Default.WithLanguageVersion(CSharp.LanguageVersion.Preview), + referencedAssemblies:=TargetFrameworkUtil.GetReferences(s_targetFrameworkSupportingByRefLikeGenerics)).EmitToImageReference() + + Dim source1 = + + + + + Dim comp1 = CreateCompilation(source1, targetFramework:=s_targetFrameworkSupportingByRefLikeGenerics, references:={csCompilation}, options:=TestOptions.DebugExe) + + Dim a = comp1.GetTypeByMetadataName("A`1") + AssertEx.Equal("A(Of T)", a.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)) + Assert.False(a.TypeParameters.Single().AllowsRefLikeType) + + Dim b = comp1.GetTypeByMetadataName("B`1") + AssertEx.Equal("B(Of S)", b.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)) + Assert.False(b.TypeParameters.Single().AllowsRefLikeType) + + Dim c = comp1.GetTypeByMetadataName("C`1") + AssertEx.Equal("C(Of T)", c.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)) + Assert.True(c.TypeParameters.Single().AllowsRefLikeType) + + c = b.BaseTypeNoUseSiteDiagnostics + AssertEx.Equal("C(Of S)", c.ToDisplayString(SymbolDisplayFormat.TestFormatWithConstraints)) + Assert.True(c.TypeParameters.Single().AllowsRefLikeType) + + CompileAndVerify( + comp1, + verify:=If(ExecutionConditionUtil.IsMonoOrCoreClr, Verification.Passes, Verification.Skipped), + expectedOutput:=If(ExecutionConditionUtil.IsMonoOrCoreClr, +"System.Int32 +Test +Done", Nothing)).VerifyDiagnostics() + End Sub + + + Public Sub AllowsConstraint_02() + + Dim csSource = +" +public class C +{ + public virtual void M() + where T : allows ref struct + { + } +} +" + + Dim csCompilation = CreateCSharpCompilation(csSource, + parseOptions:=CSharp.CSharpParseOptions.Default.WithLanguageVersion(CSharp.LanguageVersion.Preview), + referencedAssemblies:=TargetFrameworkUtil.GetReferences(s_targetFrameworkSupportingByRefLikeGenerics)).EmitToImageReference() + + Dim source1 = + + + + + Dim comp1 = CreateCompilation(source1, targetFramework:=s_targetFrameworkSupportingByRefLikeGenerics, references:={csCompilation}) + + Dim m = comp1.GetMember(Of MethodSymbol)("B.M") + Assert.False(m.TypeParameters.Single().AllowsRefLikeType) + Assert.True(m.OverriddenMethod.TypeParameters.Single().AllowsRefLikeType) + + comp1.AssertTheseDiagnostics( + +BC32077: 'Public Overrides Sub M(Of T)()' cannot override 'Public Overridable Overloads Sub M(Of T)()' because they differ by type parameter constraints. + Public Overrides Sub M(Of T) + ~ +) + End Sub + + + Public Sub AllowsConstraint_03() + + Dim csSource = +" +public interface IC +{ + public abstract void M() + where T : allows ref struct; +} +" + + Dim csCompilation = CreateCSharpCompilation(csSource, + parseOptions:=CSharp.CSharpParseOptions.Default.WithLanguageVersion(CSharp.LanguageVersion.Preview), + referencedAssemblies:=TargetFrameworkUtil.GetReferences(s_targetFrameworkSupportingByRefLikeGenerics)).EmitToImageReference() + + Dim source1 = + + + + + Dim comp1 = CreateCompilation(source1, targetFramework:=s_targetFrameworkSupportingByRefLikeGenerics, references:={csCompilation}) + comp1.AssertTheseDiagnostics( + +BC32078: 'Public Sub M(Of T)()' cannot implement 'IC.Sub M(Of T)()' because they differ by type parameter constraints. + Sub M(Of T) Implements IC.M + ~~~~ +) + + Dim m = comp1.GetMember(Of MethodSymbol)("B.M") + Assert.False(m.TypeParameters.Single().AllowsRefLikeType) + Assert.True(m.ExplicitInterfaceImplementations.Single().TypeParameters.Single().AllowsRefLikeType) + End Sub + + + Public Sub NoPiaEmbedding() + Dim csSource = +" +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +[assembly: ImportedFromTypeLib(""GeneralPIA.dll"")] +[assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] + +[ComImport()] +[Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58278"")] +public interface ITest29 +{ + void M21() where T1 : allows ref struct; +} +" + + Dim csCompilation = CreateCSharpCompilation(csSource, + parseOptions:=CSharp.CSharpParseOptions.Default.WithLanguageVersion(CSharp.LanguageVersion.Preview), + assemblyName:="Pia", + referencedAssemblies:=TargetFrameworkUtil.GetReferences(s_targetFrameworkSupportingByRefLikeGenerics)).EmitToImageReference(embedInteropTypes:=True) + + Dim sources1 = + + + + Dim validator As Action(Of ModuleSymbol) = Sub([module]) + DirectCast([module], PEModuleSymbol).Module.PretendThereArentNoPiaLocalTypes() + + Dim type2 = [module].GlobalNamespace.GetMember(Of PENamedTypeSymbol)("ITest29") + Assert.Equal(TypeKind.Interface, type2.TypeKind) + Dim method = type2.GetMember(Of PEMethodSymbol)("M21") + Dim tp = method.TypeParameters + Dim t1 = tp(0) + Assert.Equal("T1", t1.Name) + Assert.True(t1.AllowsRefLikeType) + End Sub + + Dim compilation1 = CreateCompilation( + sources1, + targetFramework:=s_targetFrameworkSupportingByRefLikeGenerics, + options:=TestOptions.DebugDll, + references:={csCompilation}) + + CompileAndVerify(compilation1, symbolValidator:=validator, verify:=Verification.Skipped).VerifyDiagnostics() + End Sub + End Class +End Namespace + diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb index 59b991849251c..798d74ecf6e0e 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WellKnownTypeValidationTests.vb @@ -493,6 +493,7 @@ End Namespace special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__VirtualStaticsInInterfaces OrElse special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__NumericIntPtr OrElse special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__ByRefFields OrElse + special = SpecialMember.System_Runtime_CompilerServices_RuntimeFeature__ByRefLikeGenerics OrElse special = SpecialMember.System_Runtime_CompilerServices_PreserveBaseOverridesAttribute__ctor OrElse special = SpecialMember.System_Runtime_CompilerServices_InlineArrayAttribute__ctor OrElse special = SpecialMember.System_ReadOnlySpan_T__ctor_Reference OrElse @@ -821,7 +822,9 @@ End Namespace WellKnownMember.System_ReadOnlySpan_T__ToArray, WellKnownMember.System_Span_T__CopyTo_Span_T, WellKnownMember.System_ReadOnlySpan_T__CopyTo_Span_T, - WellKnownMember.System_Collections_Immutable_ImmutableArray_T__AsSpan + WellKnownMember.System_Collections_Immutable_ImmutableArray_T__AsSpan, + WellKnownMember.System_Span_T__ctor_ref_T, + WellKnownMember.System_ReadOnlySpan_T__ctor_ref_readonly_T ' Not always available. Continue For End Select @@ -1026,7 +1029,9 @@ End Namespace WellKnownMember.System_ReadOnlySpan_T__ToArray, WellKnownMember.System_Span_T__CopyTo_Span_T, WellKnownMember.System_ReadOnlySpan_T__CopyTo_Span_T, - WellKnownMember.System_Collections_Immutable_ImmutableArray_T__AsSpan + WellKnownMember.System_Collections_Immutable_ImmutableArray_T__AsSpan, + WellKnownMember.System_Span_T__ctor_ref_T, + WellKnownMember.System_ReadOnlySpan_T__ctor_ref_readonly_T ' Not always available. Continue For End Select diff --git a/src/Dependencies/Collections/Internal/SegmentedArrayHelper.cs b/src/Dependencies/Collections/Internal/SegmentedArrayHelper.cs index bf108cfaf189c..ab4ffa67a1514 100644 --- a/src/Dependencies/Collections/Internal/SegmentedArrayHelper.cs +++ b/src/Dependencies/Collections/Internal/SegmentedArrayHelper.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Microsoft.CodeAnalysis.Collections.Internal diff --git a/src/Dependencies/Collections/SegmentedList`1.cs b/src/Dependencies/Collections/SegmentedList`1.cs index bf2bef8821287..4747f34ce1e75 100644 --- a/src/Dependencies/Collections/SegmentedList`1.cs +++ b/src/Dependencies/Collections/SegmentedList`1.cs @@ -1198,7 +1198,8 @@ public void Sort(Comparison comparison) if (_size > 1) { - SegmentedArray.Sort(_items, 0, _size, Comparer.Create(comparison)); + var segment = new SegmentedArraySegment(_items, 0, _size); + SegmentedArraySortHelper.Sort(segment, comparison); } _version++; } diff --git a/src/Dependencies/PooledObjects/ArrayBuilder.cs b/src/Dependencies/PooledObjects/ArrayBuilder.cs index b0246977a88b4..b1dce5fbdf91e 100644 --- a/src/Dependencies/PooledObjects/ArrayBuilder.cs +++ b/src/Dependencies/PooledObjects/ArrayBuilder.cs @@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.PooledObjects { [DebuggerDisplay("Count = {Count,nq}")] [DebuggerTypeProxy(typeof(ArrayBuilder<>.DebuggerProxy))] - internal sealed partial class ArrayBuilder : IReadOnlyCollection, IReadOnlyList + internal sealed partial class ArrayBuilder : IReadOnlyCollection, IReadOnlyList, ICollection { /// /// See for an explanation of this constant value. @@ -139,6 +139,12 @@ public T this[int index] } } + public bool IsReadOnly + => false; + + public bool IsEmpty + => Count == 0; + /// /// Write to slot . /// Fills in unallocated slots preceding the , if any. @@ -303,7 +309,12 @@ public void Sort(IComparer comparer) } public void Sort(Comparison compare) - => Sort(Comparer.Create(compare)); + { + if (this.Count <= 1) + return; + + Sort(Comparer.Create(compare)); + } public void Sort(int startIndex, IComparer comparer) { diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs index 7f5a193236ab7..c3fcbfbd57629 100644 --- a/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs +++ b/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs @@ -105,7 +105,7 @@ protected override IList FormatBasedOnEndToken(ParsedDocument docume root, [CommonFormattingHelpers.GetFormattingSpan(root, span.Value)], options, - rules: null, + rules: default, cancellationToken).GetTextChanges(cancellationToken); } diff --git a/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs b/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs index dc9511bf2b8d8..7963af9f6c2c6 100644 --- a/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs +++ b/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs @@ -7,7 +7,6 @@ using System.ComponentModel.Composition; using System.Linq; using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.CommentSelection; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Host.Mef; @@ -16,7 +15,6 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; diff --git a/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs b/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs index 9c56b5ff7ce90..b2d60950b3383 100644 --- a/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs +++ b/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs @@ -4,14 +4,11 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.DocumentationComments; -using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; -using Microsoft.VisualStudio.Text.Editor; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Utilities; diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs index 13f8e5ba66166..5726d27d96435 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel.Composition; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.Classification; diff --git a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs index aa1c6bdee8b93..d777fcd367c42 100644 --- a/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs +++ b/src/EditorFeatures/CSharp/EventHookup/EventHookupSessionManager_EventHookupSession.cs @@ -19,7 +19,6 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Shared.Utilities; -using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; using Roslyn.Utilities; diff --git a/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs b/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs index bd67876b2110c..0cb940aba6795 100644 --- a/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs +++ b/src/EditorFeatures/CSharp/Formatting/CSharpFormattingInteractionService.cs @@ -17,7 +17,6 @@ using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; -using Microsoft.VisualStudio.Text.Editor; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Formatting; diff --git a/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs b/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs index 35ec41c436d82..8e163ffa7583d 100644 --- a/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs +++ b/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs @@ -7,7 +7,6 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/AbstractPasteProcessor.cs b/src/EditorFeatures/CSharp/StringCopyPaste/AbstractPasteProcessor.cs index 00a57052a54ab..162aada98d09b 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/AbstractPasteProcessor.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/AbstractPasteProcessor.cs @@ -5,13 +5,8 @@ using System; using System.Collections.Immutable; using System.Linq; -using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.Indentation; -using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.Text.Shared.Extensions; using Microsoft.VisualStudio.Text; using Roslyn.Utilities; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/KnownSourcePasteProcessor.cs b/src/EditorFeatures/CSharp/StringCopyPaste/KnownSourcePasteProcessor.cs index 52b8c4ba21028..1fc0495cfd818 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/KnownSourcePasteProcessor.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/KnownSourcePasteProcessor.cs @@ -5,11 +5,7 @@ using System; using System.Collections.Immutable; using System.Linq; -using System.Threading; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs index 34c277b0d2faf..592925bdef8ac 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler.cs @@ -9,7 +9,6 @@ using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.StringCopyPaste; using Microsoft.CodeAnalysis.Host.Mef; @@ -27,7 +26,6 @@ using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; -using VSUtilities = Microsoft.VisualStudio.Utilities; namespace Microsoft.CodeAnalysis.Editor.CSharp.StringCopyPaste; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler_CutCopy.cs b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler_CutCopy.cs index 6417d40261d7c..b4b10da7c9c5c 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler_CutCopy.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteCommandHandler_CutCopy.cs @@ -3,19 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text; using System.Threading; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.StringCopyPaste; using Microsoft.CodeAnalysis.EmbeddedLanguages.VirtualChars; -using Microsoft.CodeAnalysis.ErrorReporting; -using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Commanding; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteData.cs b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteData.cs index d2dc1d9b78710..d183eb9652434 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteData.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteData.cs @@ -4,10 +4,6 @@ using System; using System.Collections.Immutable; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.CSharp.Syntax; using System.Diagnostics.CodeAnalysis; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteHelpers.cs b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteHelpers.cs index 1d90e23e29aab..6d9460ac71a2f 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteHelpers.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/StringCopyPasteHelpers.cs @@ -8,12 +8,9 @@ using System.Globalization; using System.Linq; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.InheritanceMargin; using Microsoft.CodeAnalysis.PooledObjects; -using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text.Shared.Extensions; using Microsoft.VisualStudio.Text; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/StringInfo.cs b/src/EditorFeatures/CSharp/StringCopyPaste/StringInfo.cs index 79c96f689c683..fa453c402f813 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/StringInfo.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/StringInfo.cs @@ -5,7 +5,6 @@ using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; diff --git a/src/EditorFeatures/CSharp/StringCopyPaste/UnknownSourcePasteProcessor.cs b/src/EditorFeatures/CSharp/StringCopyPaste/UnknownSourcePasteProcessor.cs index 05b75b0451d10..7cbaa57063359 100644 --- a/src/EditorFeatures/CSharp/StringCopyPaste/UnknownSourcePasteProcessor.cs +++ b/src/EditorFeatures/CSharp/StringCopyPaste/UnknownSourcePasteProcessor.cs @@ -5,11 +5,9 @@ using System; using System.Collections.Immutable; using System.Linq; -using System.Threading; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.Indentation; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; diff --git a/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs b/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs index 87d2286dad4dd..2fea0efdf67c0 100644 --- a/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/AddMissingImports/CSharpAddMissingImportsRefactoringProviderTests.cs @@ -16,370 +16,369 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.AddMissingImports +namespace Microsoft.CodeAnalysis.AddMissingImports; + +[UseExportProvider] +[Trait(Traits.Feature, Traits.Features.AddMissingImports)] +public class CSharpAddMissingImportsRefactoringProviderTests : AbstractCSharpCodeActionTest { - [UseExportProvider] - [Trait(Traits.Feature, Traits.Features.AddMissingImports)] - public class CSharpAddMissingImportsRefactoringProviderTests : AbstractCSharpCodeActionTest + protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) + => new CSharpAddMissingImportsRefactoringProvider(); + + protected override void InitializeWorkspace(EditorTestWorkspace workspace, TestParameters parameters) { - protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) - => new CSharpAddMissingImportsRefactoringProvider(); + // Treat the span being tested as the pasted span + var hostDocument = workspace.Documents.First(); + var pastedTextSpan = hostDocument.SelectedSpans.FirstOrDefault(); - protected override void InitializeWorkspace(EditorTestWorkspace workspace, TestParameters parameters) + if (!pastedTextSpan.IsEmpty) { - // Treat the span being tested as the pasted span - var hostDocument = workspace.Documents.First(); - var pastedTextSpan = hostDocument.SelectedSpans.FirstOrDefault(); + var pasteTrackingService = workspace.ExportProvider.GetExportedValue(); + + // This tests the paste tracking service's resiliancy to failing when multiple pasted spans are + // registered consecutively and that the last registered span wins. + pasteTrackingService.RegisterPastedTextSpan(hostDocument.GetTextBuffer(), default); + pasteTrackingService.RegisterPastedTextSpan(hostDocument.GetTextBuffer(), pastedTextSpan); + } + } - if (!pastedTextSpan.IsEmpty) + private Task TestInRegularAndScriptAsync( + string initialMarkup, string expectedMarkup, + bool placeSystemNamespaceFirst, bool separateImportDirectiveGroups) + { + var options = + new OptionsCollection(GetLanguage()) { - var pasteTrackingService = workspace.ExportProvider.GetExportedValue(); + { GenerationOptions.PlaceSystemNamespaceFirst, placeSystemNamespaceFirst }, + { GenerationOptions.SeparateImportDirectiveGroups, separateImportDirectiveGroups }, + }; + return TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: options); + } - // This tests the paste tracking service's resiliancy to failing when multiple pasted spans are - // registered consecutively and that the last registered span wins. - pasteTrackingService.RegisterPastedTextSpan(hostDocument.GetTextBuffer(), default); - pasteTrackingService.RegisterPastedTextSpan(hostDocument.GetTextBuffer(), pastedTextSpan); + [WpfFact] + public async Task AddMissingImports_AddImport_PasteContainsSingleMissingImport() + { + var code = """ + class C + { + public [|D|] Foo { get; } } - } - private Task TestInRegularAndScriptAsync( - string initialMarkup, string expectedMarkup, - bool placeSystemNamespaceFirst, bool separateImportDirectiveGroups) - { - var options = - new OptionsCollection(GetLanguage()) - { - { GenerationOptions.PlaceSystemNamespaceFirst, placeSystemNamespaceFirst }, - { GenerationOptions.SeparateImportDirectiveGroups, separateImportDirectiveGroups }, - }; - return TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: options); - } + namespace A + { + public class D { } + } + """; - [WpfFact] - public async Task AddMissingImports_AddImport_PasteContainsSingleMissingImport() - { - var code = """ - class C - { - public [|D|] Foo { get; } - } - - namespace A - { - public class D { } - } - """; - - var expected = """ - using A; - - class C - { - public D Foo { get; } - } - - namespace A - { - public class D { } - } - """; - - await TestInRegularAndScriptAsync(code, expected); - } + var expected = """ + using A; - [WpfFact] - public async Task AddMissingImports_AddImportsBelowSystem_PlaceSystemFirstPasteContainsMultipleMissingImports() - { - var code = """ - using System; - - class C - { - [|public D Foo { get; } - public E Bar { get; }|] - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - var expected = """ - using System; - using A; - using B; - - class C - { - public D Foo { get; } - public E Bar { get; } - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: true, separateImportDirectiveGroups: false); - } + class C + { + public D Foo { get; } + } - [WpfFact] - public async Task AddMissingImports_AddImportsAboveSystem_DoNotPlaceSystemFirstPasteContainsMultipleMissingImports() - { - var code = """ - using System; - - class C - { - [|public D Foo { get; } - public E Bar { get; }|] - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - var expected = """ - using A; - using B; - using System; - - class C - { - public D Foo { get; } - public E Bar { get; } - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: false, separateImportDirectiveGroups: false); - } + namespace A + { + public class D { } + } + """; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/pull/42221")] - public async Task AddMissingImports_AddImportsUngrouped_SeparateImportGroupsPasteContainsMultipleMissingImports() - { - var code = """ - using System; - - class C - { - [|public D Foo { get; } - public E Bar { get; }|] - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - var expected = """ - using A; - using B; - - using System; - - class C - { - public D Foo { get; } - public E Bar { get; } - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: false, separateImportDirectiveGroups: true); - } + await TestInRegularAndScriptAsync(code, expected); + } - [WpfFact] - public async Task AddMissingImports_PartialFix_PasteContainsFixableAndAmbiguousMissingImports() - { - var code = """ - class C - { - [|public D Foo { get; } - public E Bar { get; }|] - } - - namespace A - { - public class D { } - } - - namespace B - { - public class D { } - public class E { } - } - """; - - var expected = """ - using B; - - class C - { - public D Foo { get; } - public E Bar { get; } - } - - namespace A - { - public class D { } - } - - namespace B - { - public class D { } - public class E { } - } - """; - - await TestInRegularAndScriptAsync(code, expected); - } + [WpfFact] + public async Task AddMissingImports_AddImportsBelowSystem_PlaceSystemFirstPasteContainsMultipleMissingImports() + { + var code = """ + using System; - [WpfFact] - public async Task AddMissingImports_NoAction_NoPastedSpan() - { - var code = """ - class C - { - public D[||] Foo { get; } - } - - namespace A - { - public class D { } - } - """; - - await TestMissingInRegularAndScriptAsync(code); - } + class C + { + [|public D Foo { get; } + public E Bar { get; }|] + } - [WpfFact] - public async Task AddMissingImports_NoAction_PasteIsNotMissingImports() - { - var code = """ - class [|C|] - { - public D Foo { get; } - } - - namespace A - { - public class D { } - } - """; - - await TestMissingInRegularAndScriptAsync(code); - } + namespace A + { + public class D { } + } - [WpfFact] - public async Task AddMissingImports_NoAction_PasteContainsAmibiguousMissingImport() - { - var code = """ - class C - { - public [|D|] Foo { get; } - } - - namespace A - { - public class D { } - } - - namespace B - { - public class D { } - } - """; - - await TestMissingInRegularAndScriptAsync(code); - } + namespace B + { + public class E { } + } + """; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/31768")] - public async Task AddMissingImports_AddMultipleImports_NoPreviousImports() - { - var code = """ - class C - { - [|public D Foo { get; } - public E Bar { get; }|] - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - var expected = """ - using A; - using B; - - class C - { - public D Foo { get; } - public E Bar { get; } - } - - namespace A - { - public class D { } - } - - namespace B - { - public class E { } - } - """; - - await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: false, separateImportDirectiveGroups: false); - } + var expected = """ + using System; + using A; + using B; + + class C + { + public D Foo { get; } + public E Bar { get; } + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: true, separateImportDirectiveGroups: false); + } + + [WpfFact] + public async Task AddMissingImports_AddImportsAboveSystem_DoNotPlaceSystemFirstPasteContainsMultipleMissingImports() + { + var code = """ + using System; + + class C + { + [|public D Foo { get; } + public E Bar { get; }|] + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + var expected = """ + using A; + using B; + using System; + + class C + { + public D Foo { get; } + public E Bar { get; } + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: false, separateImportDirectiveGroups: false); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/pull/42221")] + public async Task AddMissingImports_AddImportsUngrouped_SeparateImportGroupsPasteContainsMultipleMissingImports() + { + var code = """ + using System; + + class C + { + [|public D Foo { get; } + public E Bar { get; }|] + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + var expected = """ + using A; + using B; + + using System; + + class C + { + public D Foo { get; } + public E Bar { get; } + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: false, separateImportDirectiveGroups: true); + } + + [WpfFact] + public async Task AddMissingImports_PartialFix_PasteContainsFixableAndAmbiguousMissingImports() + { + var code = """ + class C + { + [|public D Foo { get; } + public E Bar { get; }|] + } + + namespace A + { + public class D { } + } + + namespace B + { + public class D { } + public class E { } + } + """; + + var expected = """ + using B; + + class C + { + public D Foo { get; } + public E Bar { get; } + } + + namespace A + { + public class D { } + } + + namespace B + { + public class D { } + public class E { } + } + """; + + await TestInRegularAndScriptAsync(code, expected); + } + + [WpfFact] + public async Task AddMissingImports_NoAction_NoPastedSpan() + { + var code = """ + class C + { + public D[||] Foo { get; } + } + + namespace A + { + public class D { } + } + """; + + await TestMissingInRegularAndScriptAsync(code); + } + + [WpfFact] + public async Task AddMissingImports_NoAction_PasteIsNotMissingImports() + { + var code = """ + class [|C|] + { + public D Foo { get; } + } + + namespace A + { + public class D { } + } + """; + + await TestMissingInRegularAndScriptAsync(code); + } + + [WpfFact] + public async Task AddMissingImports_NoAction_PasteContainsAmibiguousMissingImport() + { + var code = """ + class C + { + public [|D|] Foo { get; } + } + + namespace A + { + public class D { } + } + + namespace B + { + public class D { } + } + """; + + await TestMissingInRegularAndScriptAsync(code); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/31768")] + public async Task AddMissingImports_AddMultipleImports_NoPreviousImports() + { + var code = """ + class C + { + [|public D Foo { get; } + public E Bar { get; }|] + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + var expected = """ + using A; + using B; + + class C + { + public D Foo { get; } + public E Bar { get; } + } + + namespace A + { + public class D { } + } + + namespace B + { + public class E { } + } + """; + + await TestInRegularAndScriptAsync(code, expected, placeSystemNamespaceFirst: false, separateImportDirectiveGroups: false); } } diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs index ab7bf1bd81842..a4afeb967d972 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBraceCompletionTests.cs @@ -6,22 +6,21 @@ using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using static Microsoft.CodeAnalysis.BraceCompletion.AbstractBraceCompletionService; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion; + +[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] +public class AutomaticBraceCompletionTests : AbstractAutomaticBraceCompletionTests { - [Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] - public class AutomaticBraceCompletionTests : AbstractAutomaticBraceCompletionTests + [WpfFact] + public void WithExpressionBracesSameLine() { - [WpfFact] - public void WithExpressionBracesSameLine() - { - var code = @" + var code = @" class C { void M(C c) @@ -30,7 +29,7 @@ void M(C c) } }"; - var expected = @" + var expected = @" class C { void M(C c) @@ -38,17 +37,17 @@ void M(C c) c = c with { } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expected); - } + CheckStart(session.Session); + CheckText(session.Session, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/47381")] - public void ImplicitObjectCreationExpressionBracesSameLine() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/47381")] + public void ImplicitObjectCreationExpressionBracesSameLine() + { + var code = @" class C { void M(C c) @@ -57,7 +56,7 @@ void M(C c) } }"; - var expected = @" + var expected = @" class C { void M(C c) @@ -65,17 +64,17 @@ void M(C c) c = new() { } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expected); - } + CheckStart(session.Session); + CheckText(session.Session, expected); + } - [WpfFact] - public void WithExpressionBracesSameLine_Enter() - { - var code = @" + [WpfFact] + public void WithExpressionBracesSameLine_Enter() + { + var code = @" class C { void M(C c) @@ -83,7 +82,7 @@ void M(C c) c = c with $$ } }"; - var expected = @" + var expected = @" class C { void M(C c) @@ -94,340 +93,340 @@ void M(C c) } } }"; - using var session = CreateSession(code); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + using var session = CreateSession(code); + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact] - public void Creation() - { - using var session = CreateSession("$$"); - Assert.NotNull(session); - } + [WpfFact] + public void Creation() + { + using var session = CreateSession("$$"); + Assert.NotNull(session); + } - [WpfFact] - public void InvalidLocation_String() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_String() + { + var code = @"class C { string s = ""$$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void InvalidLocation_String2() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_String2() + { + var code = @"class C { string s = @"" $$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void ValidLocation_InterpolatedString1() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString1() + { + var code = @"class C { string s = $""$$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void ValidLocation_InterpolatedString2() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString2() + { + var code = @"class C { string s = $@""$$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void ValidLocation_InterpolatedString3() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString3() + { + var code = @"class C { string x = ""goo"" string s = $""{x} $$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void ValidLocation_InterpolatedString4() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString4() + { + var code = @"class C { string x = ""goo"" string s = $@""{x} $$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void ValidLocation_InterpolatedString5() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString5() + { + var code = @"class C { string s = $""{{$$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void ValidLocation_InterpolatedString6() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString6() + { + var code = @"class C { string s = $""{}$$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void ValidLocation_InterpolatedString7() - { - var code = @"class C + [WpfFact] + public void ValidLocation_InterpolatedString7() + { + var code = @"class C { string s = $""{}$$ }"; - var expected = @"class C + var expected = @"class C { string s = $""{}{ } }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 0, expected); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckReturn(session.Session, 0, expected); + } - [WpfFact] - public void InvalidLocation_InterpolatedString1() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_InterpolatedString1() + { + var code = @"class C { string s = @""$$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void InvalidLocation_InterpolatedString2() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_InterpolatedString2() + { + var code = @"class C { string s = ""$$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void InvalidLocation_Comment() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_Comment() + { + var code = @"class C { //$$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void InvalidLocation_Comment2() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_Comment2() + { + var code = @"class C { /* $$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void InvalidLocation_Comment3() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_Comment3() + { + var code = @"class C { /// $$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void InvalidLocation_Comment4() - { - var code = @"class C + [WpfFact] + public void InvalidLocation_Comment4() + { + var code = @"class C { /** $$ }"; - using var session = CreateSession(code); - Assert.Null(session); - } + using var session = CreateSession(code); + Assert.Null(session); + } - [WpfFact] - public void MultiLine_Comment() - { - var code = @"class C + [WpfFact] + public void MultiLine_Comment() + { + var code = @"class C { void Method() { /* */$$ } }"; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - [WpfFact] - public void MultiLine_DocComment() - { - var code = @"class C + [WpfFact] + public void MultiLine_DocComment() + { + var code = @"class C { void Method() { /** */$$ } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - } + CheckStart(session.Session); + } - [WpfFact] - public void String1() - { - var code = @"class C + [WpfFact] + public void String1() + { + var code = @"class C { void Method() { var s = """"$$ } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - } + CheckStart(session.Session); + } - [WpfFact] - public void String2() - { - var code = @"class C + [WpfFact] + public void String2() + { + var code = @"class C { void Method() { var s = @""""$$ } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - } + CheckStart(session.Session); + } - [WpfFact] - public void Class_OpenBrace() - { - var code = @"class C $$"; + [WpfFact] + public void Class_OpenBrace() + { + var code = @"class C $$"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - } + CheckStart(session.Session); + } - [WpfFact] - public void Class_Delete() - { - var code = @"class C $$"; + [WpfFact] + public void Class_Delete() + { + var code = @"class C $$"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } + CheckStart(session.Session); + CheckBackspace(session.Session); + } - [WpfFact] - public void Class_Tab() - { - var code = @"class C $$"; + [WpfFact] + public void Class_Tab() + { + var code = @"class C $$"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } + CheckStart(session.Session); + CheckTab(session.Session); + } - [WpfFact] - public void Class_CloseBrace() - { - var code = @"class C $$"; + [WpfFact] + public void Class_CloseBrace() + { + var code = @"class C $$"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } + CheckStart(session.Session); + CheckOverType(session.Session); + } - [WpfFact] - public void Method_OpenBrace_Multiple() - { - var code = @"class C + [WpfFact] + public void Method_OpenBrace_Multiple() + { + var code = @"class C { void Method() { $$ }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - } + CheckStart(session.Session); + } - [WpfFact] - public void Class_OpenBrace_Enter() - { - var code = @"class C $$"; + [WpfFact] + public void Class_OpenBrace_Enter() + { + var code = @"class C $$"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 4); - } + CheckStart(session.Session); + CheckReturn(session.Session, 4); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] - public void WithExpression() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/47438")] + public void WithExpression() + { + var code = @" record C { void M() @@ -436,7 +435,7 @@ void M() } }"; - var expectedBeforeReturn = @" + var expectedBeforeReturn = @" record C { void M() @@ -445,7 +444,7 @@ void M() } }"; - var expectedAfterReturn = @" + var expectedAfterReturn = @" record C { void M() @@ -456,18 +455,18 @@ void M() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expectedAfterReturn); - } + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expectedAfterReturn); + } - [WpfFact] - public void RecursivePattern() - { - var code = @" + [WpfFact] + public void RecursivePattern() + { + var code = @" class C { void M() @@ -476,7 +475,7 @@ void M() } }"; - var expectedBeforeReturn = @" + var expectedBeforeReturn = @" class C { void M() @@ -485,7 +484,7 @@ void M() } }"; - var expectedAfterReturn = @" + var expectedAfterReturn = @" class C { void M() @@ -496,18 +495,18 @@ void M() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expectedAfterReturn); - } + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expectedAfterReturn); + } - [WpfFact] - public void RecursivePattern_Nested() - { - var code = @" + [WpfFact] + public void RecursivePattern_Nested() + { + var code = @" class C { void M() @@ -516,7 +515,7 @@ void M() } }"; - var expectedBeforeReturn = @" + var expectedBeforeReturn = @" class C { void M() @@ -525,7 +524,7 @@ void M() } }"; - var expectedAfterReturn = @" + var expectedAfterReturn = @" class C { void M() @@ -536,18 +535,18 @@ void M() } } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expectedAfterReturn); - } + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expectedAfterReturn); + } - [WpfFact] - public void RecursivePattern_Parentheses1() - { - var code = @" + [WpfFact] + public void RecursivePattern_Parentheses1() + { + var code = @" class C { void M() @@ -555,7 +554,7 @@ void M() _ = this is { Name: $$ } } }"; - var expected = @" + var expected = @" class C { void M() @@ -564,17 +563,17 @@ void M() } }"; - using var session = CreateSession(EditorTestWorkspace.CreateCSharp(code), '(', ')'); - Assert.NotNull(session); + using var session = CreateSession(EditorTestWorkspace.CreateCSharp(code), '(', ')'); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expected); - } + CheckStart(session.Session); + CheckText(session.Session, expected); + } - [WpfFact] - public void RecursivePattern_Parentheses2() - { - var code = @" + [WpfFact] + public void RecursivePattern_Parentheses2() + { + var code = @" class C { void M() @@ -582,7 +581,7 @@ void M() _ = this is { Name: { Length: (> 3) and $$ } } } }"; - var expected = @" + var expected = @" class C { void M() @@ -591,17 +590,17 @@ void M() } }"; - using var session = CreateSession(EditorTestWorkspace.CreateCSharp(code), '(', ')'); - Assert.NotNull(session); + using var session = CreateSession(EditorTestWorkspace.CreateCSharp(code), '(', ')'); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expected); - } + CheckStart(session.Session); + CheckText(session.Session, expected); + } - [WpfFact] - public void RecursivePattern_FollowedByInvocation() - { - var code = @" + [WpfFact] + public void RecursivePattern_FollowedByInvocation() + { + var code = @" class C { void M() @@ -611,7 +610,7 @@ void M() } }"; - var expectedBeforeReturn = @" + var expectedBeforeReturn = @" class C { void M() @@ -621,7 +620,7 @@ void M() } }"; - var expectedAfterReturn = @" + var expectedAfterReturn = @" class C { void M() @@ -633,18 +632,18 @@ void M() M(); } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expectedAfterReturn); - } + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expectedAfterReturn); + } - [WpfFact] - public void RecursivePattern_WithInvocation_FollowedByInvocation() - { - var code = @" + [WpfFact] + public void RecursivePattern_WithInvocation_FollowedByInvocation() + { + var code = @" class C { void M() @@ -654,7 +653,7 @@ void M() } }"; - var expectedBeforeReturn = @" + var expectedBeforeReturn = @" class C { void M() @@ -664,7 +663,7 @@ void M() } }"; - var expectedAfterReturn = @" + var expectedAfterReturn = @" class C { void M() @@ -676,18 +675,18 @@ void M() M(); } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expectedAfterReturn); - } + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expectedAfterReturn); + } - [WpfFact] - public void SwitchExpression() - { - var code = @" + [WpfFact] + public void SwitchExpression() + { + var code = @" class C { void M() @@ -696,7 +695,7 @@ void M() } }"; - var expectedBeforeReturn = @" + var expectedBeforeReturn = @" class C { void M() @@ -705,7 +704,7 @@ void M() } }"; - var expectedAfterReturn = @" + var expectedAfterReturn = @" class C { void M() @@ -716,18 +715,18 @@ void M() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expectedAfterReturn); - } + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expectedAfterReturn); + } - [WpfFact] - public void Class_ObjectInitializer_OpenBrace_Enter() - { - var code = @"using System.Collections.Generic; + [WpfFact] + public void Class_ObjectInitializer_OpenBrace_Enter() + { + var code = @"using System.Collections.Generic; class C { @@ -737,7 +736,7 @@ class C }; }"; - var expected = @"using System.Collections.Generic; + var expected = @"using System.Collections.Generic; class C { @@ -749,17 +748,17 @@ class C } }; }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void Collection_Initializer_OpenBraceOnSameLine_Enter() - { - var code = @"using System.Collections.Generic; + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void Collection_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"using System.Collections.Generic; class C { @@ -769,7 +768,7 @@ public void man() } }"; - var expected = @"using System.Collections.Generic; + var expected = @"using System.Collections.Generic; class C { @@ -780,22 +779,22 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void Collection_Initializer_OpenBraceOnDifferentLine_Enter() - { - var code = @"using System.Collections.Generic; + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void Collection_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"using System.Collections.Generic; class C { @@ -805,7 +804,7 @@ public void man() } }"; - var expected = @"using System.Collections.Generic; + var expected = @"using System.Collections.Generic; class C { @@ -817,17 +816,17 @@ public void man() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void Object_Initializer_OpenBraceOnSameLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void Object_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C { public void man() { @@ -840,7 +839,7 @@ class Goo public int bar; }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -854,22 +853,22 @@ class Goo { public int bar; }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void Object_Initializer_OpenBraceOnDifferentLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void Object_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C { public void man() { @@ -882,7 +881,7 @@ class Goo public int bar; }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -897,17 +896,17 @@ class Goo { public int bar; }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void ArrayImplicit_Initializer_OpenBraceOnSameLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void ArrayImplicit_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C { public void man() { @@ -915,7 +914,7 @@ public void man() } }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -924,22 +923,22 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void ArrayImplicit_Initializer_OpenBraceOnDifferentLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void ArrayImplicit_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C { public void man() { @@ -947,7 +946,7 @@ public void man() } }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -957,17 +956,17 @@ public void man() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void ArrayExplicit1_Initializer_OpenBraceOnSameLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void ArrayExplicit1_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C { public void man() { @@ -975,7 +974,7 @@ public void man() } }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -984,22 +983,22 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void ArrayExplicit1_Initializer_OpenBraceOnDifferentLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void ArrayExplicit1_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C { public void man() { @@ -1007,7 +1006,7 @@ public void man() } }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -1017,17 +1016,17 @@ public void man() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void ArrayExplicit2_Initializer_OpenBraceOnSameLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void ArrayExplicit2_Initializer_OpenBraceOnSameLine_Enter() + { + var code = @"class C { public void man() { @@ -1035,7 +1034,7 @@ public void man() } }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -1044,21 +1043,21 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, false) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] - public void ArrayExplicit2_Initializer_OpenBraceOnDifferentLine_Enter() - { - var code = @"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1070773")] + public void ArrayExplicit2_Initializer_OpenBraceOnDifferentLine_Enter() + { + var code = @"class C { public void man() { @@ -1066,7 +1065,7 @@ public void man() } }"; - var expected = @"class C + var expected = @"class C { public void man() { @@ -1076,94 +1075,94 @@ public void man() } } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/3447")] - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/850540")] - public void BlockIndentationWithAutomaticBraceFormattingDisabled() - { - var code = @"class C + [WorkItem("https://github.com/dotnet/roslyn/issues/3447")] + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/850540")] + public void BlockIndentationWithAutomaticBraceFormattingDisabled() + { + var code = @"class C { public void X() $$ }"; - var expected = @"class C + var expected = @"class C { public void X() {} }"; - var expectedAfterReturn = @"class C + var expectedAfterReturn = @"class C { public void X() { } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { AutoFormattingOptionsStorage.FormatOnCloseBrace, false }, - { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.Block }, - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { AutoFormattingOptionsStorage.FormatOnCloseBrace, false }, + { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.Block }, + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); + CheckStart(session.Session); + Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); - CheckReturn(session.Session, 4, expectedAfterReturn); - } + CheckReturn(session.Session, 4, expectedAfterReturn); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/2224")] - public void NoSmartOrBlockIndentationWithAutomaticBraceFormattingDisabled() - { - var code = @"namespace NS1 + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/2224")] + public void NoSmartOrBlockIndentationWithAutomaticBraceFormattingDisabled() + { + var code = @"namespace NS1 { public class C1 $$ }"; - var expected = @"namespace NS1 + var expected = @"namespace NS1 { public class C1 { } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.None }, - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.None }, + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); - } + CheckStart(session.Session); + Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/2330")] - public void BlockIndentationWithAutomaticBraceFormatting() - { - var code = @"namespace NS1 + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/2330")] + public void BlockIndentationWithAutomaticBraceFormatting() + { + var code = @"namespace NS1 { public class C1 $$ }"; - var expected = @"namespace NS1 + var expected = @"namespace NS1 { public class C1 { } }"; - var expectedAfterReturn = @"namespace NS1 + var expectedAfterReturn = @"namespace NS1 { public class C1 { @@ -1171,24 +1170,24 @@ public class C1 } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.Block }, - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.Block }, + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); + CheckStart(session.Session); + Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); - CheckReturn(session.Session, 8, expectedAfterReturn); - } + CheckReturn(session.Session, 8, expectedAfterReturn); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/2330")] - public void BlockIndentationWithAutomaticBraceFormattingSecondSet() - { - var code = @"namespace NS1 + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/2330")] + public void BlockIndentationWithAutomaticBraceFormattingSecondSet() + { + var code = @"namespace NS1 { public class C1 { public class C2 $$ @@ -1196,7 +1195,7 @@ public class C1 } }"; - var expected = @"namespace NS1 + var expected = @"namespace NS1 { public class C1 { public class C2 { } @@ -1204,7 +1203,7 @@ public class C1 } }"; - var expectedAfterReturn = @"namespace NS1 + var expectedAfterReturn = @"namespace NS1 { public class C1 { public class C2 { @@ -1214,24 +1213,24 @@ public class C1 } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.Block }, - }; + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.Block }, + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); + CheckStart(session.Session); + Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); - CheckReturn(session.Session, 8, expectedAfterReturn); - } + CheckReturn(session.Session, 8, expectedAfterReturn); + } - [WpfFact] - public void DoesNotFormatInsideBracePairInInitializers() - { - var code = @"class C + [WpfFact] + public void DoesNotFormatInsideBracePairInInitializers() + { + var code = @"class C { void M() { @@ -1239,47 +1238,47 @@ void M() } }"; - var expected = @"class C + var expected = @"class C { void M() { var x = new int[] {} } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - CheckText(session.Session, expected); - } + CheckStart(session.Session); + CheckText(session.Session, expected); + } - [WpfFact] - public void DoesNotFormatOnReturnWithNonWhitespaceInBetween() - { - var code = @"class C $$"; + [WpfFact] + public void DoesNotFormatOnReturnWithNonWhitespaceInBetween() + { + var code = @"class C $$"; - var expected = @"class C { dd + var expected = @"class C { dd }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "dd"); - CheckReturn(session.Session, 0, expected); - } + CheckStart(session.Session); + Type(session.Session, "dd"); + CheckReturn(session.Session, 0, expected); + } - [WpfFact] - public void CurlyBraceFormattingInsideLambdaInsideInterpolation() - { - var code = @"class C + [WpfFact] + public void CurlyBraceFormattingInsideLambdaInsideInterpolation() + { + var code = @"class C { void M(string[] args) { var s = $""{ args.Select(a => $$)}"" } }"; - var expectedAfterStart = @"class C + var expectedAfterStart = @"class C { void M(string[] args) { @@ -1287,56 +1286,56 @@ void M(string[] args) } }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); - Assert.Equal(expectedAfterStart, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); - } + CheckStart(session.Session); + Assert.Equal(expectedAfterStart, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); + } - [WpfFact] - public void CurlyBraceFormatting_DoesNotAddNewLineWhenAlreadyExists() - { - var code = @"class C $$"; + [WpfFact] + public void CurlyBraceFormatting_DoesNotAddNewLineWhenAlreadyExists() + { + var code = @"class C $$"; - var expected = @"class C + var expected = @"class C { }"; - using var session = CreateSession(code); - Assert.NotNull(session); + using var session = CreateSession(code); + Assert.NotNull(session); - CheckStart(session.Session); + CheckStart(session.Session); - // Sneakily insert a new line between the braces. - var buffer = session.Session.SubjectBuffer; - buffer.Insert(10, Environment.NewLine); + // Sneakily insert a new line between the braces. + var buffer = session.Session.SubjectBuffer; + buffer.Insert(10, Environment.NewLine); - CheckReturn(session.Session, 4, expected); - } + CheckReturn(session.Session, 4, expected); + } - [WpfFact] - public void CurlyBraceFormatting_InsertsCorrectNewLine() - { - var code = @"class C $$"; + [WpfFact] + public void CurlyBraceFormatting_InsertsCorrectNewLine() + { + var code = @"class C $$"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { FormattingOptions2.NewLine, "\r" } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { FormattingOptions2.NewLine, "\r" } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 4, result: "class C\r{\r\r}"); - } + CheckStart(session.Session); + CheckReturn(session.Session, 4, result: "class C\r{\r\r}"); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void WithInitializer_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void WithInitializer_Enter(bool bracesOnNewLine) + { + var code = @" record R { public void man(R r) @@ -1344,7 +1343,7 @@ public void man(R r) var r2 = r with $$ } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" record R { public void man(R r) @@ -1364,22 +1363,22 @@ public void man(R r) } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void PropertyPatternClause_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void PropertyPatternClause_Enter(bool bracesOnNewLine) + { + var code = @" class C { public void man() @@ -1388,7 +1387,7 @@ public void man() } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" class C { public void man() @@ -1408,22 +1407,22 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ObjectCollectionArrayInitializers, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, bracesOnNewLine ? 16 : 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, bracesOnNewLine ? 16 : 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void Accessor_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void Accessor_Enter(bool bracesOnNewLine) + { + var code = @" class C { public int I @@ -1432,7 +1431,7 @@ public int I } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" class C { public int I @@ -1452,22 +1451,22 @@ public int I } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.Accessors, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.Accessors, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void AnonymousMethod_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void AnonymousMethod_Enter(bool bracesOnNewLine) + { + var code = @" class C { public void man() @@ -1476,7 +1475,7 @@ public void man() } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" class C { public void man() @@ -1496,22 +1495,22 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.AnonymousMethods, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.AnonymousMethods, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void AnonymousType_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void AnonymousType_Enter(bool bracesOnNewLine) + { + var code = @" class C { public void man() @@ -1520,7 +1519,7 @@ public void man() } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" class C { public void man() @@ -1540,22 +1539,22 @@ public void man() } } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.AnonymousTypes, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.AnonymousTypes, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void If_OpenBraceOnSameLine_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void If_OpenBraceOnSameLine_Enter(bool bracesOnNewLine) + { + var code = @" class C { public void man() @@ -1564,7 +1563,7 @@ public void man() } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" class C { public void man() @@ -1585,22 +1584,22 @@ public void man() } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] - [WpfTheory, CombinatorialData] - public void Else_OpenBraceOnSameLine_Enter(bool bracesOnNewLine) - { - var code = @" + [WorkItem("https://github.com/dotnet/roslyn/issues/50275")] + [WpfTheory, CombinatorialData] + public void Else_OpenBraceOnSameLine_Enter(bool bracesOnNewLine) + { + var code = @" class C { public void man() @@ -1611,7 +1610,7 @@ public void man() } }"; - var expected = bracesOnNewLine ? @" + var expected = bracesOnNewLine ? @" class C { public void man() @@ -1636,52 +1635,51 @@ public void man() } }"; - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, bracesOnNewLine) } - }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { CSharpFormattingOptions2.NewLineBeforeOpenBrace, CSharpFormattingOptions2.NewLineBeforeOpenBrace.DefaultValue.WithFlagValue(NewLineBeforeOpenBracePlacement.ControlBlocks, bracesOnNewLine) } + }; + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - CheckReturn(session.Session, 12, expected); - } + CheckStart(session.Session); + CheckReturn(session.Session, 12, expected); + } - [WpfFact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1758005")] - public void NoFormattingAfterNewlineIfOptionsDisabled() - { - var code = @"namespace NS1 + [WpfFact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1758005")] + public void NoFormattingAfterNewlineIfOptionsDisabled() + { + var code = @"namespace NS1 $$"; - var expected = @"namespace NS1 + var expected = @"namespace NS1 {}"; - var expectedAfterReturn = @"namespace NS1 + var expectedAfterReturn = @"namespace NS1 { }"; - // Those option ensures no additional formatting would happen around added braces, including indention of added newline - var globalOptions = new OptionsCollection(LanguageNames.CSharp) - { - { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.None }, - { AutoFormattingOptionsStorage.FormatOnCloseBrace, false }, - }; + // Those option ensures no additional formatting would happen around added braces, including indention of added newline + var globalOptions = new OptionsCollection(LanguageNames.CSharp) + { + { FormattingOptions2.SmartIndent, FormattingOptions2.IndentStyle.None }, + { AutoFormattingOptionsStorage.FormatOnCloseBrace, false }, + }; - using var session = CreateSession(code, globalOptions); - Assert.NotNull(session); + using var session = CreateSession(code, globalOptions); + Assert.NotNull(session); - CheckStart(session.Session); - Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); + CheckStart(session.Session); + Assert.Equal(expected, session.Session.SubjectBuffer.CurrentSnapshot.GetText()); - CheckReturn(session.Session, 0, expectedAfterReturn); - } + CheckReturn(session.Session, 0, expectedAfterReturn); + } - internal static Holder CreateSession(string code, OptionsCollection? globalOptions = null) - { - return CreateSession( - EditorTestWorkspace.CreateCSharp(code), - CurlyBrace.OpenCharacter, CurlyBrace.CloseCharacter, globalOptions); - } + internal static Holder CreateSession(string code, OptionsCollection? globalOptions = null) + { + return CreateSession( + EditorTestWorkspace.CreateCSharp(code), + CurlyBrace.OpenCharacter, CurlyBrace.CloseCharacter, globalOptions); } } diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs index 9cd8e622cbcb8..253d41a7cdc19 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs @@ -4,329 +4,326 @@ #nullable disable -using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using static Microsoft.CodeAnalysis.BraceCompletion.AbstractBraceCompletionService; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion; + +[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] +public class AutomaticBracketCompletionTests : AbstractAutomaticBraceCompletionTests { - [Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] - public class AutomaticBracketCompletionTests : AbstractAutomaticBraceCompletionTests + [WpfFact] + public void Creation() { - [WpfFact] - public void Creation() - { - using var session = CreateSession("$$"); - Assert.NotNull(session); - } - - [WpfFact] - public void Attribute_TopLevel() - { - using var session = CreateSession("$$"); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void Attribute_TopLevel2() - { - using var session = CreateSession("using System;$$"); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void InvalidLocation_String() - { - var code = """ - class C - { - string s = "$$ - } - """; - using var session = CreateSession(code); - Assert.Null(session); - } - - [WpfFact] - public void InvalidLocation_String2() - { - var code = """ - class C - { - string s = @" - $$ - } - """; - using var session = CreateSession(code); - Assert.Null(session); - } - - [WpfFact] - public void InvalidLocation_Comment() - { - var code = """ - class C - { - //$$ - } - """; - using var session = CreateSession(code); - Assert.Null(session); - } - - [WpfFact] - public void InvalidLocation_Comment2() - { - var code = """ - class C - { - /* $$ - } - """; - using var session = CreateSession(code); - Assert.Null(session); - } - - [WpfFact] - public void InvalidLocation_Comment3() - { - var code = """ - class C - { - /// $$ - } - """; - using var session = CreateSession(code); - Assert.Null(session); - } - - [WpfFact] - public void InvalidLocation_Comment4() - { - var code = """ - class C - { - /** $$ - } - """; - using var session = CreateSession(code); - Assert.Null(session); - } - - [WpfFact] - public void MultiLine_Comment() - { - var code = """ - class C - { - void Method() - { - /* */$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void MultiLine_DocComment() - { - var code = """ - class C + using var session = CreateSession("$$"); + Assert.NotNull(session); + } + + [WpfFact] + public void Attribute_TopLevel() + { + using var session = CreateSession("$$"); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void Attribute_TopLevel2() + { + using var session = CreateSession("using System;$$"); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void InvalidLocation_String() + { + var code = """ + class C + { + string s = "$$ + } + """; + using var session = CreateSession(code); + Assert.Null(session); + } + + [WpfFact] + public void InvalidLocation_String2() + { + var code = """ + class C + { + string s = @" + $$ + } + """; + using var session = CreateSession(code); + Assert.Null(session); + } + + [WpfFact] + public void InvalidLocation_Comment() + { + var code = """ + class C + { + //$$ + } + """; + using var session = CreateSession(code); + Assert.Null(session); + } + + [WpfFact] + public void InvalidLocation_Comment2() + { + var code = """ + class C + { + /* $$ + } + """; + using var session = CreateSession(code); + Assert.Null(session); + } + + [WpfFact] + public void InvalidLocation_Comment3() + { + var code = """ + class C + { + /// $$ + } + """; + using var session = CreateSession(code); + Assert.Null(session); + } + + [WpfFact] + public void InvalidLocation_Comment4() + { + var code = """ + class C + { + /** $$ + } + """; + using var session = CreateSession(code); + Assert.Null(session); + } + + [WpfFact] + public void MultiLine_Comment() + { + var code = """ + class C + { + void Method() { - void Method() - { - /** */$$ - } + /* */$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void String1() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void MultiLine_DocComment() + { + var code = """ + class C + { + void Method() { - void Method() - { - var s = ""$$ - } + /** */$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void String2() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void String1() + { + var code = """ + class C + { + void Method() { - void Method() - { - var s = @""$$ - } + var s = ""$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void Attribute_OpenBracket() - { - var code = """ - $$ - class C { } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void Attribute_OpenBracket_Delete() - { - var code = """ - $$ - class C { } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void Attribute_OpenBracket_Tab() - { - var code = """ - $$ - class C { } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void Attribute_OpenBracket_CloseBracket() - { - var code = """ - $$ - class C { } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void Array_Multiple_Invalid() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void String2() + { + var code = """ + class C + { + void Method() { - int [$$] + var s = @""$$ } - """; + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); - using var session = CreateSession(code); - Assert.NotNull(session); + CheckStart(session.Session); + } - CheckStart(session.Session); - } + [WpfFact] + public void Attribute_OpenBracket() + { + var code = """ + $$ + class C { } + """; - [WpfFact] - public void Array_Nested() - { - var code = """ - class C - { - int [] i = new int [arr$$] - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - - CheckStart(session.Session); - } - - [WpfFact] - public void ListPattern() - { - var code = """ - class C + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void Attribute_OpenBracket_Delete() + { + var code = """ + $$ + class C { } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void Attribute_OpenBracket_Tab() + { + var code = """ + $$ + class C { } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void Attribute_OpenBracket_CloseBracket() + { + var code = """ + $$ + class C { } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void Array_Multiple_Invalid() + { + var code = """ + class C + { + int [$$] + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void Array_Nested() + { + var code = """ + class C + { + int [] i = new int [arr$$] + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + + CheckStart(session.Session); + } + + [WpfFact] + public void ListPattern() + { + var code = """ + class C + { + void M(object o) { - void M(object o) - { - _ = o is$$ - } + _ = o is$$ } - """; - var expectedBeforeReturn = """ - class C + } + """; + var expectedBeforeReturn = """ + class C + { + void M(object o) { - void M(object o) - { - _ = o is [] - } + _ = o is [] } - """; - var expected = """ - class C + } + """; + var expected = """ + class C + { + void M(object o) { - void M(object o) - { - _ = o is - [ + _ = o is + [ - ] - } + ] } - """; - using var session = CreateSession(code); - CheckStart(session.Session); - CheckText(session.Session, expectedBeforeReturn); - CheckReturn(session.Session, 12, expected); - } - - internal static Holder CreateSession(string code) - { - return CreateSession( - EditorTestWorkspace.CreateCSharp(code), - Bracket.OpenCharacter, Bracket.CloseCharacter); - } + } + """; + using var session = CreateSession(code); + CheckStart(session.Session); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expected); + } + + internal static Holder CreateSession(string code) + { + return CreateSession( + EditorTestWorkspace.CreateCSharp(code), + Bracket.OpenCharacter, Bracket.CloseCharacter); } } diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs index ecbe91d23d2b6..5ea271b00c5c0 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs @@ -4,440 +4,437 @@ #nullable disable -using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using static Microsoft.CodeAnalysis.BraceCompletion.AbstractBraceCompletionService; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion; + +[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] +public class AutomaticLessAndGreaterThanCompletionTests : AbstractAutomaticBraceCompletionTests { - [Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] - public class AutomaticLessAndGreaterThanCompletionTests : AbstractAutomaticBraceCompletionTests + [WpfFact] + public void Creation() { - [WpfFact] - public void Creation() - { - using var session = CreateSession("$$"); - Assert.NotNull(session); - } - - [WpfFact] - public void InvalidLocation_TopLevel() - { - using var session = CreateSession("$$"); - Assert.NotNull(session); - } - - [WpfFact] - public void InvalidLocation_TopLevel2() - { - using var session = CreateSession("using System;$$"); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact] - public void Class_TypeParameter() - { - var code = @"class C$$"; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Method_TypeParameter() - { - var code = """ - class C - { - void Method$$ - } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Class_TypeParameter_Delete() - { - var code = @"class C$$"; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void Class_TypeParameter_Tab() - { - var code = @"class C$$"; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void Class_TypeParameter_GreaterThan() - { - var code = @"class C$$"; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void Multiple_Invalid() - { - var code = @"class C<$$>"; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact] - public void Multiple_Nested() - { - var code = """ - class C - { - C - } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void TypeArgument_Invalid() - { - var code = """ - class C + using var session = CreateSession("$$"); + Assert.NotNull(session); + } + + [WpfFact] + public void InvalidLocation_TopLevel() + { + using var session = CreateSession("$$"); + Assert.NotNull(session); + } + + [WpfFact] + public void InvalidLocation_TopLevel2() + { + using var session = CreateSession("using System;$$"); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact] + public void Class_TypeParameter() + { + var code = @"class C$$"; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Method_TypeParameter() + { + var code = """ + class C + { + void Method$$ + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Class_TypeParameter_Delete() + { + var code = @"class C$$"; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void Class_TypeParameter_Tab() + { + var code = @"class C$$"; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void Class_TypeParameter_GreaterThan() + { + var code = @"class C$$"; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void Multiple_Invalid() + { + var code = @"class C<$$>"; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact] + public void Multiple_Nested() + { + var code = """ + class C + { + C + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void TypeArgument_Invalid() + { + var code = """ + class C + { + void Method() { - void Method() - { - var i = 1; - var b = i $$ - } + var i = 1; + var b = i $$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact] - public void TypeArgument1() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact] + public void TypeArgument1() + { + var code = """ + class C + { + void Method() { - void Method() - { - var a = new List$$ - } + var a = new List$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void TypeArgument2() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void TypeArgument2() + { + var code = """ + class C + { + void Method() { - void Method() - { - var a = typeof(List$$ - } + var a = typeof(List$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531637")] - public void TypeParameterReturnType() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531637")] + public void TypeParameterReturnType() + { + var code = """ + class C + { + List$$ + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + Type(session.Session, "int"); + CheckOverType(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531637")] + public void TypeParameterInDecl() + { + var code = """ + class C + { + void List$$ + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + Type(session.Session, "T"); + CheckOverType(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531637")] + public void TypeParameterInDeclWith() + { + var code = """ + class C + { + async Task$$ + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + Type(session.Session, "int"); + CheckOverType(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530864")] + public void TypeArgumentWithUsing() + { + var code = """ + using System.Collections.Generic; + + class C + { + void Test() { List$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "int"); - CheckOverType(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531637")] - public void TypeParameterInDecl() - { - var code = """ - class C - { - void List$$ - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "T"); - CheckOverType(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531637")] - public void TypeParameterInDeclWith() - { - var code = """ - class C - { - async Task$$ - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "int"); - CheckOverType(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530864")] - public void TypeArgumentWithUsing() - { - var code = """ - using System.Collections.Generic; - - class C - { - void Test() - { - List$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "int"); - CheckOverType(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530864")] - public void TypeArgumentNoUsing() - { - var code = """ - class C - { - void Test() - { - List$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] - public void NotInLessThanComparisonOperation() - { - var code = """ - using System.Linq; - class C - { - void Test(int[] args) - { - var a = args[0]$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] - public void NotInLessThanComparisonOperationAfterConditionalAccessExpression() - { - var code = """ - using System.Linq; - class C - { - void Test(object[] args, object[] other) - { - var a = args?.First()$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] - public void TypeArgumentInConditionalAccessExpressionSimple() - { - var code = """ - using System.Linq; - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + Type(session.Session, "int"); + CheckOverType(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530864")] + public void TypeArgumentNoUsing() + { + var code = """ + class C + { + void Test() { - void Test(object[] args) - { - args?.OfType$$ - } + List$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] - public void TypeArgumentInConditionalAccessExpressionNested() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] + public void NotInLessThanComparisonOperation() + { + var code = """ + using System.Linq; + class C + { + void Test(int[] args) { - void Test() - { - Outer t = new Outer(); - t?.GetInner()?.Method$$ - } + var a = args[0]$$ } - class Outer + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] + public void NotInLessThanComparisonOperationAfterConditionalAccessExpression() + { + var code = """ + using System.Linq; + class C + { + void Test(object[] args, object[] other) { - public Inner GetInner() - { - return new Inner(); - } + var a = args?.First()$$ } - class Inner + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] + public void TypeArgumentInConditionalAccessExpressionSimple() + { + var code = """ + using System.Linq; + class C + { + void Test(object[] args) { - public void Method() { } + args?.OfType$$ } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "int"); - CheckOverType(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] - public void TypeArgumentInConditionalAccessExpressionDeeplyNested() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] + public void TypeArgumentInConditionalAccessExpressionNested() + { + var code = """ + class C + { + void Test() { - void Test() - { - new Outer1()?.GetInner()?.GetInner().DoSomething$$ - } + Outer t = new Outer(); + t?.GetInner()?.Method$$ } - internal class Outer1 + } + class Outer + { + public Inner GetInner() { - public Outer2 GetInner() - { - return new Outer2(); - } + return new Inner(); } - internal class Outer2 + } + class Inner + { + public void Method() { } + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + Type(session.Session, "int"); + CheckOverType(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] + public void TypeArgumentInConditionalAccessExpressionDeeplyNested() + { + var code = """ + class C + { + void Test() { - public Outer2() { } - public Inner GetInner() - { - return new Inner(); - } + new Outer1()?.GetInner()?.GetInner().DoSomething$$ } - internal class Inner + } + internal class Outer1 + { + public Outer2 GetInner() { - public Inner() { } - public void DoSomething() { } + return new Outer2(); } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] - public void TypeArgumentInConditionalAccessExpressionWithLambdas() - { - var code = """ - using System; - using System.Collections.Generic; - using System.Linq; - - class Program + } + internal class Outer2 + { + public Outer2() { } + public Inner GetInner() { - void Goo(object[] args) - { - var a = new Outer(); - a?.M(x => x?.ToString())?.Method$$ - } + return new Inner(); } + } + internal class Inner + { + public Inner() { } + public void DoSomething() { } + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } - public class Outer + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/1628")] + public void TypeArgumentInConditionalAccessExpressionWithLambdas() + { + var code = """ + using System; + using System.Collections.Generic; + using System.Linq; + + class Program + { + void Goo(object[] args) { - internal Inner M(Func p) - { - throw new NotImplementedException(); - } + var a = new Outer(); + a?.M(x => x?.ToString())?.Method$$ } + } - public class Inner + public class Outer + { + internal Inner M(Func p) { - public void Method() { } + throw new NotImplementedException(); } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void FunctionPointerStartSession() - { - var code = """ - class C - { - delegate*$$ - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - Type(session.Session, "int"); - CheckOverType(session.Session); - } - - internal static Holder CreateSession(string code) - { - return CreateSession( - EditorTestWorkspace.CreateCSharp(code), - LessAndGreaterThan.OpenCharacter, LessAndGreaterThan.CloseCharacter); - } + } + + public class Inner + { + public void Method() { } + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void FunctionPointerStartSession() + { + var code = """ + class C + { + delegate*$$ + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + Type(session.Session, "int"); + CheckOverType(session.Session); + } + + internal static Holder CreateSession(string code) + { + return CreateSession( + EditorTestWorkspace.CreateCSharp(code), + LessAndGreaterThan.OpenCharacter, LessAndGreaterThan.CloseCharacter); } } diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLineEnderTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLineEnderTests.cs index f219cb1cf673f..d795151cdd000 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLineEnderTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLineEnderTests.cs @@ -7,62 +7,61 @@ using System; using Microsoft.CodeAnalysis.Editor.CSharp.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion; + +[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] +public class AutomaticLineEnderTests : AbstractAutomaticLineEnderTests { - [Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] - public class AutomaticLineEnderTests : AbstractAutomaticLineEnderTests + [WpfFact] + public void Creation() { - [WpfFact] - public void Creation() - { - Test(@" + Test(@" $$", "$$"); - } + } - [WpfFact] - public void Usings() - { - Test(@"using System; + [WpfFact] + public void Usings() + { + Test(@"using System; $$", @"using System$$"); - } + } - [WpfFact] - public void Namespace() - { - Test(@"namespace {} + [WpfFact] + public void Namespace() + { + Test(@"namespace {} $$", @"namespace {$$}"); - } + } - [WpfFact] - public void Class() - { - Test(@"class {} + [WpfFact] + public void Class() + { + Test(@"class {} $$", "class {$$}"); - } + } - [WpfFact] - public void Method() - { - Test(@"class C + [WpfFact] + public void Method() + { + Test(@"class C { void Method() {$$} }", @"class C { void Method() {$$} }", assertNextHandlerInvoked: true); - } + } - [WpfFact] - public void Field() - { - Test(@"class C + [WpfFact] + public void Field() + { + Test(@"class C { private readonly int i = 3; $$ @@ -70,12 +69,12 @@ public void Field() { pri$$vate re$$adonly i$$nt i = 3$$ }"); - } + } - [WpfFact] - public void EventField() - { - Test(@"class C + [WpfFact] + public void EventField() + { + Test(@"class C { event System.EventHandler e = null; $$ @@ -83,12 +82,12 @@ public void EventField() { e$$vent System.Even$$tHandler e$$ = null$$ }"); - } + } - [WpfFact] - public void Field2() - { - Test(@"class C + [WpfFact] + public void Field2() + { + Test(@"class C { private readonly int i; $$ @@ -96,12 +95,12 @@ public void Field2() { private readonly int i$$ }"); - } + } - [WpfFact] - public void EventField2() - { - Test(@"class C + [WpfFact] + public void EventField2() + { + Test(@"class C { event System.EventHandler e { @@ -111,12 +110,12 @@ event System.EventHandler e { eve$$nt System.E$$ventHandler e$$ }"); - } + } - [WpfFact] - public void Field3() - { - Test(@"class C + [WpfFact] + public void Field3() + { + Test(@"class C { private readonly int $$ @@ -124,12 +123,12 @@ private readonly int { private readonly int$$ }"); - } + } - [WpfFact] - public void EventField3() - { - Test(@"class C + [WpfFact] + public void EventField3() + { + Test(@"class C { event System.EventHandler $$ @@ -137,12 +136,12 @@ event System.EventHandler { event System.EventHandler$$ }"); - } + } - [WpfFact] - public void EmbededStatement() - { - Test(@"class C + [WpfFact] + public void EmbededStatement() + { + Test(@"class C { void Method() { @@ -158,12 +157,12 @@ void Method() if (true) $$ } }"); - } + } - [WpfFact] - public void EmbededStatement1() - { - Test(@"class C + [WpfFact] + public void EmbededStatement1() + { + Test(@"class C { void Method() { @@ -179,12 +178,12 @@ void Method() Console.WriteLine()$$ } }"); - } + } - [WpfFact] - public void EmbededStatement2() - { - Test(@"class C + [WpfFact] + public void EmbededStatement2() + { + Test(@"class C { void Method() { @@ -200,12 +199,12 @@ void Method() Console.WriteLine($$) } }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/57323")] - public void EmbededStatementFollowedByStatement() - { - Test(@"class C + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/57323")] + public void EmbededStatementFollowedByStatement() + { + Test(@"class C { void Method() { @@ -233,12 +232,12 @@ void Method() } } }"); - } + } - [WpfFact] - public void Statement() - { - Test(@"class C + [WpfFact] + public void Statement() + { + Test(@"class C { void Method() { @@ -252,12 +251,12 @@ void Method() int i$$ } }"); - } + } - [WpfFact] - public void Statement1() - { - Test(@"class C + [WpfFact] + public void Statement1() + { + Test(@"class C { void Method() { @@ -271,12 +270,12 @@ void Method() int$$ } }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedMethod() - { - Test(@"class T + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedMethod() + { + Test(@"class T { int M() => 1 + 2; $$ @@ -284,12 +283,12 @@ public void ExpressionBodiedMethod() { int M() => 1 + 2$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedOperator() - { - Test(@"class Complex + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedOperator() + { + Test(@"class Complex { int real; int imaginary; public static Complex operator +(Complex a, Complex b) => a.Add(b.real + 1); @@ -301,12 +300,12 @@ public void ExpressionBodiedOperator() public static Complex operator +(Complex a, Complex b) => a.Add(b.real + 1)$$ private Complex Add(int b) => null; }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedConversionOperator() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedConversionOperator() + { + Test(@"using System; public struct DBBool { public static readonly DBBool dbFalse = new DBBool(-1); @@ -332,12 +331,12 @@ public struct DBBool public static implicit operator DBBool(bool x) => x ? new DBBool(1) : dbFalse$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedProperty() - { - Test(@"class T + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedProperty() + { + Test(@"class T { int P1 => 1 + 2; $$ @@ -345,12 +344,12 @@ public void ExpressionBodiedProperty() { int P1 => 1 + 2$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedIndexer() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedIndexer() + { + Test(@"using System; class SampleCollection { private T[] arr = new T[100]; @@ -362,12 +361,12 @@ class SampleCollection private T[] arr = new T[100]; public T this[int i] => i > 0 ? arr[i + 1] : arr[i + 2]$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedMethodWithBlockBodiedAnonymousMethodExpression() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedMethodWithBlockBodiedAnonymousMethodExpression() + { + Test(@"using System; class TestClass { Func Y() => delegate (int x) @@ -383,12 +382,12 @@ Func Y() => delegate (int x) return 9; }$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedMethodWithSingleLineBlockBodiedAnonymousMethodExpression() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedMethodWithSingleLineBlockBodiedAnonymousMethodExpression() + { + Test(@"using System; class TestClass { Func Y() => delegate (int x) { return 9; }; @@ -398,12 +397,12 @@ class TestClass { Func Y() => delegate (int x) { return 9; }$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedMethodWithBlockBodiedSimpleLambdaExpression() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedMethodWithBlockBodiedSimpleLambdaExpression() + { + Test(@"using System; class TestClass { Func Y() => f => @@ -419,12 +418,12 @@ Func Y() => f => return f * 9; }$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedMethodWithExpressionBodiedSimpleLambdaExpression() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedMethodWithExpressionBodiedSimpleLambdaExpression() + { + Test(@"using System; class TestClass { Func Y() => f => f * 9; @@ -434,12 +433,12 @@ class TestClass { Func Y() => f => f * 9$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void ExpressionBodiedMethodWithBlockBodiedAnonymousMethodExpressionInMethodArgs() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void ExpressionBodiedMethodWithBlockBodiedAnonymousMethodExpressionInMethodArgs() + { + Test(@"using System; class TestClass { public int Prop => Method1(delegate () @@ -459,12 +458,12 @@ class TestClass private int Method1(Func p) => null; }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void Format_SimpleExpressionBodiedMember() - { - Test(@"class T + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void Format_SimpleExpressionBodiedMember() + { + Test(@"class T { int M() => 1 + 2; $$ @@ -472,12 +471,12 @@ public void Format_SimpleExpressionBodiedMember() { int M() => 1 + 2$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void Format_ExpressionBodiedMemberWithSingleLineBlock() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void Format_ExpressionBodiedMemberWithSingleLineBlock() + { + Test(@"using System; class TestClass { Func Y() => delegate (int x) { return 9; }; @@ -487,12 +486,12 @@ class TestClass { Func Y () => delegate(int x) { return 9 ; }$$ }"); - } + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] - public void Format_ExpressionBodiedMemberWithMultiLineBlock() - { - Test(@"using System; + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/3944")] + public void Format_ExpressionBodiedMemberWithMultiLineBlock() + { + Test(@"using System; class TestClass { Func Y() => delegate (int x) @@ -508,12 +507,12 @@ Func Y() => delegate(int x) return 9; }$$ }"); - } + } - [WpfFact] - public void Format_Statement() - { - Test(@"class C + [WpfFact] + public void Format_Statement() + { + Test(@"class C { void Method() { @@ -527,28 +526,28 @@ void Method() int i = 1 $$ } }"); - } + } - [WpfFact] - public void Format_Using() - { - Test(@"using System.Linq; + [WpfFact] + public void Format_Using() + { + Test(@"using System.Linq; $$", @" using System . Linq $$"); - } + } - [WpfFact] - public void Format_Using2() - { - Test(@"using + [WpfFact] + public void Format_Using2() + { + Test(@"using System.Linq; $$", @" using System . Linq $$"); - } + } - [WpfFact] - public void Format_Field() - { - Test(@"class C + [WpfFact] + public void Format_Field() + { + Test(@"class C { int i = 1; $$ @@ -556,12 +555,12 @@ public void Format_Field() { int i = 1 $$ }"); - } + } - [WpfFact] - public void Statement_Trivia() - { - Test(@"class C + [WpfFact] + public void Statement_Trivia() + { + Test(@"class C { void goo() { @@ -575,12 +574,12 @@ void goo() goo()$$ //comment } }"); - } + } - [WpfFact] - public void TrailingText_Negative() - { - Test(@"class C + [WpfFact] + public void TrailingText_Negative() + { + Test(@"class C { event System.EventHandler e = null int i = 2; $$ @@ -588,12 +587,12 @@ public void TrailingText_Negative() { event System.EventHandler e = null$$ int i = 2; }"); - } + } - [WpfFact] - public void CompletionSetUp() - { - Test(@"class Program + [WpfFact] + public void CompletionSetUp() + { + Test(@"class Program { object goo(object o) { @@ -607,12 +606,12 @@ object goo(object o) return goo($$) } }", completionActive: true); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530352")] - public void EmbededStatement3() - { - Test(@"class Program + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530352")] + public void EmbededStatement3() + { + Test(@"class Program { void Method() { @@ -628,12 +627,12 @@ void Method() foreach (var x in y$$) } }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530716")] - public void DoNotAssertOnMultilineToken() - { - Test(@"interface I + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530716")] + public void DoNotAssertOnMultilineToken() + { + Test(@"interface I { void M(string s = @"""""" $$ @@ -641,12 +640,12 @@ void M(string s = @"""""" { void M(string s = @""""""$$ }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530718")] - public void AutomaticLineFormat() - { - Test(@"class C + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530718")] + public void AutomaticLineFormat() + { + Test(@"class C { public string P { set; get; } $$ @@ -654,12 +653,12 @@ public void AutomaticLineFormat() { public string P {set;get;$$} }"); - } + } - [WpfFact] - public void NotAfterExisitingSemicolon() - { - Test(@"class TestClass + [WpfFact] + public void NotAfterExisitingSemicolon() + { + Test(@"class TestClass { private int i; $$ @@ -667,12 +666,12 @@ public void NotAfterExisitingSemicolon() { private int i;$$ }"); - } + } - [WpfFact] - public void NotAfterCloseBraceInMethod() - { - Test(@"class TestClass + [WpfFact] + public void NotAfterCloseBraceInMethod() + { + Test(@"class TestClass { void Test() { } $$ @@ -680,12 +679,12 @@ void Test() { } { void Test() { }$$ }"); - } + } - [WpfFact] - public void NotAfterCloseBraceInStatement() - { - Test(@"class TestClass + [WpfFact] + public void NotAfterCloseBraceInStatement() + { + Test(@"class TestClass { void Test() { @@ -699,12 +698,12 @@ void Test() if (true) { }$$ } }"); - } + } - [WpfFact] - public void NotAfterAutoPropertyAccessor() - { - Test(@"class TestClass + [WpfFact] + public void NotAfterAutoPropertyAccessor() + { + Test(@"class TestClass { public int A { get; set } $$ @@ -712,12 +711,12 @@ public void NotAfterAutoPropertyAccessor() { public int A { get; set$$ } }"); - } + } - [WpfFact] - public void NotAfterAutoPropertyDeclaration() - { - Test(@"class TestClass + [WpfFact] + public void NotAfterAutoPropertyDeclaration() + { + Test(@"class TestClass { public int A { get; set; } $$ @@ -725,12 +724,12 @@ public void NotAfterAutoPropertyDeclaration() { public int A { get; set; }$$ }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void DelegatedInEmptyBlock() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void DelegatedInEmptyBlock() + { + Test(@"class TestClass { void Method() { @@ -743,12 +742,12 @@ void Method() try { $$} } }", assertNextHandlerInvoked: true); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void DelegatedInEmptyBlock2() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void DelegatedInEmptyBlock2() + { + Test(@"class TestClass { void Method() { @@ -761,12 +760,12 @@ void Method() if (true) { $$} } }", assertNextHandlerInvoked: true); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void NotDelegatedOutsideEmptyBlock() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void NotDelegatedOutsideEmptyBlock() + { + Test(@"class TestClass { void Method() { @@ -780,12 +779,12 @@ void Method() try { }$$ } }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void NotDelegatedAfterOpenBraceAndMissingCloseBrace() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void NotDelegatedAfterOpenBraceAndMissingCloseBrace() + { + Test(@"class TestClass { void Method() { @@ -799,12 +798,12 @@ void Method() try {$$ } }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void NotDelegatedInNonEmptyBlock() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void NotDelegatedInNonEmptyBlock() + { + Test(@"class TestClass { void Method() { @@ -818,12 +817,12 @@ void Method() try { x$$ } } }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void NotDelegatedAfterOpenBraceInAnonymousObjectCreationExpression() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void NotDelegatedAfterOpenBraceInAnonymousObjectCreationExpression() + { + Test(@"class TestClass { void Method() { @@ -837,12 +836,12 @@ void Method() var pet = new { $$} } }"); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] - public void NotDelegatedAfterOpenBraceObjectCreationExpression() - { - Test(@"class TestClass + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/150480")] + public void NotDelegatedAfterOpenBraceObjectCreationExpression() + { + Test(@"class TestClass { void Method() { @@ -856,12 +855,12 @@ void Method() var pet = new List { $$} } }"); - } + } - [WpfFact] - public void TestMulitpleNamespace() - { - Test($@" + [WpfFact] + public void TestMulitpleNamespace() + { + Test($@" namespace Bar2 {{ $$ @@ -873,34 +872,34 @@ namespace B$$ar2$$ namespace Bar {{ }}"); - } + } - [WpfTheory] - [InlineData("namespace")] - [InlineData("class")] - [InlineData("struct")] - [InlineData("record")] - [InlineData("enum")] - [InlineData("interface")] - public void TestEmptyBaseTypeDeclarationAndNamespace(string typeKeyword) - { - Test($@" + [WpfTheory] + [InlineData("namespace")] + [InlineData("class")] + [InlineData("struct")] + [InlineData("record")] + [InlineData("enum")] + [InlineData("interface")] + public void TestEmptyBaseTypeDeclarationAndNamespace(string typeKeyword) + { + Test($@" public {typeKeyword} Bar {{ $$ }}", $@" pu$$blic {typeKeyword} $$Bar$$"); - } + } - [WpfTheory] - [InlineData("class")] - [InlineData("struct")] - [InlineData("record")] - [InlineData("enum")] - [InlineData("interface")] - public void TestMultipleBaseTypeDeclaration(string typeKeyword) - { - Test($@" + [WpfTheory] + [InlineData("class")] + [InlineData("struct")] + [InlineData("record")] + [InlineData("enum")] + [InlineData("interface")] + public void TestMultipleBaseTypeDeclaration(string typeKeyword) + { + Test($@" public {typeKeyword} Bar2 {{ $$ @@ -913,12 +912,12 @@ public void TestMultipleBaseTypeDeclaration(string typeKeyword) public {typeKeyword} Bar {{ }}"); - } + } - [WpfFact] - public void TestNestedTypeDeclaration() - { - Test(@" + [WpfFact] + public void TestNestedTypeDeclaration() + { + Test(@" public class Bar1 { public class Bar2 @@ -931,12 +930,12 @@ public class Bar1 { pu$$blic cla$$ss B$$ar2$$ }"); - } + } - [WpfFact] - public void TestNestedNamespace() - { - Test(@" + [WpfFact] + public void TestNestedNamespace() + { + Test(@" namespace Bar1 { namespace Bar2 @@ -949,41 +948,41 @@ namespace Bar1 { namespa$$ce $$B$$ar2$$ }"); - } + } - [WpfTheory] - [InlineData("namespace")] - [InlineData("class")] - [InlineData("struct")] - [InlineData("record")] - [InlineData("enum")] - [InlineData("interface")] - public void TestBaseTypeDeclarationAndNamespaceWithOpenBrace(string typeKeyword) - { - Test($@" + [WpfTheory] + [InlineData("namespace")] + [InlineData("class")] + [InlineData("struct")] + [InlineData("record")] + [InlineData("enum")] + [InlineData("interface")] + public void TestBaseTypeDeclarationAndNamespaceWithOpenBrace(string typeKeyword) + { + Test($@" public {typeKeyword} Bar {{ $$", $@" pub$$lic {typeKeyword} B$$ar {{$$"); - } + } - [WpfTheory] - [InlineData("namespace")] - [InlineData("class")] - [InlineData("struct")] - [InlineData("record")] - [InlineData("enum")] - [InlineData("interface")] - public void TestValidTypeDeclarationAndNamespace(string typeKeyword) - { - Test($@"public {typeKeyword} Bar {{}} + [WpfTheory] + [InlineData("namespace")] + [InlineData("class")] + [InlineData("struct")] + [InlineData("record")] + [InlineData("enum")] + [InlineData("interface")] + public void TestValidTypeDeclarationAndNamespace(string typeKeyword) + { + Test($@"public {typeKeyword} Bar {{}} $$", - $@"public {typeKeyword}$$ Ba$$r {{}}$$"); - } + $@"public {typeKeyword}$$ Ba$$r {{}}$$"); + } - [WpfFact] - public void TestMethod() - { - Test(@" + [WpfFact] + public void TestMethod() + { + Test(@" public class Bar { void Main() @@ -995,12 +994,12 @@ public class Bar { v$$oid Ma$$in($$)$$ }"); - } + } - [WpfFact] - public void TestConstructor() - { - Test(@" + [WpfFact] + public void TestConstructor() + { + Test(@" public class Bar { void Bar() @@ -1012,12 +1011,12 @@ public class Bar { v$$oid Ba$$r($$)$$ }"); - } + } - [WpfFact] - public void TestValidMethodInInterface() - { - Test(@" + [WpfFact] + public void TestValidMethodInInterface() + { + Test(@" public interface Bar { void Main(); @@ -1027,12 +1026,12 @@ public interface Bar { v$$oid Mai$$n($$)$$; }"); - } + } - [WpfFact] - public void TestMissingSemicolonMethodInInterface() - { - Test(@" + [WpfFact] + public void TestMissingSemicolonMethodInInterface() + { + Test(@" public interface Bar { void Main() @@ -1042,12 +1041,12 @@ public interface Bar { v$$oid Mai$$n($$)$$ }"); - } + } - [WpfFact] - public void TestValidLocalFunction() - { - Test(@" + [WpfFact] + public void TestValidLocalFunction() + { + Test(@" public class Bar { void Main() @@ -1067,12 +1066,12 @@ void Main() } } }"); - } + } - [WpfFact] - public void TestLocalFunction() - { - Test(@" + [WpfFact] + public void TestLocalFunction() + { + Test(@" public class Bar { void Main() @@ -1090,12 +1089,12 @@ void Main() v$$oid Loca$$l($$)$$ } }"); - } + } - [WpfFact] - public void TestIndexerAsLastElementInClass() - { - Test(@" + [WpfFact] + public void TestIndexerAsLastElementInClass() + { + Test(@" public class Bar { public int this[int i] @@ -1107,12 +1106,12 @@ public class Bar { p$$ublic in$$t thi$$s[in$$t i]$$ }"); - } + } - [WpfFact] - public void TestIndexerNotAsLastElementInClass() - { - Test(@" + [WpfFact] + public void TestIndexerNotAsLastElementInClass() + { + Test(@" public class Bar { public int this[int i] @@ -1126,12 +1125,12 @@ public class Bar p$$ublic in$$t thi$$s[in$$t i]$$ void Main() {} }"); - } + } - [WpfFact] - public void TestValidIndexer() - { - Test(@" + [WpfFact] + public void TestValidIndexer() + { + Test(@" public class Bar { public int this[int i] @@ -1145,12 +1144,12 @@ public class Bar { } }"); - } + } - [WpfFact] - public void TestGetAccessorOfProperty() - { - var initialMarkup = @" + [WpfFact] + public void TestGetAccessorOfProperty() + { + var initialMarkup = @" public class Bar { public int P @@ -1159,7 +1158,7 @@ public int P } }"; - var firstResult = @" + var firstResult = @" public class Bar { public int P @@ -1170,7 +1169,7 @@ public int P } } }"; - var secondResult = @" + var secondResult = @" public class Bar { public int P @@ -1179,14 +1178,14 @@ public int P $$ } }"; - Test(firstResult, initialMarkup); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkup); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestSetAccessorOfProperty() - { - var initialMarkup = @" + [WpfFact] + public void TestSetAccessorOfProperty() + { + var initialMarkup = @" public class Bar { public int P @@ -1194,7 +1193,7 @@ public int P set$$ } }"; - var firstResult = @" + var firstResult = @" public class Bar { public int P @@ -1205,7 +1204,7 @@ public int P } } }"; - var secondResult = @" + var secondResult = @" public class Bar { public int P @@ -1214,14 +1213,14 @@ public int P $$ } }"; - Test(firstResult, initialMarkup); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkup); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestGetAccessorOfIndexer() - { - Test(@" + [WpfFact] + public void TestGetAccessorOfIndexer() + { + Test(@" public class Bar { public int this[int i] @@ -1239,12 +1238,12 @@ public int this[int i] ge$$t$$ } }"); - } + } - [WpfFact] - public void TestValidGetAccessorOfIndexer() - { - Test(@" + [WpfFact] + public void TestValidGetAccessorOfIndexer() + { + Test(@" public class Bar { public int this[int i] @@ -1266,12 +1265,12 @@ public int this[int i] } } }"); - } + } - [WpfFact] - public void TestNonEmptyGetAccessor() - { - Test(@" + [WpfFact] + public void TestNonEmptyGetAccessor() + { + Test(@" public Class Bar { public int P @@ -1286,7 +1285,7 @@ public int P } } }", - @" + @" public Class Bar { public int P @@ -1300,12 +1299,12 @@ public int P } } }"); - } + } - [WpfFact] - public void TestNonEmptySetAccessor() - { - Test(@" + [WpfFact] + public void TestNonEmptySetAccessor() + { + Test(@" public Class Bar { public int P @@ -1320,7 +1319,7 @@ public int P } } }", - @" + @" public Class Bar { public int P @@ -1334,12 +1333,12 @@ public int P } } }"); - } + } - [WpfFact] - public void TestSetAccessorOfIndexer() - { - Test(@" + [WpfFact] + public void TestSetAccessorOfIndexer() + { + Test(@" public class Bar { public int this[int i] @@ -1359,12 +1358,12 @@ public int this[int i] se$$t$$ } }"); - } + } - [WpfFact] - public void TestValidSetAccessorOfIndexer() - { - Test(@" + [WpfFact] + public void TestValidSetAccessorOfIndexer() + { + Test(@" public class Bar { public int this[int i] @@ -1388,12 +1387,12 @@ public int this[int i] } } }"); - } + } - [WpfFact] - public void TestAddAccessorInEventDeclaration() - { - Test(@" + [WpfFact] + public void TestAddAccessorInEventDeclaration() + { + Test(@" using System; public class Bar { @@ -1415,12 +1414,12 @@ public event EventHandler e remove } }"); - } + } - [WpfFact] - public void TestValidAddAccessorInEventDeclaration() - { - Test(@" + [WpfFact] + public void TestValidAddAccessorInEventDeclaration() + { + Test(@" using System; public class Bar { @@ -1446,12 +1445,12 @@ public event EventHandler e remove { } } }"); - } + } - [WpfFact] - public void TestRemoveAccessor() - { - Test(@" + [WpfFact] + public void TestRemoveAccessor() + { + Test(@" using System; public class Bar { @@ -1473,12 +1472,12 @@ public event EventHandler e remo$$ve$$ } }"); - } + } - [WpfFact] - public void TestValidRemoveAccessor() - { - Test(@" + [WpfFact] + public void TestValidRemoveAccessor() + { + Test(@" using System; public class Bar { @@ -1504,17 +1503,17 @@ public event EventHandler e } } }"); - } + } - [WpfFact] - public void TestField() - { - var initialMarkup = @" + [WpfFact] + public void TestField() + { + var initialMarkup = @" public class Bar { p$$ublic i$$nt i$$ii$$ }"; - var firstResult = @" + var firstResult = @" public class Bar { public int iii @@ -1522,21 +1521,21 @@ public int iii $$ } }"; - var secondResult = @" + var secondResult = @" public class Bar { public int iii; $$ }"; - Test(firstResult, initialMarkup); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkup); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestReadonlyField() - { - Test(@" + [WpfFact] + public void TestReadonlyField() + { + Test(@" public class Bar { public readonly int iii; @@ -1546,12 +1545,12 @@ public class Bar { p$$ublic reado$$nly i$$nt i$$ii$$ }"); - } + } - [WpfFact] - public void TestNonEmptyProperty() - { - Test(@" + [WpfFact] + public void TestNonEmptyProperty() + { + Test(@" public class Bar { public int Foo @@ -1567,12 +1566,12 @@ public int Foo $$get$$ { }$$ } }"); - } + } - [WpfFact] - public void TestMulitpleFields() - { - Test(@" + [WpfFact] + public void TestMulitpleFields() + { + Test(@" public class Bar { public int apple, banana; @@ -1582,12 +1581,12 @@ public class Bar { p$$ublic i$$nt ap$$ple$$, ba$$nana;$$ }"); - } + } - [WpfFact] - public void TestMultipleEvents() - { - Test(@" + [WpfFact] + public void TestMultipleEvents() + { + Test(@" using System; public class Bar { @@ -1599,18 +1598,18 @@ public class Bar { p$$ublic event EventHandler ap$$ple$$, ba$$nana$$;$$ }"); - } + } - [WpfFact] - public void TestEvent() - { - var initialMarkup = @" + [WpfFact] + public void TestEvent() + { + var initialMarkup = @" using System; public class Bar { pu$$blic e$$vent EventHand$$ler c$$c$$ }"; - var firstResult = @" + var firstResult = @" using System; public class Bar { @@ -1619,21 +1618,21 @@ public event EventHandler cc $$ } }"; - var secondResult = @" + var secondResult = @" using System; public class Bar { public event EventHandler cc; $$ }"; - Test(firstResult, initialMarkup); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkup); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestNonEmptyEvent() - { - Test(@" + [WpfFact] + public void TestNonEmptyEvent() + { + Test(@" using System; public class Bar { @@ -1651,12 +1650,12 @@ public event EventHandler Foo $$add$$ {$$ }$$ } }"); - } + } - [WpfFact] - public void TestObjectCreationExpressionWithParenthesis() - { - var initialMarkup = @" + [WpfFact] + public void TestObjectCreationExpressionWithParenthesis() + { + var initialMarkup = @" public class Bar { public void M() @@ -1670,7 +1669,7 @@ public class Foo public int PP { get; set; } }"; - var firstResult = @" + var firstResult = @" public class Bar { public void M() @@ -1687,7 +1686,7 @@ public class Foo public int PP { get; set; } }"; - var secondResult = @" + var secondResult = @" public class Bar { public void M() @@ -1702,14 +1701,14 @@ public class Foo public int PP { get; set; } }"; - Test(firstResult, initialMarkup); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkup); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestObjectCreationExpressionWithNoParenthesis() - { - var initialMarkUp = @" + [WpfFact] + public void TestObjectCreationExpressionWithNoParenthesis() + { + var initialMarkUp = @" public class Bar { public void M() @@ -1723,7 +1722,7 @@ public class Foo public int PP { get; set; } }"; - var firstResult = @" + var firstResult = @" public class Bar { public void M() @@ -1740,7 +1739,7 @@ public class Foo public int PP { get; set; } }"; - var secondResult = @" + var secondResult = @" public class Bar { public void M() @@ -1755,14 +1754,14 @@ public class Foo public int PP { get; set; } }"; - Test(firstResult, initialMarkUp); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkUp); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestObjectCreationExpressionWithCorrectSemicolon() - { - var initialMarkUp = @" + [WpfFact] + public void TestObjectCreationExpressionWithCorrectSemicolon() + { + var initialMarkUp = @" public class Bar { public void M() @@ -1776,7 +1775,7 @@ public class Foo public int PP { get; set; } }"; - var firstResult = @" + var firstResult = @" public class Bar { public void M() @@ -1793,7 +1792,7 @@ public class Foo public int PP { get; set; } }"; - var secondResult = @" + var secondResult = @" public class Bar { public void M() @@ -1808,14 +1807,14 @@ public class Foo public int PP { get; set; } }"; - Test(firstResult, initialMarkUp); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkUp); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestObjectCreationExpressionUsedAsExpression() - { - var initialMarkUp = @" + [WpfFact] + public void TestObjectCreationExpressionUsedAsExpression() + { + var initialMarkUp = @" public class Bar { public void M() @@ -1833,7 +1832,7 @@ public class Foo public int PP { get; set; } }"; - var firstResult = @" + var firstResult = @" public class Bar { public void M() @@ -1854,7 +1853,7 @@ public class Foo public int PP { get; set; } }"; - var secondResult = @" + var secondResult = @" public class Bar { public void M() @@ -1873,14 +1872,14 @@ public class Foo public int PP { get; set; } }"; - Test(firstResult, initialMarkUp); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkUp); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestObjectCreationExpressionInUsingStatement() - { - var initialMarkup = @" + [WpfFact] + public void TestObjectCreationExpressionInUsingStatement() + { + var initialMarkup = @" public class Bar { public void M() @@ -1894,7 +1893,7 @@ public class Foo public int PP { get; set; } }"; - var firstResult = @" + var firstResult = @" public class Bar { public void M() @@ -1911,7 +1910,7 @@ public class Foo public int PP { get; set; } }"; - var secondResult = @" + var secondResult = @" public class Bar { public void M() @@ -1926,15 +1925,15 @@ public class Foo public int PP { get; set; } }"; - Test(firstResult, initialMarkup); - Test(secondResult, firstResult); - } + Test(firstResult, initialMarkup); + Test(secondResult, firstResult); + } - [WpfFact] - public void TestObjectCreationExpressionWithNonEmptyInitializer() - { - Test( - @" + [WpfFact] + public void TestObjectCreationExpressionWithNonEmptyInitializer() + { + Test( + @" public class Bar { public void M() @@ -1948,7 +1947,7 @@ public class Foo public int HH { get; set; } public int PP { get; set; } }", - @" + @" public class Bar { public void M() @@ -1962,120 +1961,120 @@ public class Foo public int PP { get; set; } }"); - } + } - [WpfFact] - public void TestArrayInitializer1() - { - Test( - """ - using System.Collections.Generic; - public class Bar + [WpfFact] + public void TestArrayInitializer1() + { + Test( + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - int[] a = new int[] { 1, 2 }; - $$ - } + int[] a = new int[] { 1, 2 }; + $$ } - """, - """ - using System.Collections.Generic; - public class Bar + } + """, + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - int[] a = n$$ew in$$t[$$]$$ {$$ 1$$, 2 $$}; - } + int[] a = n$$ew in$$t[$$]$$ {$$ 1$$, 2 $$}; } - """); - } + } + """); + } - [WpfFact] - public void TestArrayInitializer2() - { - Test( - """ - using System.Collections.Generic; - public class Bar + [WpfFact] + public void TestArrayInitializer2() + { + Test( + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - int[] a = new[] { 1, 2 }; - $$ - } + int[] a = new[] { 1, 2 }; + $$ } - """, - """ - using System.Collections.Generic; - public class Bar + } + """, + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - int[] a = n$$ew[$$]$$ {$$ 1$$, 2 $$}; - } + int[] a = n$$ew[$$]$$ {$$ 1$$, 2 $$}; } - """); - } + } + """); + } - [WpfFact] - public void TestCollectionInitializerWithNonEmptyInitializer() - { - Test( - """ - using System.Collections.Generic; - public class Bar + [WpfFact] + public void TestCollectionInitializerWithNonEmptyInitializer() + { + Test( + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - var a = new List() { 1, 2 }; - $$ - } + var a = new List() { 1, 2 }; + $$ } - """, - """ - using System.Collections.Generic; - public class Bar + } + """, + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - var a = n$$ew Lis$$t($$) {$$ 1$$, 2 $$}; - } + var a = n$$ew Lis$$t($$) {$$ 1$$, 2 $$}; } - """); - } + } + """); + } - [WpfFact] - public void TestCollectionExpression() - { - Test( - """ - using System.Collections.Generic; - public class Bar + [WpfFact] + public void TestCollectionExpression() + { + Test( + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - int[] a = [1, 2]; - $$ - } + int[] a = [1, 2]; + $$ } - """, - """ - using System.Collections.Generic; - public class Bar + } + """, + """ + using System.Collections.Generic; + public class Bar + { + public void M() { - public void M() - { - int[] a = $$[$$ 1$$, 2 $$]; - } + int[] a = $$[$$ 1$$, 2 $$]; } - """); - } + } + """); + } - [WpfFact] - public void TestIfStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestIfStatementWithInnerStatement() + { + Test(@" public class Bar { public void Main(bool x) @@ -2095,12 +2094,12 @@ public void Main(bool x) var z = 1; } }"); - } + } - [WpfFact] - public void TestIfStatementWithFollowingElseClause() - { - Test(@" + [WpfFact] + public void TestIfStatementWithFollowingElseClause() + { + Test(@" public class Bar { public void Main(bool x) @@ -2122,12 +2121,12 @@ public void Main(bool x) else if (!x) } }"); - } + } - [WpfFact] - public void TestIfStatementWithoutStatement() - { - Test(@" + [WpfFact] + public void TestIfStatementWithoutStatement() + { + Test(@" public class Bar { public void Main(bool x) @@ -2145,12 +2144,12 @@ public void Main(bool x) i$$f$$ ($$x)$$ } }"); - } + } - [WpfFact] - public void TestNestIfStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestNestIfStatementWithInnerStatement() + { + Test(@" public class Bar { public void Main(int x) @@ -2176,12 +2175,12 @@ public void Main(int x) var a = 1000; } }"); - } + } - [WpfFact] - public void TestNestIfStatementWithoutInnerStatement() - { - Test(@" + [WpfFact] + public void TestNestIfStatementWithoutInnerStatement() + { + Test(@" public class Bar { public void Main(int x) @@ -2205,12 +2204,12 @@ public void Main(int x) i$$f ($$x =$$= 4)$$ } }"); - } + } - [WpfFact] - public void TestNestedElseIfStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestNestedElseIfStatementWithInnerStatement() + { + Test(@" public class Bar { public void Fo(int i) @@ -2244,12 +2243,12 @@ public void Fo(int i) } } }"); - } + } - [WpfFact] - public void TestNestIfElseStatementWithBlockWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestNestIfElseStatementWithBlockWithInnerStatement() + { + Test(@" public class Bar { public void Main(int x) @@ -2285,12 +2284,12 @@ public void Main(int x) } } }"); - } + } - [WpfFact] - public void TestEmptyDoStatement() - { - Test(@" + [WpfFact] + public void TestEmptyDoStatement() + { + Test(@" public class Bar { public void Main() @@ -2308,12 +2307,12 @@ public void Main() d$$o$$ } }"); - } + } - [WpfFact] - public void TestDoStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestDoStatementWithInnerStatement() + { + Test(@" public class Bar { public void Main() @@ -2333,12 +2332,12 @@ public void Main() var c = 10; } }"); - } + } - [WpfFact] - public void TestDoStatementWithWhileClause() - { - Test(@" + [WpfFact] + public void TestDoStatementWithWhileClause() + { + Test(@" public class Bar { public void Main() @@ -2360,12 +2359,12 @@ public void Main() while (true); } }"); - } + } - [WpfFact] - public void TestSingleElseStatement() - { - Test(@" + [WpfFact] + public void TestSingleElseStatement() + { + Test(@" public class Bar { public void Fo() @@ -2389,12 +2388,12 @@ public void Fo() e$$lse$$ } }"); - } + } - [WpfFact] - public void TestElseStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestElseStatementWithInnerStatement() + { + Test(@" public class Bar { public void Fo() @@ -2420,12 +2419,12 @@ public void Fo() var c = 10; } }"); - } + } - [WpfFact] - public void TestElseIfStatement() - { - Test(@" + [WpfFact] + public void TestElseIfStatement() + { + Test(@" public class Bar { public void Fo() @@ -2449,12 +2448,12 @@ public void Fo() e$$lse i$$f ($$false)$$ } }"); - } + } - [WpfFact] - public void TestElseIfInTheMiddleWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestElseIfInTheMiddleWithInnerStatement() + { + Test(@" public class Bar { public void Fo() @@ -2486,12 +2485,12 @@ public void Fo() } } }"); - } + } - [WpfFact] - public void TestElseClauseInNestedIfStatement() - { - Test(@" + [WpfFact] + public void TestElseClauseInNestedIfStatement() + { + Test(@" public class Bar { public void Fo(int i) @@ -2521,12 +2520,12 @@ public void Fo(int i) } } }"); - } + } - [WpfFact] - public void TestForStatementWithoutStatement() - { - Test(@" + [WpfFact] + public void TestForStatementWithoutStatement() + { + Test(@" public class Bar { public void Fo() @@ -2544,12 +2543,12 @@ public void Fo() f$$or (i$$nt i; i < 10;$$ i++)$$ } }"); - } + } - [WpfFact] - public void TestForStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestForStatementWithInnerStatement() + { + Test(@" public class Bar { public void Fo() @@ -2569,12 +2568,12 @@ public void Fo() var c = 10; } }"); - } + } - [WpfFact] - public void TestForEachStatementWithoutInnerStatement() - { - Test(@" + [WpfFact] + public void TestForEachStatementWithoutInnerStatement() + { + Test(@" public class Bar { public void Fo() @@ -2594,12 +2593,12 @@ public void Fo() var c = 10; } }"); - } + } - [WpfFact] - public void TestLockStatementWithoutInnerStatement() - { - Test(@" + [WpfFact] + public void TestLockStatementWithoutInnerStatement() + { + Test(@" public class Bar { object o = new object(); @@ -2619,12 +2618,12 @@ public void Fo() l$$ock$$(o)$$ } }"); - } + } - [WpfFact] - public void TestLockStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestLockStatementWithInnerStatement() + { + Test(@" public class Bar { object o = new object(); @@ -2646,12 +2645,12 @@ public void Fo() var i = 10; } }"); - } + } - [WpfFact] - public void TestUsingStatementWithoutInnerStatement() - { - Test(@" + [WpfFact] + public void TestUsingStatementWithoutInnerStatement() + { + Test(@" using System; public class Bar { @@ -2681,12 +2680,12 @@ public class D : IDisposable public void Dispose() {} }"); - } + } - [WpfFact] - public void TestUsingStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestUsingStatementWithInnerStatement() + { + Test(@" using System; public class Bar { @@ -2718,12 +2717,12 @@ public class D : IDisposable public void Dispose() {} }"); - } + } - [WpfFact] - public void TestUsingInLocalDeclarationStatement() - { - Test(@" + [WpfFact] + public void TestUsingInLocalDeclarationStatement() + { + Test(@" using System; public class Bar { @@ -2751,12 +2750,12 @@ public class D : IDisposable public void Dispose() {} }"); - } + } - [WpfFact] - public void TestWhileStatementWithoutInnerStatement() - { - Test(@" + [WpfFact] + public void TestWhileStatementWithoutInnerStatement() + { + Test(@" public class Bar { public void Fo() @@ -2774,12 +2773,12 @@ public void Fo() wh$$ile (tr$$ue)$$ } }"); - } + } - [WpfFact] - public void TestWhileStatementWithInnerStatement() - { - Test(@" + [WpfFact] + public void TestWhileStatementWithInnerStatement() + { + Test(@" public class Bar { public void Fo() @@ -2799,12 +2798,12 @@ public void Fo() var c = 10; } }"); - } + } - [WpfFact] - public void TestSwitchExpression1() - { - Test(@" + [WpfFact] + public void TestSwitchExpression1() + { + Test(@" public class Bar { public void Goo(int c) @@ -2815,7 +2814,7 @@ public void Goo(int c) } } }", - @" + @" public class Bar { public void Goo(int c) @@ -2824,12 +2823,12 @@ public void Goo(int c) } }"); - } + } - [WpfFact] - public void TestSwitchExpression2() - { - Test(@" + [WpfFact] + public void TestSwitchExpression2() + { + Test(@" public class Bar { public void Goo(int c) @@ -2840,7 +2839,7 @@ public void Goo(int c) } } }", - @" + @" public class Bar { public void Goo(int c) @@ -2849,15 +2848,15 @@ public void Goo(int c) } }"); - } + } - [WpfFact] - public void TestSwitchStatementWithOnlyOpenParenthesis() - { - // This test is to make sure {} will be added to the switch statement, - // but our formatter now can't format the case when the CloseParenthesis token is missing. - // If any future formatter improvement can handle this case, this test can be modified safely - Test(@" + [WpfFact] + public void TestSwitchStatementWithOnlyOpenParenthesis() + { + // This test is to make sure {} will be added to the switch statement, + // but our formatter now can't format the case when the CloseParenthesis token is missing. + // If any future formatter improvement can handle this case, this test can be modified safely + Test(@" public class bar { public void TT() @@ -2875,12 +2874,12 @@ public void TT() swi$$tch ($$ } }"); - } + } - [WpfFact] - public void TestSwitchStatement() - { - Test(@" + [WpfFact] + public void TestSwitchStatement() + { + Test(@" public class bar { public void TT() @@ -2900,12 +2899,12 @@ public void TT() switc$$h ($$i)$$ } }"); - } + } - [WpfFact] - public void TestValidSwitchStatement() - { - Test(@" + [WpfFact] + public void TestValidSwitchStatement() + { + Test(@" public class bar { public void TT() @@ -2927,12 +2926,12 @@ public void TT() } } }"); - } + } - [WpfFact] - public void TestValidTryStatement() - { - Test(@" + [WpfFact] + public void TestValidTryStatement() + { + Test(@" public class bar { public void TT() @@ -2952,12 +2951,12 @@ public void TT() } } }"); - } + } - [WpfFact] - public void TestTryStatement() - { - Test(@" + [WpfFact] + public void TestTryStatement() + { + Test(@" public class bar { public void TT() @@ -2975,12 +2974,12 @@ public void TT() tr$$y$$ } }"); - } + } - [WpfFact] - public void TestValidCatchClause() - { - Test(@" + [WpfFact] + public void TestValidCatchClause() + { + Test(@" public class Bar { public void TT() @@ -3006,12 +3005,12 @@ public void TT() } } }"); - } + } - [WpfFact] - public void TestCatchClauseWithException() - { - Test(@" + [WpfFact] + public void TestCatchClauseWithException() + { + Test(@" public class Bar { public void TT() @@ -3035,12 +3034,12 @@ public void TT() cat$$ch (Syste$$m.Exception)$$ } }"); - } + } - [WpfFact] - public void TestSingleCatchClause() - { - Test(@" + [WpfFact] + public void TestSingleCatchClause() + { + Test(@" public class bar { public void TT() @@ -3064,12 +3063,12 @@ public void TT() cat$$ch$$ } }"); - } + } - [WpfFact] - public void TestCatchClauseWithWhenClause() - { - Test(@" + [WpfFact] + public void TestCatchClauseWithWhenClause() + { + Test(@" public class bar { public void TT() @@ -3093,12 +3092,12 @@ public void TT() c$$atch (Ex$$ception) whe$$n (tru$$e)$$ } }"); - } + } - [WpfFact] - public void TestFinallyCaluse() - { - Test(@" + [WpfFact] + public void TestFinallyCaluse() + { + Test(@" public class Bar { public void Bar2() @@ -3128,12 +3127,12 @@ public void Bar2() fin$$ally$$ } }"); - } + } - [WpfFact] - public void TestValidFinallyCaluse() - { - Test(@" + [WpfFact] + public void TestValidFinallyCaluse() + { + Test(@" public class Bar { public void Bar2() @@ -3165,12 +3164,12 @@ public void Bar2() } } }"); - } + } - [WpfFact] - public void TestObjectCreationExpressionWithMissingType() - { - Test(@" + [WpfFact] + public void TestObjectCreationExpressionWithMissingType() + { + Test(@" public class Bar { public void Bar2() @@ -3189,12 +3188,12 @@ public void Bar2() Bar b = new$$ } }"); - } + } - [WpfFact] - public void TestRemoveInitializerForImplicitObjectCreationExpression() - { - Test(@" + [WpfFact] + public void TestRemoveInitializerForImplicitObjectCreationExpression() + { + Test(@" public class Bar { public void Bar2() @@ -3214,14 +3213,14 @@ public void Bar2() }; } }"); - } + } - [WpfTheory] - [InlineData("checked")] - [InlineData("unchecked")] - public void TestCheckedStatement(string keywordToken) - { - Test($@" + [WpfTheory] + [InlineData("checked")] + [InlineData("unchecked")] + public void TestCheckedStatement(string keywordToken) + { + Test($@" public class Bar {{ public void Bar2() @@ -3240,14 +3239,14 @@ public void Bar2() {keywordToken}$$ }} }}"); - } + } - [WpfTheory] - [InlineData("checked")] - [InlineData("unchecked")] - public void TextCheckedExpression(string keywordToken) - { - Test($@" + [WpfTheory] + [InlineData("checked")] + [InlineData("unchecked")] + public void TextCheckedExpression(string keywordToken) + { + Test($@" public class Bar {{ public void Bar2() @@ -3264,12 +3263,12 @@ public void Bar2() var i = {keywordToken}$$(1 +$$ 1)$$ }} }}"); - } + } - [WpfFact] - public void TestConvertFieldToPropertyWithAttributeAndComment() - { - Test(@" + [WpfFact] + public void TestConvertFieldToPropertyWithAttributeAndComment() + { + Test(@" public class Bar { public int Property @@ -3292,12 +3291,12 @@ public int Property$$ [SomeAttri] public void Method() { } }"); - } + } - [WpfFact] - public void TestConvertEventFieldToPropertyWithAttributeAndComment() - { - Test(@" + [WpfFact] + public void TestConvertEventFieldToPropertyWithAttributeAndComment() + { + Test(@" public class Bar { public event EventHandler MyEvent @@ -3320,19 +3319,18 @@ public event EventHandler MyEvent$$ [SomeAttri] public void Method() { } }"); - } + } - protected override string Language => LanguageNames.CSharp; + protected override string Language => LanguageNames.CSharp; - protected override Action CreateNextHandler(EditorTestWorkspace workspace) - => () => { }; + protected override Action CreateNextHandler(EditorTestWorkspace workspace) + => () => { }; - internal override IChainedCommandHandler GetCommandHandler(EditorTestWorkspace workspace) - { - return Assert.IsType( - workspace.GetService( - ContentTypeNames.CSharpContentType, - PredefinedCommandHandlerNames.AutomaticLineEnder)); - } + internal override IChainedCommandHandler GetCommandHandler(EditorTestWorkspace workspace) + { + return Assert.IsType( + workspace.GetService( + ContentTypeNames.CSharpContentType, + PredefinedCommandHandlerNames.AutomaticLineEnder)); } } diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs index 99fe39fe9f6f9..6b134de149004 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs @@ -8,654 +8,653 @@ using Xunit; using static Microsoft.CodeAnalysis.BraceCompletion.AbstractBraceCompletionService; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion; + +[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] +public sealed class AutomaticLiteralCompletionTests : AbstractAutomaticBraceCompletionTests { - [Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] - public sealed class AutomaticLiteralCompletionTests : AbstractAutomaticBraceCompletionTests - { - [WpfFact] - public void Creation() - { - using var session = CreateSessionSingleQuote("$$"); - Assert.NotNull(session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - public void String_TopLevel() - { - using var session = CreateSessionDoubleQuote("$$"); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - public void VerbatimString_TopLevel() - { - using var session = CreateSessionDoubleQuote("@$$"); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - public void Char_TopLevel() - { - using var session = CreateSessionSingleQuote("$$"); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - public void String_TopLevel2() - { - using var session = CreateSessionDoubleQuote("using System;$$"); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - public void VerbatimString_TopLevel2() - { - using var session = CreateSessionDoubleQuote("using System;@$$"); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void String_String() - { - var code = """ - class C - { - void Method() - { - var s = ""$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.Null(session); - } - - [WpfFact] - public void String_VerbatimString() - { - var code = """ - class C - { - void Method() - { - var s = ""@$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.Null(session); - } - - [WpfFact] - public void String_Char() - { - var code = """ - class C - { - void Method() - { - var s = @""$$ - } - } - """; - using var session = CreateSessionSingleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Method_String() - { - var code = """ - class C - { - void Method() - { - var s = $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Method_String_Delete() - { - var code = """ - class C - { - void Method() - { - var s = $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void Method_String_Tab() - { - var code = """ - class C - { - void Method() - { - var s = $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void Method_String_Quotation() - { - var code = """ - class C - { - void Method() - { - var s = $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void VerbatimMethod_String() - { - var code = """ - class C - { - void Method() - { - var s = @$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void VerbatimMethod_String_Delete() - { - var code = """ - class C - { - void Method() - { - var s = @$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void VerbatimMethod_String_Tab() - { - var code = """ - class C - { - void Method() - { - var s = @$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void VerbatimMethod_String_Quotation() - { - var code = """ - class C - { - void Method() - { - var s = @$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void Method_InterpolatedString() - { - var code = """ - class C - { - void Method() - { - var s = $[||]$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Method_InterpolatedString_Delete() - { - var code = """ - class C - { - void Method() - { - var s = $[||]$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void Method_InterpolatedString_Tab() - { - var code = """ - class C - { - void Method() - { - var s = $[||]$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void Method_InterpolatedString_Quotation() - { - var code = """ - class C - { - void Method() - { - var s = $[||]$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void VerbatimMethod_InterpolatedString() - { - var code = """ - class C - { - void Method() - { - var s = $@$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void VerbatimMethod_InterpolatedString_Delete() - { - var code = """ - class C - { - void Method() - { - var s = $@$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void VerbatimMethod_InterpolatedString_Tab() - { - var code = """ - class C - { - void Method() - { - var s = $@$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void VerbatimMethod_InterpolatedString_Quotation() - { - var code = """ - class C - { - void Method() - { - var s = $@$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void Preprocessor1() - { - var code = """ - class C - { - void Method() - { - #line $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void Preprocessor2() - { - var code = """ - class C - { - void Method() - { - #line $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void Preprocessor3() - { - var code = """ - class C - { - void Method() - { - #line $$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546047")] - public void VerbatimStringDoubleQuote() - { - var code = """ - class C - { - void Method() - { - var s = @""$$ - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.Null(session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] - public void String_CompleteLiteral() - { - var code = """ - class C - { - void Method() - { - var s = "this" + $$that"; - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] - public void String_BeforeOtherString1() - { - var code = """ - class C - { - void Method() - { - var s = $$ + " + bar"; - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] - public void String_BeforeOtherString2() - { - var code = """ - class C - { - void Method() - { - var s = $$ + "; } "; - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] - public void String_DoNotCompleteVerbatim() - { - var code = """ - class C - { - void Method() - { - var s = "this" + @$$that - and this"; - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] - public void String_CompleteLiteral_EndOfFile() - { - var code = """ - class C - { - void Method() - { - var s = "this" + $$that" - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] - public void String_InArgumentList1() - { - var code = """ - class C - { - void Method() - { - var s = Goo($[||]$$); - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] - public void String_InArgumentList2() - { - var code = """ - class C - { - void Method() - { - var s = Goo(@[||]$$); - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] - public void String_InArgumentList3() - { - var code = """ - class C - { - void Method() - { - var s = Goo(@$[||]$$); - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] - public void String_InArgumentList4() - { - var code = """ - class C - { - void Method() - { - var s = Goo($@[||]$$); - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] - public void String_InArgumentList5() - { - var code = """ - class C - { - void Method() - { - // Handled by normal verbatim string handler. - var s = Goo(@[||]$$); - } - } - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] - public void String_GlobalStatement() - { - var code = """ - $[||]$$ - """; - using var session = CreateSessionDoubleQuote(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - internal static Holder CreateSessionSingleQuote(string code) - { - return CreateSession( - EditorTestWorkspace.CreateCSharp(code), - SingleQuote.OpenCharacter, SingleQuote.CloseCharacter); - } - - internal static Holder CreateSessionDoubleQuote(string code) - { - return CreateSession( - EditorTestWorkspace.CreateCSharp(code), - DoubleQuote.OpenCharacter, DoubleQuote.CloseCharacter); - } + [WpfFact] + public void Creation() + { + using var session = CreateSessionSingleQuote("$$"); + Assert.NotNull(session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + public void String_TopLevel() + { + using var session = CreateSessionDoubleQuote("$$"); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + public void VerbatimString_TopLevel() + { + using var session = CreateSessionDoubleQuote("@$$"); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + public void Char_TopLevel() + { + using var session = CreateSessionSingleQuote("$$"); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + public void String_TopLevel2() + { + using var session = CreateSessionDoubleQuote("using System;$$"); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + public void VerbatimString_TopLevel2() + { + using var session = CreateSessionDoubleQuote("using System;@$$"); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void String_String() + { + var code = """ + class C + { + void Method() + { + var s = ""$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.Null(session); + } + + [WpfFact] + public void String_VerbatimString() + { + var code = """ + class C + { + void Method() + { + var s = ""@$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.Null(session); + } + + [WpfFact] + public void String_Char() + { + var code = """ + class C + { + void Method() + { + var s = @""$$ + } + } + """; + using var session = CreateSessionSingleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Method_String() + { + var code = """ + class C + { + void Method() + { + var s = $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Method_String_Delete() + { + var code = """ + class C + { + void Method() + { + var s = $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void Method_String_Tab() + { + var code = """ + class C + { + void Method() + { + var s = $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void Method_String_Quotation() + { + var code = """ + class C + { + void Method() + { + var s = $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void VerbatimMethod_String() + { + var code = """ + class C + { + void Method() + { + var s = @$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void VerbatimMethod_String_Delete() + { + var code = """ + class C + { + void Method() + { + var s = @$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void VerbatimMethod_String_Tab() + { + var code = """ + class C + { + void Method() + { + var s = @$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void VerbatimMethod_String_Quotation() + { + var code = """ + class C + { + void Method() + { + var s = @$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void Method_InterpolatedString() + { + var code = """ + class C + { + void Method() + { + var s = $[||]$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Method_InterpolatedString_Delete() + { + var code = """ + class C + { + void Method() + { + var s = $[||]$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void Method_InterpolatedString_Tab() + { + var code = """ + class C + { + void Method() + { + var s = $[||]$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void Method_InterpolatedString_Quotation() + { + var code = """ + class C + { + void Method() + { + var s = $[||]$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void VerbatimMethod_InterpolatedString() + { + var code = """ + class C + { + void Method() + { + var s = $@$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void VerbatimMethod_InterpolatedString_Delete() + { + var code = """ + class C + { + void Method() + { + var s = $@$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void VerbatimMethod_InterpolatedString_Tab() + { + var code = """ + class C + { + void Method() + { + var s = $@$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void VerbatimMethod_InterpolatedString_Quotation() + { + var code = """ + class C + { + void Method() + { + var s = $@$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void Preprocessor1() + { + var code = """ + class C + { + void Method() + { + #line $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void Preprocessor2() + { + var code = """ + class C + { + void Method() + { + #line $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void Preprocessor3() + { + var code = """ + class C + { + void Method() + { + #line $$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546047")] + public void VerbatimStringDoubleQuote() + { + var code = """ + class C + { + void Method() + { + var s = @""$$ + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.Null(session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] + public void String_CompleteLiteral() + { + var code = """ + class C + { + void Method() + { + var s = "this" + $$that"; + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] + public void String_BeforeOtherString1() + { + var code = """ + class C + { + void Method() + { + var s = $$ + " + bar"; + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] + public void String_BeforeOtherString2() + { + var code = """ + class C + { + void Method() + { + var s = $$ + "; } "; + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] + public void String_DoNotCompleteVerbatim() + { + var code = """ + class C + { + void Method() + { + var s = "this" + @$$that + and this"; + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/59178")] + public void String_CompleteLiteral_EndOfFile() + { + var code = """ + class C + { + void Method() + { + var s = "this" + $$that" + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] + public void String_InArgumentList1() + { + var code = """ + class C + { + void Method() + { + var s = Goo($[||]$$); + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] + public void String_InArgumentList2() + { + var code = """ + class C + { + void Method() + { + var s = Goo(@[||]$$); + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] + public void String_InArgumentList3() + { + var code = """ + class C + { + void Method() + { + var s = Goo(@$[||]$$); + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] + public void String_InArgumentList4() + { + var code = """ + class C + { + void Method() + { + var s = Goo($@[||]$$); + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] + public void String_InArgumentList5() + { + var code = """ + class C + { + void Method() + { + // Handled by normal verbatim string handler. + var s = Goo(@[||]$$); + } + } + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/62571")] + public void String_GlobalStatement() + { + var code = """ + $[||]$$ + """; + using var session = CreateSessionDoubleQuote(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + internal static Holder CreateSessionSingleQuote(string code) + { + return CreateSession( + EditorTestWorkspace.CreateCSharp(code), + SingleQuote.OpenCharacter, SingleQuote.CloseCharacter); + } + + internal static Holder CreateSessionDoubleQuote(string code) + { + return CreateSession( + EditorTestWorkspace.CreateCSharp(code), + DoubleQuote.OpenCharacter, DoubleQuote.CloseCharacter); } } diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs index 226a300a88580..993f53e89eebe 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs @@ -4,202 +4,199 @@ #nullable disable -using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using static Microsoft.CodeAnalysis.BraceCompletion.AbstractBraceCompletionService; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AutomaticCompletion; + +[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] +public class AutomaticParenthesisCompletionTests : AbstractAutomaticBraceCompletionTests { - [Trait(Traits.Feature, Traits.Features.AutomaticCompletion)] - public class AutomaticParenthesisCompletionTests : AbstractAutomaticBraceCompletionTests + [WpfFact] + public void Creation() { - [WpfFact] - public void Creation() - { - using var session = CreateSession("$$"); - Assert.NotNull(session); - } - - [WpfFact] - public void String1() - { - var code = """ - class C - { - void Method() - { - var s = ""$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void String2() - { - var code = """ - class C - { - void Method() - { - var s = @""$$ - } - } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void ParameterList_OpenParenthesis() - { - var code = """ - class C - { - void Method$$ - } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void ParameterList_OpenParenthesis_Delete() - { - var code = """ - class C + using var session = CreateSession("$$"); + Assert.NotNull(session); + } + + [WpfFact] + public void String1() + { + var code = """ + class C + { + void Method() { - void Method$$ + var s = ""$$ } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckBackspace(session.Session); - } - - [WpfFact] - public void ParameterList_OpenParenthesis_Tab() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void String2() + { + var code = """ + class C + { + void Method() { - void Method$$ + var s = @""$$ } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckTab(session.Session); - } - - [WpfFact] - public void ParameterList_OpenParenthesis_CloseParenthesis() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void ParameterList_OpenParenthesis() + { + var code = """ + class C + { + void Method$$ + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void ParameterList_OpenParenthesis_Delete() + { + var code = """ + class C + { + void Method$$ + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckBackspace(session.Session); + } + + [WpfFact] + public void ParameterList_OpenParenthesis_Tab() + { + var code = """ + class C + { + void Method$$ + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckTab(session.Session); + } + + [WpfFact] + public void ParameterList_OpenParenthesis_CloseParenthesis() + { + var code = """ + class C + { + void Method$$ + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + CheckOverType(session.Session); + } + + [WpfFact] + public void Argument() + { + var code = """ + class C + { + void Method() { - void Method$$ + Method$$ } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - CheckOverType(session.Session); - } - - [WpfFact] - public void Argument() - { - var code = """ - class C + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Argument_Invalid() + { + var code = """ + class C + { + void Method() { - void Method() - { - Method$$ - } + Method($$) } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Argument_Invalid() - { - var code = """ - class C + } + """; + + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact] + public void Array_Nested() + { + var code = """ + class C + { + int Method(int i) { - void Method() - { - Method($$) - } + Method(Method$$) } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact] - public void Array_Nested() - { - var code = """ - class C + } + """; + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546337")] + public void OpenParenthesisWithExistingCloseParen() + { + var code = """ + class A + { + public A(int a, int b) { } + + public static A Create() { - int Method(int i) - { - Method(Method$$) - } + return new A$$ + 0, 0); } - """; - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546337")] - public void OpenParenthesisWithExistingCloseParen() - { - var code = """ - class A - { - public A(int a, int b) { } + } + """; - public static A Create() - { - return new A$$ - 0, 0); - } - } - """; - - using var session = CreateSession(code); - Assert.NotNull(session); - CheckStart(session.Session, expectValidSession: false); - } - - internal static Holder CreateSession(string code) - { - return CreateSession( - EditorTestWorkspace.CreateCSharp(code), - Parenthesis.OpenCharacter, Parenthesis.CloseCharacter); - } + using var session = CreateSession(code); + Assert.NotNull(session); + CheckStart(session.Session, expectValidSession: false); + } + + internal static Holder CreateSession(string code) + { + return CreateSession( + EditorTestWorkspace.CreateCSharp(code), + Parenthesis.OpenCharacter, Parenthesis.CloseCharacter); } } diff --git a/src/EditorFeatures/CSharpTest/BlockCommentEditing/BlockCommentEditingTests.cs b/src/EditorFeatures/CSharpTest/BlockCommentEditing/BlockCommentEditingTests.cs index 199d5fbe40ce7..08b0b2dece9e1 100644 --- a/src/EditorFeatures/CSharpTest/BlockCommentEditing/BlockCommentEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/BlockCommentEditing/BlockCommentEditingTests.cs @@ -6,7 +6,6 @@ using Microsoft.CodeAnalysis.Editor.CSharp.BlockCommentEditing; using Microsoft.CodeAnalysis.Editor.UnitTests; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text; @@ -15,713 +14,712 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BlockCommentEditing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BlockCommentEditing; + +[Trait(Traits.Feature, Traits.Features.BlockCommentEditing)] +public class BlockCommentEditingTests : AbstractTypingCommandHandlerTest { - [Trait(Traits.Feature, Traits.Features.BlockCommentEditing)] - public class BlockCommentEditingTests : AbstractTypingCommandHandlerTest + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11057")] + public void EdgeCase0() { - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11057")] - public void EdgeCase0() - { - var code = @" + var code = @" $$/**/ "; - var expected = @" + var expected = @" $$/**/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11057")] - public void EdgeCase1() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11057")] + public void EdgeCase1() + { + var code = @" /**/$$ "; - var expected = @" + var expected = @" /**/ $$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11056")] - public void EdgeCase2() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11056")] + public void EdgeCase2() + { + var code = @" $$/* */ "; - var expected = @" + var expected = @" $$/* */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11056")] - public void EdgeCase3() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/11056")] + public void EdgeCase3() + { + var code = @" /* */$$ "; - var expected = @" + var expected = @" /* */ $$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/16128")] - public void EofCase0() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/16128")] + public void EofCase0() + { + var code = @" /* */$$"; - var expected = @" + var expected = @" /* */ $$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/16128")] - public void EofCase1() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/16128")] + public void EofCase1() + { + var code = @" /*$$"; - var expected = @" + var expected = @" /* * $$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/16128")] - public void EofCase2() - { - var code = @" + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/16128")] + public void EofCase2() + { + var code = @" /***$$"; - var expected = @" + var expected = @" /*** * $$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine0() - { - var code = @" + [WpfFact] + public void InsertOnStartLine0() + { + var code = @" /*$$ "; - var expected = @" + var expected = @" /* * $$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine1() - { - var code = @" + [WpfFact] + public void InsertOnStartLine1() + { + var code = @" /*$$*/ "; - var expected = @" + var expected = @" /* $$*/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine2() - { - var code = @" + [WpfFact] + public void InsertOnStartLine2() + { + var code = @" /*$$ */ "; - var expected = @" + var expected = @" /* * $$*/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine3() - { - var code = @" + [WpfFact] + public void InsertOnStartLine3() + { + var code = @" /* $$ 1. */ "; - var expected = @" + var expected = @" /* * $$1. */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine4() - { - var code = @" + [WpfFact] + public void InsertOnStartLine4() + { + var code = @" /* 1.$$ */ "; - var expected = @" + var expected = @" /* 1. * $$ */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine5() - { - var code = @" + [WpfFact] + public void InsertOnStartLine5() + { + var code = @" /********$$ "; - var expected = @" + var expected = @" /******** * $$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine6() - { - var code = @" + [WpfFact] + public void InsertOnStartLine6() + { + var code = @" /**$$ "; - var expected = @" + var expected = @" /** * $$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine7() - { - var code = @" + [WpfFact] + public void InsertOnStartLine7() + { + var code = @" /* $$ "; - var expected = @" + var expected = @" /* * $$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void NotInsertOnStartLine0() - { - var code = @" + [WpfFact] + public void NotInsertOnStartLine0() + { + var code = @" /$$* */ "; - var expected = @" + var expected = @" / $$* */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine0() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine0() + { + var code = @" /* *$$ "; - var expected = @" + var expected = @" /* * *$$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine1() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine1() + { + var code = @" /* *$$*/ "; - var expected = @" + var expected = @" /* * $$*/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine2() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine2() + { + var code = @" /* *$$ */ "; - var expected = @" + var expected = @" /* * *$$*/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine3() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine3() + { + var code = @" /* * $$ 1. */ "; - var expected = @" + var expected = @" /* * * $$1. */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine4() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine4() + { + var code = @" /* * 1.$$ */ "; - var expected = @" + var expected = @" /* * 1. * $$ */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine5() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine5() + { + var code = @" /* * 1. * $$ */ "; - var expected = @" + var expected = @" /* * 1. * * $$ */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine6() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine6() + { + var code = @" /* $$ * */ "; - var expected = @" + var expected = @" /* $$* */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine7() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine7() + { + var code = @" /* *************$$ */ "; - var expected = @" + var expected = @" /* ************* *$$ */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine8() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine8() + { + var code = @" /** *$$ */ "; - var expected = @" + var expected = @" /** * *$$ */ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine9() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine9() + { + var code = @" /** *$$ "; - var expected = @" + var expected = @" /** * *$$ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnEndLine0() - { - var code = @" + [WpfFact] + public void InsertOnEndLine0() + { + var code = @" /* *$$/ "; - var expected = @" + var expected = @" /* * *$$/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnEndLine1() - { - var code = @" + [WpfFact] + public void InsertOnEndLine1() + { + var code = @" /** *$$/ "; - var expected = @" + var expected = @" /** * *$$/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnEndLine2() - { - var code = @" + [WpfFact] + public void InsertOnEndLine2() + { + var code = @" /** * *$$/ "; - var expected = @" + var expected = @" /** * * *$$/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnEndLine3() - { - var code = @" + [WpfFact] + public void InsertOnEndLine3() + { + var code = @" /* $$ */ "; - var expected = @" + var expected = @" /* $$*/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnEndLine4() - { - var code = @" + [WpfFact] + public void InsertOnEndLine4() + { + var code = @" /* $$*/ "; - var expected = @" + var expected = @" /* $$*/ "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void NotInsertInVerbatimString0() - { - var code = @" + [WpfFact] + public void NotInsertInVerbatimString0() + { + var code = @" var code = @"" /*$$ ""; "; - var expected = @" + var expected = @" var code = @"" /* $$ ""; "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void NotInsertInVerbatimString1() - { - var code = @" + [WpfFact] + public void NotInsertInVerbatimString1() + { + var code = @" var code = @"" /* *$$ ""; "; - var expected = @" + var expected = @" var code = @"" /* * $$ ""; "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void BoundCheckInsertOnStartLine0() - { - var code = @" + [WpfFact] + public void BoundCheckInsertOnStartLine0() + { + var code = @" /$$*"; - var expected = @" + var expected = @" / $$*"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void BoundCheckInsertOnStartLine1() - { - var code = @" + [WpfFact] + public void BoundCheckInsertOnStartLine1() + { + var code = @" /*$$ "; - var expected = @" + var expected = @" /* * $$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void BoundCheckInsertOnMiddleLine() - { - var code = @" + [WpfFact] + public void BoundCheckInsertOnMiddleLine() + { + var code = @" /* *$$ "; - var expected = @" + var expected = @" /* * *$$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void BoundCheckInsertOnEndLine() - { - var code = @" + [WpfFact] + public void BoundCheckInsertOnEndLine() + { + var code = @" /* *$$/"; - var expected = @" + var expected = @" /* * *$$/"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InsertOnStartLine2_Tab() - { - var code = @" + [WpfFact] + public void InsertOnStartLine2_Tab() + { + var code = @" /*$$*/ "; - var expected = @" + var expected = @" /* * $$*/ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnStartLine3_Tab() - { - var code = @" + [WpfFact] + public void InsertOnStartLine3_Tab() + { + var code = @" /*$$1. */ "; - var expected = @" + var expected = @" /* *$$1. */ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnStartLine4_Tab() - { - var code = @" + [WpfFact] + public void InsertOnStartLine4_Tab() + { + var code = @" /* 1.$$ */ "; - var expected = @" + var expected = @" /* 1. * $$ */ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnStartLine6_Tab() - { - var code = @" + [WpfFact] + public void InsertOnStartLine6_Tab() + { + var code = @" /*$$ "; - var expected = @" + var expected = @" /* *$$ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine2_Tab() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine2_Tab() + { + var code = @" /* *$$*/ "; - var expected = @" + var expected = @" /* * *$$*/ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine3_Tab() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine3_Tab() + { + var code = @" /* * $$1. */ "; - var expected = @" + var expected = @" /* * * $$1. */ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine4_Tab() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine4_Tab() + { + var code = @" /* * 1.$$ */ "; - var expected = @" + var expected = @" /* * 1. * $$ */ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InsertOnMiddleLine5_Tab() - { - var code = @" + [WpfFact] + public void InsertOnMiddleLine5_Tab() + { + var code = @" /* * 1. * $$ */ "; - var expected = @" + var expected = @" /* * 1. * * $$ */ "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - [WpfFact] - public void InLanguageConstructTrailingTrivia() - { - var code = @" + [WpfFact] + public void InLanguageConstructTrailingTrivia() + { + var code = @" class C { int i; /*$$ } "; - var expected = @" + var expected = @" class C { int i; /* * $$ } "; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void InLanguageConstructTrailingTrivia_Tabs() - { - var code = @" + [WpfFact] + public void InLanguageConstructTrailingTrivia_Tabs() + { + var code = @" class C { int i; /*$$ } "; - var expected = @" + var expected = @" class C { int i; /* * $$ } "; - VerifyTabs(code, expected); - } + VerifyTabs(code, expected); + } - protected override EditorTestWorkspace CreateTestWorkspace(string initialMarkup) - => EditorTestWorkspace.CreateCSharp(initialMarkup); + protected override EditorTestWorkspace CreateTestWorkspace(string initialMarkup) + => EditorTestWorkspace.CreateCSharp(initialMarkup); - protected override (ReturnKeyCommandArgs, string insertionText) CreateCommandArgs(ITextView textView, ITextBuffer textBuffer) - => (new ReturnKeyCommandArgs(textView, textBuffer), "\r\n"); + protected override (ReturnKeyCommandArgs, string insertionText) CreateCommandArgs(ITextView textView, ITextBuffer textBuffer) + => (new ReturnKeyCommandArgs(textView, textBuffer), "\r\n"); - internal override ICommandHandler GetCommandHandler(EditorTestWorkspace workspace) - => Assert.IsType(workspace.GetService(ContentTypeNames.CSharpContentType, nameof(BlockCommentEditingCommandHandler))); - } + internal override ICommandHandler GetCommandHandler(EditorTestWorkspace workspace) + => Assert.IsType(workspace.GetService(ContentTypeNames.CSharpContentType, nameof(BlockCommentEditingCommandHandler))); } diff --git a/src/EditorFeatures/CSharpTest/BlockCommentEditing/CloseBlockCommentTests.cs b/src/EditorFeatures/CSharpTest/BlockCommentEditing/CloseBlockCommentTests.cs index 7b66495b77f2c..b64399895711e 100644 --- a/src/EditorFeatures/CSharpTest/BlockCommentEditing/CloseBlockCommentTests.cs +++ b/src/EditorFeatures/CSharpTest/BlockCommentEditing/CloseBlockCommentTests.cs @@ -5,9 +5,7 @@ #nullable disable using Microsoft.CodeAnalysis.Editor.CSharp.BlockCommentEditing; -using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.UnitTests; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Commanding; @@ -17,364 +15,363 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BlockCommentEditing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BlockCommentEditing; + +[Trait(Traits.Feature, Traits.Features.BlockCommentEditing)] +public sealed class CloseBlockCommentTests : AbstractTypingCommandHandlerTest { - [Trait(Traits.Feature, Traits.Features.BlockCommentEditing)] - public sealed class CloseBlockCommentTests : AbstractTypingCommandHandlerTest + [WpfFact] + public void ClosedRegularlyAfterAsterisk() { - [WpfFact] - public void ClosedRegularlyAfterAsterisk() - { - var code = """ - /* - * - *$$ - """; - var expected = """ - /* - * - */$$ - """; - Verify(code, expected); - } + var code = """ + /* + * + *$$ + """; + var expected = """ + /* + * + */$$ + """; + Verify(code, expected); + } - [WpfFact] - public void ClosedAfterAsteriskSpace1() - { - var code = """ - /* - * - * $$ - """; - var expected = """ - /* - * - */$$ - """; - Verify(code, expected); - } + [WpfFact] + public void ClosedAfterAsteriskSpace1() + { + var code = """ + /* + * + * $$ + """; + var expected = """ + /* + * + */$$ + """; + Verify(code, expected); + } - [WpfFact] - public void ClosedAfterAsteriskSpace2() - { - var code = """ - /* - * $$ - """; - var expected = """ - /* - */$$ - """; - Verify(code, expected); - } + [WpfFact] + public void ClosedAfterAsteriskSpace2() + { + var code = """ + /* + * $$ + """; + var expected = """ + /* + */$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterSlashAsteriskSpace() - { - var code = """ - /* $$ - """; - var expected = """ - /* /$$ - """; - Verify(code, expected); - } - - [WpfFact] - public void NotClosedAfterSlashDoubleAsteriskSpace() - { - var code = """ - /** $$ - """; - var expected = """ - /** /$$ - """; - Verify(code, expected); - } - - [WpfFact] - public void NotClosedAfterSpaceWithoutAsterisk() - { - var code = """ - /* - * - $$ - """; - var expected = """ - /* - * - /$$ - """; - Verify(code, expected); - } + [WpfFact] + public void NotClosedAfterSlashAsteriskSpace() + { + var code = """ + /* $$ + """; + var expected = """ + /* /$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithNonWhitespaceBeforeAsterisk1() - { - var code = """ - /* - * - ** $$ - """; - var expected = """ - /* - * - ** /$$ - """; - Verify(code, expected); - } + [WpfFact] + public void NotClosedAfterSlashDoubleAsteriskSpace() + { + var code = """ + /** $$ + """; + var expected = """ + /** /$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithNonWhitespaceBeforeAsterisk2() - { - var code = """ - /* - * - /* $$ - """; - var expected = """ - /* - * - /* /$$ - """; - Verify(code, expected); - } + [WpfFact] + public void NotClosedAfterSpaceWithoutAsterisk() + { + var code = """ + /* + * + $$ + """; + var expected = """ + /* + * + /$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithNonWhitespaceBeforeAsterisk3() - { - var code = """ - /* - * - a * $$ - """; - var expected = """ - /* - * - a * /$$ - """; - Verify(code, expected); - } - - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithNonWhitespaceAfterCursor1() - { - var code = """ - /* - * - * $$/ - """; - var expected = """ - /* - * - * /$$/ - """; - Verify(code, expected); - } + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithNonWhitespaceBeforeAsterisk1() + { + var code = """ + /* + * + ** $$ + """; + var expected = """ + /* + * + ** /$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithNonWhitespaceAfterCursor2() - { - var code = """ - /* - * - * $$* - """; - var expected = """ - /* - * - * /$$* - """; - Verify(code, expected); - } + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithNonWhitespaceBeforeAsterisk2() + { + var code = """ + /* + * + /* $$ + """; + var expected = """ + /* + * + /* /$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithNonWhitespaceAfterCursor3() - { - var code = """ + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithNonWhitespaceBeforeAsterisk3() + { + var code = """ /* * - * $$ a - """; - var expected = """ + a * $$ + """; + var expected = """ /* * - * /$$ a - """; - Verify(code, expected); - } + a * /$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithWhitespaceAfterCursor() - { - // Note: There is a single trailing space after the cursor. - var code = """ + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithNonWhitespaceAfterCursor1() + { + var code = """ + /* + * + * $$/ + """; + var expected = """ + /* + * + * /$$/ + """; + Verify(code, expected); + } + + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithNonWhitespaceAfterCursor2() + { + var code = """ + /* + * + * $$* + """; + var expected = """ + /* + * + * /$$* + """; + Verify(code, expected); + } + + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithNonWhitespaceAfterCursor3() + { + var code = """ + /* + * + * $$ a + """; + var expected = """ + /* + * + * /$$ a + """; + Verify(code, expected); + } + + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithWhitespaceAfterCursor() + { + // Note: There is a single trailing space after the cursor. + var code = """ + /* + * + * $$ + """; + var expected = """ + /* + * + * /$$ + """; + Verify(code, expected); + } + + [WpfFact] + public void NotClosedAfterAsteriskDoubleSpace() + { + var code = """ + /* + * + * $$ + """; + var expected = """ + /* + * + * /$$ + """; + Verify(code, expected); + } + + [WpfFact] + public void ClosedAfterAsteriskSpaceWithNothingBeforeAsterisk() + { + var code = """ /* * - * $$ - """; - var expected = """ + * $$ + """; + var expected = """ /* * - * /$$ - """; - Verify(code, expected); - } + */$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskDoubleSpace() - { - var code = """ + [WpfFact] + public void ClosedAfterAsteriskSpaceWithTabsBeforeAsterisk() + { + var code = """ /* * - * $$ - """; - var expected = """ + * $$ + """; + var expected = """ /* * - * /$$ - """; - Verify(code, expected); - } + */$$ + """; + VerifyTabs(code, expected); + } - [WpfFact] - public void ClosedAfterAsteriskSpaceWithNothingBeforeAsterisk() - { - var code = """ - /* - * - * $$ - """; - var expected = """ - /* - * - */$$ - """; - Verify(code, expected); - } - - [WpfFact] - public void ClosedAfterAsteriskSpaceWithTabsBeforeAsterisk() - { - var code = """ - /* - * - * $$ - """; - var expected = """ - /* - * - */$$ - """; - VerifyTabs(code, expected); - } - - [WpfFact] - public void NotClosedAfterAsteriskSpaceWithOptionOff() + [WpfFact] + public void NotClosedAfterAsteriskSpaceWithOptionOff() + { + var code = """ + /* + * + * $$ + """; + var expected = """ + /* + * + * /$$ + """; + Verify(code, expected, workspace => { - var code = """ + var globalOptions = workspace.GetService(); + globalOptions.SetGlobalOption(BlockCommentEditingOptionsStorage.AutoInsertBlockCommentStartString, LanguageNames.CSharp, false); + }); + } + + [WpfFact] + public void NotClosedAfterAsteriskSpaceOutsideComment() + { + var code = """ + / * + * + * $$ + """; + var expected = """ + / * + * + * /$$ + """; + Verify(code, expected); + } + + [WpfFact] + public void NotClosedAfterAsteriskSpaceInsideString() + { + var code = """ + class C + { + string s = @" /* * * $$ - """; - var expected = """ + """; + var expected = """ + class C + { + string s = @" /* * * /$$ - """; - Verify(code, expected, workspace => - { - var globalOptions = workspace.GetService(); - globalOptions.SetGlobalOption(BlockCommentEditingOptionsStorage.AutoInsertBlockCommentStartString, LanguageNames.CSharp, false); - }); - } + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceOutsideComment() - { - var code = """ - / * - * - * $$ - """; - var expected = """ - / * - * - * /$$ - """; - Verify(code, expected); - } - - [WpfFact] - public void NotClosedAfterAsteriskSpaceInsideString() - { - var code = """ - class C - { - string s = @" - /* - * - * $$ - """; - var expected = """ - class C - { - string s = @" - /* - * - * /$$ - """; - Verify(code, expected); - } - - [WpfFact] - public void ClosedAfterAsteriskSpaceEndOfFile() - { - var code = """ - /* - * $$ - """; - var expected = """ - /* - */$$ - """; - Verify(code, expected); - } + [WpfFact] + public void ClosedAfterAsteriskSpaceEndOfFile() + { + var code = """ + /* + * $$ + """; + var expected = """ + /* + */$$ + """; + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterAsteriskSpaceStartOfFile() - { - var code = @"* $$"; - var expected = @"* /$$"; + [WpfFact] + public void NotClosedAfterAsteriskSpaceStartOfFile() + { + var code = @"* $$"; + var expected = @"* /$$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void NotClosedAfterSpaceStartOfFile() - { - var code = @" $$"; - var expected = @" /$$"; + [WpfFact] + public void NotClosedAfterSpaceStartOfFile() + { + var code = @" $$"; + var expected = @" /$$"; - Verify(code, expected); - } + Verify(code, expected); + } - [WpfFact] - public void NotClosedAtStartOfFile() - { - var code = @"$$"; - var expected = @"/$$"; + [WpfFact] + public void NotClosedAtStartOfFile() + { + var code = @"$$"; + var expected = @"/$$"; - Verify(code, expected); - } + Verify(code, expected); + } - protected override EditorTestWorkspace CreateTestWorkspace(string initialMarkup) - => EditorTestWorkspace.CreateCSharp(initialMarkup); + protected override EditorTestWorkspace CreateTestWorkspace(string initialMarkup) + => EditorTestWorkspace.CreateCSharp(initialMarkup); - protected override (TypeCharCommandArgs, string insertionText) CreateCommandArgs(ITextView textView, ITextBuffer textBuffer) - => (new TypeCharCommandArgs(textView, textBuffer, '/'), "/"); + protected override (TypeCharCommandArgs, string insertionText) CreateCommandArgs(ITextView textView, ITextBuffer textBuffer) + => (new TypeCharCommandArgs(textView, textBuffer, '/'), "/"); - internal override ICommandHandler GetCommandHandler(EditorTestWorkspace workspace) - => Assert.IsType(workspace.GetService(ContentTypeNames.CSharpContentType, nameof(CloseBlockCommentCommandHandler))); - } + internal override ICommandHandler GetCommandHandler(EditorTestWorkspace workspace) + => Assert.IsType(workspace.GetService(ContentTypeNames.CSharpContentType, nameof(CloseBlockCommentCommandHandler))); } diff --git a/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs b/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs index 12e8a7b6c5f5c..b5e54ee39cb78 100644 --- a/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs +++ b/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs @@ -7,664 +7,662 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.BraceHighlighting; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BraceHighlighting +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BraceHighlighting; + +[Trait(Traits.Feature, Traits.Features.BraceHighlighting)] +public class BraceHighlightingTests : AbstractBraceHighlightingTests { - [Trait(Traits.Feature, Traits.Features.BraceHighlighting)] - public class BraceHighlightingTests : AbstractBraceHighlightingTests - { - protected override EditorTestWorkspace CreateWorkspace(string markup, ParseOptions options) - => EditorTestWorkspace.CreateCSharp(markup, parseOptions: options); - - [WpfTheory] - [InlineData(""" - public class C$$ { - } - """)] - [InlineData(""" - public class C $$[|{|] - [|}|] - """)] - [InlineData(""" - public class C {$$ - } - """)] - [InlineData(""" - public class C { - $$} - """)] - [InlineData(""" - public class C [|{|] - [|}|]$$ - """)] - public async Task TestCurlies(string testCase) - { - await TestBraceHighlightingAsync(testCase); - } + protected override EditorTestWorkspace CreateWorkspace(string markup, ParseOptions options) + => EditorTestWorkspace.CreateCSharp(markup, parseOptions: options); - [WpfTheory] - [InlineData(""" - public class C $$[|{|] - public void Goo(){} - [|}|] - """)] - [InlineData(""" - public class C {$$ - public void Goo(){} - } - """)] - [InlineData(""" - public class C { - public void Goo$$[|(|][|)|]{} - } - """)] - [InlineData(""" - public class C { - public void Goo($$){} - } - """)] - [InlineData(""" - public class C { - public void Goo[|(|][|)|]$$[|{|][|}|] - } - """)] - [InlineData(""" - public class C { - public void Goo(){$$} - } - """)] - [InlineData(""" - public class C { - public void Goo()[|{|][|}|]$$ - } - """)] - public async Task TestTouchingItems(string testCase) - { - await TestBraceHighlightingAsync(testCase); + [WpfTheory] + [InlineData(""" + public class C$$ { + } + """)] + [InlineData(""" + public class C $$[|{|] + [|}|] + """)] + [InlineData(""" + public class C {$$ } + """)] + [InlineData(""" + public class C { + $$} + """)] + [InlineData(""" + public class C [|{|] + [|}|]$$ + """)] + public async Task TestCurlies(string testCase) + { + await TestBraceHighlightingAsync(testCase); + } - [WpfTheory] - [InlineData("/// $$Goo")] - [InlineData("/// <$$summary>Goo")] - [InlineData("/// Goo")] - [InlineData("/// $$Goo")] - [InlineData("/// Goo$$")] - [InlineData("/// Goo<$$/summary>")] - [InlineData("/// Goo")] - [InlineData("/// Goo")] - [InlineData("/// Goo$$")] - - [InlineData("public class C$$[|<|]T[|>|] { }")] - [InlineData("public class C<$$T> { }")] - [InlineData("public class C { }")] - [InlineData("public class C[|<|]T[|>$$|] { }")] - - [InlineData("unsafe class C { delegate*$$[|<|] int, int[|>|] functionPointer; }")] - [InlineData("unsafe class C { delegate*[|<|]int, int[|>$$|] functionPointer; }")] - [InlineData("unsafe class C { delegate*|]$$> functionPointer; }")] - public async Task TestAngles(string testCase) - { - await TestBraceHighlightingAsync(testCase); + [WpfTheory] + [InlineData(""" + public class C $$[|{|] + public void Goo(){} + [|}|] + """)] + [InlineData(""" + public class C {$$ + public void Goo(){} + } + """)] + [InlineData(""" + public class C { + public void Goo$$[|(|][|)|]{} + } + """)] + [InlineData(""" + public class C { + public void Goo($$){} + } + """)] + [InlineData(""" + public class C { + public void Goo[|(|][|)|]$$[|{|][|}|] + } + """)] + [InlineData(""" + public class C { + public void Goo(){$$} + } + """)] + [InlineData(""" + public class C { + public void Goo()[|{|][|}|]$$ } + """)] + public async Task TestTouchingItems(string testCase) + { + await TestBraceHighlightingAsync(testCase); + } + + [WpfTheory] + [InlineData("/// $$Goo")] + [InlineData("/// <$$summary>Goo")] + [InlineData("/// Goo")] + [InlineData("/// $$Goo")] + [InlineData("/// Goo$$")] + [InlineData("/// Goo<$$/summary>")] + [InlineData("/// Goo")] + [InlineData("/// Goo")] + [InlineData("/// Goo$$")] + + [InlineData("public class C$$[|<|]T[|>|] { }")] + [InlineData("public class C<$$T> { }")] + [InlineData("public class C { }")] + [InlineData("public class C[|<|]T[|>$$|] { }")] + + [InlineData("unsafe class C { delegate*$$[|<|] int, int[|>|] functionPointer; }")] + [InlineData("unsafe class C { delegate*[|<|]int, int[|>$$|] functionPointer; }")] + [InlineData("unsafe class C { delegate*|]$$> functionPointer; }")] + public async Task TestAngles(string testCase) + { + await TestBraceHighlightingAsync(testCase); + } - [WpfFact] - public async Task TestNoHighlightingOnOperators() - { - await TestBraceHighlightingAsync( - """ - class C + [WpfFact] + public async Task TestNoHighlightingOnOperators() + { + await TestBraceHighlightingAsync( + """ + class C + { + void Goo() { - void Goo() - { - bool a = b $$< c; - bool d = e > f; - } + bool a = b $$< c; + bool d = e > f; } - """); - await TestBraceHighlightingAsync( - """ - class C + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void Goo() { - void Goo() - { - bool a = b <$$ c; - bool d = e > f; - } + bool a = b <$$ c; + bool d = e > f; } - """); - await TestBraceHighlightingAsync( - """ - class C + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void Goo() { - void Goo() - { - bool a = b < c; - bool d = e $$> f; - } + bool a = b < c; + bool d = e $$> f; } - """); - await TestBraceHighlightingAsync( - """ - class C + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void Goo() { - void Goo() - { - bool a = b < c; - bool d = e >$$ f; - } + bool a = b < c; + bool d = e >$$ f; } - """); - } + } + """); + } - [WpfFact] - public async Task TestSwitch() - { - await TestBraceHighlightingAsync( - """ - class C + [WpfFact] + public async Task TestSwitch() + { + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) { - void M(int variable) + switch $$[|(|]variable[|)|] { - switch $$[|(|]variable[|)|] - { - case 0: - break; - } + case 0: + break; } } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch ($$variable) { - switch ($$variable) - { - case 0: - break; - } + case 0: + break; } } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch (variable$$) { - switch (variable$$) - { - case 0: - break; - } + case 0: + break; } } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch [|(|]variable[|)$$|] { - switch [|(|]variable[|)$$|] - { - case 0: - break; - } + case 0: + break; } } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) - { - switch (variable) - $$[|{|] - case 0: - break; - [|}|] - } + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch (variable) + $$[|{|] + case 0: + break; + [|}|] } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) - { - switch (variable) - {$$ - case 0: - break; - } + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch (variable) + {$$ + case 0: + break; } } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch (variable) { - switch (variable) - { - case 0: - break; - $$} - } + case 0: + break; + $$} } - """); - await TestBraceHighlightingAsync( - """ - class C - { - void M(int variable) - { - switch (variable) - [|{|] - case 0: - break; - [|}$$|] - } + } + """); + await TestBraceHighlightingAsync( + """ + class C + { + void M(int variable) + { + switch (variable) + [|{|] + case 0: + break; + [|}$$|] } - """); - } + } + """); + } - [WpfFact] - public async Task TestEOF() - { - await TestBraceHighlightingAsync(""" - public class C [|{|] - [|}|]$$ - """); - await TestBraceHighlightingAsync(""" - public class C [|{|] - void Goo(){}[|}|]$$ - """); - } + [WpfFact] + public async Task TestEOF() + { + await TestBraceHighlightingAsync(""" + public class C [|{|] + [|}|]$$ + """); + await TestBraceHighlightingAsync(""" + public class C [|{|] + void Goo(){}[|}|]$$ + """); + } - [WpfFact] - public async Task TestTuples() - { - await TestBraceHighlightingAsync( - """ - class C - { - [|(|]int, int[|)$$|] x = (1, 2); - } - """, TestOptions.Regular); - await TestBraceHighlightingAsync( - """ - class C - { - (int, int) x = [|(|]1, 2[|)$$|]; - } - """, TestOptions.Regular); - } + [WpfFact] + public async Task TestTuples() + { + await TestBraceHighlightingAsync( + """ + class C + { + [|(|]int, int[|)$$|] x = (1, 2); + } + """, TestOptions.Regular); + await TestBraceHighlightingAsync( + """ + class C + { + (int, int) x = [|(|]1, 2[|)$$|]; + } + """, TestOptions.Regular); + } - [WpfFact] - public async Task TestNestedTuples() - { - await TestBraceHighlightingAsync( - """ - class C - { - ([|(|]int, int[|)$$|], string) x = ((1, 2), "hello"; - } - """, TestOptions.Regular); - await TestBraceHighlightingAsync( - """ - class C - { - ((int, int), string) x = ([|(|]1, 2[|)$$|], "hello"; - } - """, TestOptions.Regular); - } + [WpfFact] + public async Task TestNestedTuples() + { + await TestBraceHighlightingAsync( + """ + class C + { + ([|(|]int, int[|)$$|], string) x = ((1, 2), "hello"; + } + """, TestOptions.Regular); + await TestBraceHighlightingAsync( + """ + class C + { + ((int, int), string) x = ([|(|]1, 2[|)$$|], "hello"; + } + """, TestOptions.Regular); + } - [WpfFact] - public async Task TestTuplesWithGenerics() - { - await TestBraceHighlightingAsync( - """ - class C - { - [|(|]Dictionary, List[|)$$|] x = (null, null); - } - """, TestOptions.Regular); - await TestBraceHighlightingAsync( - """ - class C - { - var x = [|(|]new Dictionary(), new List()[|)$$|]; - } - """, TestOptions.Regular); - } + [WpfFact] + public async Task TestTuplesWithGenerics() + { + await TestBraceHighlightingAsync( + """ + class C + { + [|(|]Dictionary, List[|)$$|] x = (null, null); + } + """, TestOptions.Regular); + await TestBraceHighlightingAsync( + """ + class C + { + var x = [|(|]new Dictionary(), new List()[|)$$|]; + } + """, TestOptions.Regular); + } - [WpfFact] - public async Task TestRegexGroupBracket1() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexGroupBracket1() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"$$[|(|]a[|)|]"); - } + var r = new Regex(@"$$[|(|]a[|)|]"); } - """; + } + """; - await TestBraceHighlightingAsync(input); - } + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestRegexGroupBracket2() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexGroupBracket2() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"[|(|]a[|)|]$$"); - } + var r = new Regex(@"[|(|]a[|)|]$$"); } - """; + } + """; - await TestBraceHighlightingAsync(input); - } + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestRegexUnclosedGroupBracket1() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexUnclosedGroupBracket1() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"$$(a"); - } + var r = new Regex(@"$$(a"); } - """; + } + """; - await TestBraceHighlightingAsync(input); - } + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestRegexCommentBracket1() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexCommentBracket1() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"$$[|(|]?#a[|)|]"); - } + var r = new Regex(@"$$[|(|]?#a[|)|]"); } - """; + } + """; - await TestBraceHighlightingAsync(input); - } + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestRegexCommentBracket2() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexCommentBracket2() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"[|(|]?#a[|)|]$$"); - } + var r = new Regex(@"[|(|]?#a[|)|]$$"); } - """; + } + """; - await TestBraceHighlightingAsync(input); - } + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestRegexUnclosedCommentBracket() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexUnclosedCommentBracket() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"$$(?#a"); - } + var r = new Regex(@"$$(?#a"); } - """; + } + """; - await TestBraceHighlightingAsync(input); - } + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestRegexCharacterClassBracket1() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexCharacterClassBracket1() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"$$[|<|]a[|>|]"); - } + var r = new Regex(@"$$[|<|]a[|>|]"); } - """; + } + """; - await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); - } + await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); + } - [WpfFact] - public async Task TestRegexCharacterClassBracket2() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexCharacterClassBracket2() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"[|<|]a[|>|]$$"); - } + var r = new Regex(@"[|<|]a[|>|]$$"); } - """; - await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); - } + } + """; + await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); + } - [WpfFact] - public async Task TestRegexUnclosedCharacterClassBracket1() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexUnclosedCharacterClassBracket1() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"$$|]"); - } + var r = new Regex(@"$$[|<|]^a[|>|]"); } - """; + } + """; - await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); - } + await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); + } - [WpfFact] - public async Task TestRegexNegativeCharacterClassBracket2() - { - var input = """ - using System.Text.RegularExpressions; + [WpfFact] + public async Task TestRegexNegativeCharacterClassBracket2() + { + var input = """ + using System.Text.RegularExpressions; - class C + class C + { + void Goo() { - void Goo() - { - var r = new Regex(@"[|<|]^a[|>|]$$"); - } + var r = new Regex(@"[|<|]^a[|>|]$$"); } - """; + } + """; - await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); - } + await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true); + } - [WpfFact] - public async Task TestJsonBracket1() - { - var input = """ - class C + [WpfFact] + public async Task TestJsonBracket1() + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = /*lang=json*/ @"new Json[|$$(|]1, 2, 3[|)|]"; - } + var r = /*lang=json*/ @"new Json[|$$(|]1, 2, 3[|)|]"; } - """; - await TestBraceHighlightingAsync(input); - } + } + """; + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestJsonBracket2() - { - var input = """ - class C + [WpfFact] + public async Task TestJsonBracket2() + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = /*lang=json*/ @"new Json[|(|]1, 2, 3[|)|]$$"; - } + var r = /*lang=json*/ @"new Json[|(|]1, 2, 3[|)|]$$"; } - """; - await TestBraceHighlightingAsync(input); - } + } + """; + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestJsonBracket_RawStrings() - { - var input = """" - class C + [WpfFact] + public async Task TestJsonBracket_RawStrings() + { + var input = """" + class C + { + void Goo() { - void Goo() - { - var r = /*lang=json*/ """new Json[|$$(|]1, 2, 3[|)|]"""; - } + var r = /*lang=json*/ """new Json[|$$(|]1, 2, 3[|)|]"""; } - """"; - await TestBraceHighlightingAsync(input); - } + } + """"; + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestUnmatchedJsonBracket1() - { - var input = """ - class C + [WpfFact] + public async Task TestUnmatchedJsonBracket1() + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = /*lang=json*/ @"new Json$$(1, 2, 3"; - } + var r = /*lang=json*/ @"new Json$$(1, 2, 3"; } - """; - await TestBraceHighlightingAsync(input); - } + } + """; + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestJsonBracket_NoComment_NotLikelyJson() - { - var input = """ - class C + [WpfFact] + public async Task TestJsonBracket_NoComment_NotLikelyJson() + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = @"$$[ 1, 2, 3 ]"; - } + var r = @"$$[ 1, 2, 3 ]"; } - """; - await TestBraceHighlightingAsync(input); - } + } + """; + await TestBraceHighlightingAsync(input); + } - [WpfFact] - public async Task TestJsonBracket_NoComment_LikelyJson() - { - var input = """ - class C + [WpfFact] + public async Task TestJsonBracket_NoComment_LikelyJson() + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = @"[ { prop: 0 }, new Json[|$$(|]1, 2, 3[|)|], 3 ]"; - } + var r = @"[ { prop: 0 }, new Json[|$$(|]1, 2, 3[|)|], 3 ]"; } - """; - await TestBraceHighlightingAsync(input); - } + } + """; + await TestBraceHighlightingAsync(input); + } - [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/32791")] - [InlineData(@"$$ /* goo */ public class C { }")] - [InlineData(@" $$[|/*|] goo [|*/|] public class C { }")] - [InlineData(@" [|/$$*|] goo [|*/|] public class C { }")] - [InlineData(@" /*$$ goo */ public class C { }")] - [InlineData(@" /* $$goo */ public class C { }")] - [InlineData(@" /* goo$$ */ public class C { }")] - [InlineData(@" /* goo $$*/ public class C { }")] - [InlineData(@" [|/*|] goo [|*$$/|] public class C { }")] - [InlineData(@" [|/*|] goo [|*/|]$$ public class C { }")] - [InlineData(@" /* goo */ $$public class C { }")] - public async Task TestBlockComments(string input) - { - await TestBraceHighlightingAsync(input); - } + [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/32791")] + [InlineData(@"$$ /* goo */ public class C { }")] + [InlineData(@" $$[|/*|] goo [|*/|] public class C { }")] + [InlineData(@" [|/$$*|] goo [|*/|] public class C { }")] + [InlineData(@" /*$$ goo */ public class C { }")] + [InlineData(@" /* $$goo */ public class C { }")] + [InlineData(@" /* goo$$ */ public class C { }")] + [InlineData(@" /* goo $$*/ public class C { }")] + [InlineData(@" [|/*|] goo [|*$$/|] public class C { }")] + [InlineData(@" [|/*|] goo [|*/|]$$ public class C { }")] + [InlineData(@" /* goo */ $$public class C { }")] + public async Task TestBlockComments(string input) + { + await TestBraceHighlightingAsync(input); + } - [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/32791")] - [InlineData(@"$$ /** goo */ public class C { }")] - [InlineData(@" $$[|/**|] goo [|*/|] public class C { }")] - [InlineData(@" [|/$$**|] goo [|*/|] public class C { }")] - [InlineData(@" [|/*$$*|] goo [|*/|] public class C { }")] - [InlineData(@" /**$$ goo */ public class C { }")] - [InlineData(@" /** $$goo */ public class C { }")] - [InlineData(@" /** goo$$ */ public class C { }")] - [InlineData(@" /** goo $$*/ public class C { }")] - [InlineData(@" [|/**|] goo [|*$$/|] public class C { }")] - [InlineData(@" [|/**|] goo [|*/|]$$ public class C { }")] - [InlineData(@" /** goo */ $$public class C { }")] - public async Task TestDocCommentBlockComments(string input) - { - await TestBraceHighlightingAsync(input); - } + [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/32791")] + [InlineData(@"$$ /** goo */ public class C { }")] + [InlineData(@" $$[|/**|] goo [|*/|] public class C { }")] + [InlineData(@" [|/$$**|] goo [|*/|] public class C { }")] + [InlineData(@" [|/*$$*|] goo [|*/|] public class C { }")] + [InlineData(@" /**$$ goo */ public class C { }")] + [InlineData(@" /** $$goo */ public class C { }")] + [InlineData(@" /** goo$$ */ public class C { }")] + [InlineData(@" /** goo $$*/ public class C { }")] + [InlineData(@" [|/**|] goo [|*$$/|] public class C { }")] + [InlineData(@" [|/**|] goo [|*/|]$$ public class C { }")] + [InlineData(@" /** goo */ $$public class C { }")] + public async Task TestDocCommentBlockComments(string input) + { + await TestBraceHighlightingAsync(input); } } diff --git a/src/EditorFeatures/CSharpTest/BraceMatching/CSharpBraceMatcherTests.cs b/src/EditorFeatures/CSharpTest/BraceMatching/CSharpBraceMatcherTests.cs index 7822776f4e951..cea6f7fd34832 100644 --- a/src/EditorFeatures/CSharpTest/BraceMatching/CSharpBraceMatcherTests.cs +++ b/src/EditorFeatures/CSharpTest/BraceMatching/CSharpBraceMatcherTests.cs @@ -5,957 +5,955 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.BraceMatching; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BraceMatching +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BraceMatching; + +[Trait(Traits.Feature, Traits.Features.BraceMatching)] +public class CSharpBraceMatcherTests : AbstractBraceMatcherTests { - [Trait(Traits.Feature, Traits.Features.BraceMatching)] - public class CSharpBraceMatcherTests : AbstractBraceMatcherTests - { - protected override EditorTestWorkspace CreateWorkspaceFromCode(string code, ParseOptions options) - => EditorTestWorkspace.CreateCSharp(code, options); - - [Fact] - public async Task TestEmptyFile() - { - var code = @"$$"; - var expected = @""; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestAtFirstPositionInFile() - { - var code = @"$$public class C { }"; - var expected = @"public class C { }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestAtLastPositionInFile() - { - var code = @"public class C { }$$"; - var expected = @"public class C [|{|] }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestCurlyBrace1() - { - var code = @"public class C $${ }"; - var expected = @"public class C { [|}|]"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestCurlyBrace2() - { - var code = @"public class C {$$ }"; - var expected = @"public class C { [|}|]"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestCurlyBrace3() - { - var code = @"public class C { $$}"; - var expected = @"public class C [|{|] }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestCurlyBrace4() - { - var code = @"public class C { }$$"; - var expected = @"public class C [|{|] }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestParen1() - { - var code = @"public class C { void Goo$$() { } }"; - var expected = @"public class C { void Goo([|)|] { } }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestParen2() - { - var code = @"public class C { void Goo($$) { } }"; - var expected = @"public class C { void Goo([|)|] { } }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestParen3() - { - var code = @"public class C { void Goo($$ ) { } }"; - var expected = @"public class C { void Goo( [|)|] { } }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestParen4() - { - var code = @"public class C { void Goo( $$) { } }"; - var expected = @"public class C { void Goo[|(|] ) { } }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestParen5() - { - var code = @"public class C { void Goo( )$$ { } }"; - var expected = @"public class C { void Goo[|(|] ) { } }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestParen6() - { - var code = @"public class C { void Goo()$$ { } }"; - var expected = @"public class C { void Goo[|(|]) { } }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestSquareBracket1() - { - var code = @"public class C { int$$[] i; }"; - var expected = @"public class C { int[[|]|] i; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestSquareBracket2() - { - var code = @"public class C { int[$$] i; }"; - var expected = @"public class C { int[[|]|] i; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestSquareBracket3() - { - var code = @"public class C { int[$$ ] i; }"; - var expected = @"public class C { int[ [|]|] i; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestSquareBracket4() - { - var code = @"public class C { int[ $$] i; }"; - var expected = @"public class C { int[|[|] ] i; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestSquareBracket5() - { - var code = @"public class C { int[ ]$$ i; }"; - var expected = @"public class C { int[|[|] ] i; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestSquareBracket6() - { - var code = @"public class C { int[]$$ i; }"; - var expected = @"public class C { int[|[|]] i; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestAngleBracket1() - { - var code = @"public class C { Goo$$ f; }"; - var expected = @"public class C { Goo|] f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestAngleBracket2() - { - var code = @"public class C { Goo<$$int> f; }"; - var expected = @"public class C { Goo|] f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestAngleBracket3() - { - var code = @"public class C { Goo f; }"; - var expected = @"public class C { Goo[|<|]int> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestAngleBracket4() - { - var code = @"public class C { Goo$$ f; }"; - var expected = @"public class C { Goo[|<|]int> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket1() - { - var code = @"public class C { Func$$> f; }"; - var expected = @"public class C { Func[|>|] f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket2() - { - var code = @"public class C { Func<$$Func> f; }"; - var expected = @"public class C { Func[|>|] f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket3() - { - var code = @"public class C { Func> f; }"; - var expected = @"public class C { Func|]> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket4() - { - var code = @"public class C { Func> f; }"; - var expected = @"public class C { Func|]> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket5() - { - var code = @"public class C { Func> f; }"; - var expected = @"public class C { Func> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket6() - { - var code = @"public class C { Func$$> f; }"; - var expected = @"public class C { Func> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket7() - { - var code = @"public class C { Func $$> f; }"; - var expected = @"public class C { Func[|<|]Func > f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestNestedAngleBracket8() - { - var code = @"public class C { Func>$$ f; }"; - var expected = @"public class C { Func[|<|]Func> f; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestString1() - { - var code = @"public class C { string s = $$""Goo""; }"; - var expected = @"public class C { string s = ""Goo[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestString2() - { - var code = @"public class C { string s = ""$$Goo""; }"; - var expected = @"public class C { string s = ""Goo[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestString3() - { - var code = @"public class C { string s = ""Goo$$""; }"; - var expected = @"public class C { string s = [|""|]Goo""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestString4() - { - var code = @"public class C { string s = ""Goo""$$; }"; - var expected = @"public class C { string s = [|""|]Goo""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestString5() - { - var code = @"public class C { string s = ""Goo$$ "; - var expected = @"public class C { string s = ""Goo "; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimString1() - { - var code = @"public class C { string s = $$@""Goo""; }"; - var expected = @"public class C { string s = @""Goo[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimString2() - { - var code = @"public class C { string s = @$$""Goo""; }"; - var expected = @"public class C { string s = @""Goo[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimString3() - { - var code = @"public class C { string s = @""$$Goo""; }"; - var expected = @"public class C { string s = @""Goo[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimString4() - { - var code = @"public class C { string s = @""Goo$$""; }"; - var expected = @"public class C { string s = [|@""|]Goo""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimString5() - { - var code = @"public class C { string s = @""Goo""$$; }"; - var expected = @"public class C { string s = [|@""|]Goo""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString1() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""$${x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x[|}|], {y}""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString2() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{$$x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x[|}|], {y}""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString3() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x$$}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""[|{|]x}, {y}""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString4() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}$$, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""[|{|]x}, {y}""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString5() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, $${y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y[|}|]""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString6() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {$$y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y[|}|]""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString7() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y$$}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, [|{|]y}""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString8() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y}$$""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, [|{|]y}""; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString9() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $$[||]$""{x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y}[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString10() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $[||]$$""{x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y}[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString11() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $$[||]$@""{x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@""{x}, {y}[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString12() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $[||]$$@""{x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@""{x}, {y}[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestInterpolatedString13() - { - var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@$$""{x}, {y}""; }"; - var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@""{x}, {y}[|""|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestUtf8String1() - { - var code = @"public class C { string s = $$""Goo""u8; }"; - var expected = @"public class C { string s = ""Goo[|""u8|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestUtf8String2() - { - var code = @"public class C { string s = ""$$Goo""u8; }"; - var expected = @"public class C { string s = ""Goo[|""u8|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestUtf8String3() - { - var code = @"public class C { string s = ""Goo$$""u8; }"; - var expected = @"public class C { string s = [|""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestUtf8String4() - { - var code = @"public class C { string s = ""Goo""$$u8; }"; - var expected = @"public class C { string s = [|""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestUtf8String5() - { - var code = @"public class C { string s = ""Goo""u$$8; }"; - var expected = @"public class C { string s = [|""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestUtf8String6() - { - var code = @"public class C { string s = ""Goo""u8$$; }"; - var expected = @"public class C { string s = [|""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String1() - { - var code = @"public class C { string s = $$@""Goo""u8; }"; - var expected = @"public class C { string s = @""Goo[|""u8|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String2() - { - var code = @"public class C { string s = @$$""Goo""u8; }"; - var expected = @"public class C { string s = @""Goo[|""u8|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String3() - { - var code = @"public class C { string s = @""$$Goo""u8; }"; - var expected = @"public class C { string s = @""Goo[|""u8|]; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String4() - { - var code = @"public class C { string s = @""Goo$$""u8; }"; - var expected = @"public class C { string s = [|@""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String5() - { - var code = @"public class C { string s = @""Goo""$$u8; }"; - var expected = @"public class C { string s = [|@""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String6() - { - var code = @"public class C { string s = @""Goo""u$$8; }"; - var expected = @"public class C { string s = [|@""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [Fact] - public async Task TestVerbatimUtf8String7() - { - var code = @"public class C { string s = @""Goo""u8$$; }"; - var expected = @"public class C { string s = [|@""|]Goo""u8; }"; - - await TestAsync(code, expected); - } - - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestConditionalDirectiveWithSingleMatchingDirective() - { - var code = """ - public class C - { - #if$$ CHK - #endif - } - """; - var expected = """ - public class C - { - #if$$ CHK - [|#endif|] - } - """; + protected override EditorTestWorkspace CreateWorkspaceFromCode(string code, ParseOptions options) + => EditorTestWorkspace.CreateCSharp(code, options); - await TestAsync(code, expected); - } + [Fact] + public async Task TestEmptyFile() + { + var code = @"$$"; + var expected = @""; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestConditionalDirectiveWithTwoMatchingDirectives() - { - var code = """ - public class C - { - #if$$ CHK - #else - #endif - } - """; - var expected = """ - public class C - { - #if$$ CHK - [|#else|] - #endif - } - """; + await TestAsync(code, expected); + } - await TestAsync(code, expected); - } + [Fact] + public async Task TestAtFirstPositionInFile() + { + var code = @"$$public class C { }"; + var expected = @"public class C { }"; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestConditionalDirectiveWithAllMatchingDirectives() - { - var code = """ - public class C - { - #if CHK - #elif RET - #else - #endif$$ - } - """; - var expected = """ - public class C - { - [|#if|] CHK - #elif RET - #else - #endif - } - """; + await TestAsync(code, expected); + } - await TestAsync(code, expected); - } + [Fact] + public async Task TestAtLastPositionInFile() + { + var code = @"public class C { }$$"; + var expected = @"public class C [|{|] }"; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestRegionDirective() - { - var code = """ - public class C - { - $$#region test - #endregion - } - """; - var expected = """ - public class C - { - #region test - [|#endregion|] - } - """; + await TestAsync(code, expected); + } - await TestAsync(code, expected); - } + [Fact] + public async Task TestCurlyBrace1() + { + var code = @"public class C $${ }"; + var expected = @"public class C { [|}|]"; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestInterleavedDirectivesInner() - { - var code = """ - #define CHK - public class C - { - void Test() - { - #if CHK - $$#region test - var x = 5; - #endregion - #else - var y = 6; - #endif - } - } - """; - var expected = """ - #define CHK - public class C - { - void Test() - { - #if CHK - #region test - var x = 5; - [|#endregion|] - #else - var y = 6; - #endif - } - } - """; + await TestAsync(code, expected); + } - await TestAsync(code, expected); - } + [Fact] + public async Task TestCurlyBrace2() + { + var code = @"public class C {$$ }"; + var expected = @"public class C { [|}|]"; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestInterleavedDirectivesOuter() - { - var code = """ - #define CHK - public class C - { - void Test() - { - #if$$ CHK - #region test - var x = 5; - #endregion - #else - var y = 6; - #endif - } - } - """; - var expected = """ - #define CHK - public class C - { - void Test() - { - #if CHK - #region test - var x = 5; - #endregion - [|#else|] - var y = 6; - #endif - } - } - """; + await TestAsync(code, expected); + } + + [Fact] + public async Task TestCurlyBrace3() + { + var code = @"public class C { $$}"; + var expected = @"public class C [|{|] }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestCurlyBrace4() + { + var code = @"public class C { }$$"; + var expected = @"public class C [|{|] }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestParen1() + { + var code = @"public class C { void Goo$$() { } }"; + var expected = @"public class C { void Goo([|)|] { } }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestParen2() + { + var code = @"public class C { void Goo($$) { } }"; + var expected = @"public class C { void Goo([|)|] { } }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestParen3() + { + var code = @"public class C { void Goo($$ ) { } }"; + var expected = @"public class C { void Goo( [|)|] { } }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestParen4() + { + var code = @"public class C { void Goo( $$) { } }"; + var expected = @"public class C { void Goo[|(|] ) { } }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestParen5() + { + var code = @"public class C { void Goo( )$$ { } }"; + var expected = @"public class C { void Goo[|(|] ) { } }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestParen6() + { + var code = @"public class C { void Goo()$$ { } }"; + var expected = @"public class C { void Goo[|(|]) { } }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestSquareBracket1() + { + var code = @"public class C { int$$[] i; }"; + var expected = @"public class C { int[[|]|] i; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestSquareBracket2() + { + var code = @"public class C { int[$$] i; }"; + var expected = @"public class C { int[[|]|] i; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestSquareBracket3() + { + var code = @"public class C { int[$$ ] i; }"; + var expected = @"public class C { int[ [|]|] i; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestSquareBracket4() + { + var code = @"public class C { int[ $$] i; }"; + var expected = @"public class C { int[|[|] ] i; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestSquareBracket5() + { + var code = @"public class C { int[ ]$$ i; }"; + var expected = @"public class C { int[|[|] ] i; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestSquareBracket6() + { + var code = @"public class C { int[]$$ i; }"; + var expected = @"public class C { int[|[|]] i; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestAngleBracket1() + { + var code = @"public class C { Goo$$ f; }"; + var expected = @"public class C { Goo|] f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestAngleBracket2() + { + var code = @"public class C { Goo<$$int> f; }"; + var expected = @"public class C { Goo|] f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestAngleBracket3() + { + var code = @"public class C { Goo f; }"; + var expected = @"public class C { Goo[|<|]int> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestAngleBracket4() + { + var code = @"public class C { Goo$$ f; }"; + var expected = @"public class C { Goo[|<|]int> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket1() + { + var code = @"public class C { Func$$> f; }"; + var expected = @"public class C { Func[|>|] f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket2() + { + var code = @"public class C { Func<$$Func> f; }"; + var expected = @"public class C { Func[|>|] f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket3() + { + var code = @"public class C { Func> f; }"; + var expected = @"public class C { Func|]> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket4() + { + var code = @"public class C { Func> f; }"; + var expected = @"public class C { Func|]> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket5() + { + var code = @"public class C { Func> f; }"; + var expected = @"public class C { Func> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket6() + { + var code = @"public class C { Func$$> f; }"; + var expected = @"public class C { Func> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket7() + { + var code = @"public class C { Func $$> f; }"; + var expected = @"public class C { Func[|<|]Func > f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestNestedAngleBracket8() + { + var code = @"public class C { Func>$$ f; }"; + var expected = @"public class C { Func[|<|]Func> f; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestString1() + { + var code = @"public class C { string s = $$""Goo""; }"; + var expected = @"public class C { string s = ""Goo[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestString2() + { + var code = @"public class C { string s = ""$$Goo""; }"; + var expected = @"public class C { string s = ""Goo[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestString3() + { + var code = @"public class C { string s = ""Goo$$""; }"; + var expected = @"public class C { string s = [|""|]Goo""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestString4() + { + var code = @"public class C { string s = ""Goo""$$; }"; + var expected = @"public class C { string s = [|""|]Goo""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestString5() + { + var code = @"public class C { string s = ""Goo$$ "; + var expected = @"public class C { string s = ""Goo "; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimString1() + { + var code = @"public class C { string s = $$@""Goo""; }"; + var expected = @"public class C { string s = @""Goo[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimString2() + { + var code = @"public class C { string s = @$$""Goo""; }"; + var expected = @"public class C { string s = @""Goo[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimString3() + { + var code = @"public class C { string s = @""$$Goo""; }"; + var expected = @"public class C { string s = @""Goo[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimString4() + { + var code = @"public class C { string s = @""Goo$$""; }"; + var expected = @"public class C { string s = [|@""|]Goo""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimString5() + { + var code = @"public class C { string s = @""Goo""$$; }"; + var expected = @"public class C { string s = [|@""|]Goo""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString1() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""$${x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x[|}|], {y}""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString2() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{$$x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x[|}|], {y}""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString3() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x$$}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""[|{|]x}, {y}""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString4() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}$$, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""[|{|]x}, {y}""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString5() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, $${y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y[|}|]""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString6() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {$$y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y[|}|]""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString7() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y$$}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, [|{|]y}""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString8() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y}$$""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, [|{|]y}""; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString9() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $$[||]$""{x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y}[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString10() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $[||]$$""{x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $""{x}, {y}[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString11() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $$[||]$@""{x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@""{x}, {y}[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString12() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $[||]$$@""{x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@""{x}, {y}[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestInterpolatedString13() + { + var code = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@$$""{x}, {y}""; }"; + var expected = @"public class C { void M() { var x = ""Hello""; var y = ""World""; var s = $@""{x}, {y}[|""|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestUtf8String1() + { + var code = @"public class C { string s = $$""Goo""u8; }"; + var expected = @"public class C { string s = ""Goo[|""u8|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestUtf8String2() + { + var code = @"public class C { string s = ""$$Goo""u8; }"; + var expected = @"public class C { string s = ""Goo[|""u8|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestUtf8String3() + { + var code = @"public class C { string s = ""Goo$$""u8; }"; + var expected = @"public class C { string s = [|""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestUtf8String4() + { + var code = @"public class C { string s = ""Goo""$$u8; }"; + var expected = @"public class C { string s = [|""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestUtf8String5() + { + var code = @"public class C { string s = ""Goo""u$$8; }"; + var expected = @"public class C { string s = [|""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestUtf8String6() + { + var code = @"public class C { string s = ""Goo""u8$$; }"; + var expected = @"public class C { string s = [|""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String1() + { + var code = @"public class C { string s = $$@""Goo""u8; }"; + var expected = @"public class C { string s = @""Goo[|""u8|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String2() + { + var code = @"public class C { string s = @$$""Goo""u8; }"; + var expected = @"public class C { string s = @""Goo[|""u8|]; }"; - await TestAsync(code, expected); - } + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String3() + { + var code = @"public class C { string s = @""$$Goo""u8; }"; + var expected = @"public class C { string s = @""Goo[|""u8|]; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String4() + { + var code = @"public class C { string s = @""Goo$$""u8; }"; + var expected = @"public class C { string s = [|@""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String5() + { + var code = @"public class C { string s = @""Goo""$$u8; }"; + var expected = @"public class C { string s = [|@""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String6() + { + var code = @"public class C { string s = @""Goo""u$$8; }"; + var expected = @"public class C { string s = [|@""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [Fact] + public async Task TestVerbatimUtf8String7() + { + var code = @"public class C { string s = @""Goo""u8$$; }"; + var expected = @"public class C { string s = [|@""|]Goo""u8; }"; + + await TestAsync(code, expected); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestConditionalDirectiveWithSingleMatchingDirective() + { + var code = """ + public class C + { + #if$$ CHK + #endif + } + """; + var expected = """ + public class C + { + #if$$ CHK + [|#endif|] + } + """; + + await TestAsync(code, expected); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestConditionalDirectiveWithTwoMatchingDirectives() + { + var code = """ + public class C + { + #if$$ CHK + #else + #endif + } + """; + var expected = """ + public class C + { + #if$$ CHK + [|#else|] + #endif + } + """; + + await TestAsync(code, expected); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestConditionalDirectiveWithAllMatchingDirectives() + { + var code = """ + public class C + { + #if CHK + #elif RET + #else + #endif$$ + } + """; + var expected = """ + public class C + { + [|#if|] CHK + #elif RET + #else + #endif + } + """; + + await TestAsync(code, expected); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestRegionDirective() + { + var code = """ + public class C + { + $$#region test + #endregion + } + """; + var expected = """ + public class C + { + #region test + [|#endregion|] + } + """; + + await TestAsync(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestUnmatchedDirective1() - { - var code = """ - public class C + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestInterleavedDirectivesInner() + { + var code = """ + #define CHK + public class C + { + void Test() { - $$#region test + #if CHK + $$#region test + var x = 5; + #endregion + #else + var y = 6; + #endif } - """; - var expected = """ - public class C + } + """; + var expected = """ + #define CHK + public class C + { + void Test() { - #region test + #if CHK + #region test + var x = 5; + [|#endregion|] + #else + var y = 6; + #endif } - """; + } + """; - await TestAsync(code, expected); - } + await TestAsync(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] - public async Task TestUnmatchedDirective2() - { - var code = """ - #d$$efine CHK - public class C + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestInterleavedDirectivesOuter() + { + var code = """ + #define CHK + public class C + { + void Test() { + #if$$ CHK + #region test + var x = 5; + #endregion + #else + var y = 6; + #endif } - """; - var expected = """ - #define CHK - public class C + } + """; + var expected = """ + #define CHK + public class C + { + void Test() { + #if CHK + #region test + var x = 5; + #endregion + [|#else|] + var y = 6; + #endif } - """; + } + """; - await TestAsync(code, expected); - } + await TestAsync(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7534")] - public async Task TestUnmatchedConditionalDirective() - { - var code = """ - class Program - { - static void Main(string[] args) - {#if$$ + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestUnmatchedDirective1() + { + var code = """ + public class C + { + $$#region test + } + """; + var expected = """ + public class C + { + #region test + } + """; + + await TestAsync(code, expected); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7120")] + public async Task TestUnmatchedDirective2() + { + var code = """ + #d$$efine CHK + public class C + { + } + """; + var expected = """ + #define CHK + public class C + { + } + """; + + await TestAsync(code, expected); + } + + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7534")] + public async Task TestUnmatchedConditionalDirective() + { + var code = """ + class Program + { + static void Main(string[] args) + {#if$$ - } } - """; - var expected = """ - class Program - { - static void Main(string[] args) - {#if + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + {#if - } } - """; + } + """; - await TestAsync(code, expected); - } + await TestAsync(code, expected); + } - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7534")] - public async Task TestUnmatchedConditionalDirective2() - { - var code = """ - class Program - { - static void Main(string[] args) - {#else$$ + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/7534")] + public async Task TestUnmatchedConditionalDirective2() + { + var code = """ + class Program + { + static void Main(string[] args) + {#else$$ - } } - """; - var expected = """ - class Program - { - static void Main(string[] args) - {#else + } + """; + var expected = """ + class Program + { + static void Main(string[] args) + {#else - } } - """; - - await TestAsync(code, expected); - } - - [Fact] - public async Task StartTupleDeclaration() - { - var code = @"public class C { $$(int, int, int, int, int, int, int, int) x; }"; - var expected = @"public class C { (int, int, int, int, int, int, int, int[|)|] x; }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task EndTupleDeclaration() - { - var code = @"public class C { (int, int, int, int, int, int, int, int)$$ x; }"; - var expected = @"public class C { [|(|]int, int, int, int, int, int, int, int) x; }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task StartTupleLiteral() - { - var code = @"public class C { var x = $$(1, 2, 3, 4, 5, 6, 7, 8); }"; - var expected = @"public class C { var x = (1, 2, 3, 4, 5, 6, 7, 8[|)|]; }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task EndTupleLiteral() - { - var code = @"public class C { var x = (1, 2, 3, 4, 5, 6, 7, 8)$$; }"; - var expected = @"public class C { var x = [|(|]1, 2, 3, 4, 5, 6, 7, 8); }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task StartNestedTupleLiteral() - { - var code = @"public class C { var x = $$((1, 1, 1), 2, 3, 4, 5, 6, 7, 8); }"; - var expected = @"public class C { var x = ((1, 1, 1), 2, 3, 4, 5, 6, 7, 8[|)|]; }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task StartInnerNestedTupleLiteral() - { - var code = @"public class C { var x = ($$(1, 1, 1), 2, 3, 4, 5, 6, 7, 8); }"; - var expected = @"public class C { var x = ((1, 1, 1[|)|], 2, 3, 4, 5, 6, 7, 8); }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task EndNestedTupleLiteral() - { - var code = @"public class C { var x = (1, 2, 3, 4, 5, 6, 7, (8, 8, 8))$$; }"; - var expected = @"public class C { var x = [|(|]1, 2, 3, 4, 5, 6, 7, (8, 8, 8)); }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task EndInnerNestedTupleLiteral() - { - var code = @"public class C { var x = ((1, 1, 1)$$, 2, 3, 4, 5, 6, 7, 8); }"; - var expected = @"public class C { var x = ([|(|]1, 1, 1), 2, 3, 4, 5, 6, 7, 8); }"; - - await TestAsync(code, expected, TestOptions.Regular); - } - - [Fact] - public async Task TestFunctionPointer() - { - var code = @"public unsafe class C { delegate*<$$int, int> functionPointer; }"; - var expected = @"public unsafe class C { delegate*|] functionPointer; }"; - - await TestAsync(code, expected, TestOptions.Regular); - } + } + """; + + await TestAsync(code, expected); + } + + [Fact] + public async Task StartTupleDeclaration() + { + var code = @"public class C { $$(int, int, int, int, int, int, int, int) x; }"; + var expected = @"public class C { (int, int, int, int, int, int, int, int[|)|] x; }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task EndTupleDeclaration() + { + var code = @"public class C { (int, int, int, int, int, int, int, int)$$ x; }"; + var expected = @"public class C { [|(|]int, int, int, int, int, int, int, int) x; }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task StartTupleLiteral() + { + var code = @"public class C { var x = $$(1, 2, 3, 4, 5, 6, 7, 8); }"; + var expected = @"public class C { var x = (1, 2, 3, 4, 5, 6, 7, 8[|)|]; }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task EndTupleLiteral() + { + var code = @"public class C { var x = (1, 2, 3, 4, 5, 6, 7, 8)$$; }"; + var expected = @"public class C { var x = [|(|]1, 2, 3, 4, 5, 6, 7, 8); }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task StartNestedTupleLiteral() + { + var code = @"public class C { var x = $$((1, 1, 1), 2, 3, 4, 5, 6, 7, 8); }"; + var expected = @"public class C { var x = ((1, 1, 1), 2, 3, 4, 5, 6, 7, 8[|)|]; }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task StartInnerNestedTupleLiteral() + { + var code = @"public class C { var x = ($$(1, 1, 1), 2, 3, 4, 5, 6, 7, 8); }"; + var expected = @"public class C { var x = ((1, 1, 1[|)|], 2, 3, 4, 5, 6, 7, 8); }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task EndNestedTupleLiteral() + { + var code = @"public class C { var x = (1, 2, 3, 4, 5, 6, 7, (8, 8, 8))$$; }"; + var expected = @"public class C { var x = [|(|]1, 2, 3, 4, 5, 6, 7, (8, 8, 8)); }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task EndInnerNestedTupleLiteral() + { + var code = @"public class C { var x = ((1, 1, 1)$$, 2, 3, 4, 5, 6, 7, 8); }"; + var expected = @"public class C { var x = ([|(|]1, 1, 1), 2, 3, 4, 5, 6, 7, 8); }"; + + await TestAsync(code, expected, TestOptions.Regular); + } + + [Fact] + public async Task TestFunctionPointer() + { + var code = @"public unsafe class C { delegate*<$$int, int> functionPointer; }"; + var expected = @"public unsafe class C { delegate*|] functionPointer; }"; + + await TestAsync(code, expected, TestOptions.Regular); } } diff --git a/src/EditorFeatures/CSharpTest/BracePairs/CSharpBracePairsTests.cs b/src/EditorFeatures/CSharpTest/BracePairs/CSharpBracePairsTests.cs index 15dd86e0650a7..dc1b23d66440c 100644 --- a/src/EditorFeatures/CSharpTest/BracePairs/CSharpBracePairsTests.cs +++ b/src/EditorFeatures/CSharpTest/BracePairs/CSharpBracePairsTests.cs @@ -7,29 +7,28 @@ using Microsoft.CodeAnalysis.Test.Utilities.BracePairs; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BracePairs +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BracePairs; + +public sealed class CSharpBracePairsTests : AbstractBracePairsTests { - public sealed class CSharpBracePairsTests : AbstractBracePairsTests - { - protected override EditorTestWorkspace CreateWorkspace(string input) - => EditorTestWorkspace.CreateCSharp(input); + protected override EditorTestWorkspace CreateWorkspace(string input) + => EditorTestWorkspace.CreateCSharp(input); - [Fact] - public async Task Test1() - { - await Test(""" - public class C - {|a:{|} - void M{|b:(|}int i{|b:)|} - {|c:{|} - {|c:}|} + [Fact] + public async Task Test1() + { + await Test(""" + public class C + {|a:{|} + void M{|b:(|}int i{|b:)|} + {|c:{|} + {|c:}|} - {|d:[|}Attr{|d:]|} - void M2{|e:(|}List{|f:<|}int{|f:>|} i{|e:)|} - {|g:{|} - {|g:}|} - {|a:}|} - """); - } + {|d:[|}Attr{|d:]|} + void M2{|e:(|}List{|f:<|}int{|f:>|} i{|e:)|} + {|g:{|} + {|g:}|} + {|a:}|} + """); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.AddImports.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.AddImports.cs index a762076eefa27..4d00af88adbe4 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.AddImports.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.AddImports.cs @@ -9,151 +9,149 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task AddParameterAddsAllImports() { - [Fact] - public async Task AddParameterAddsAllImports() - { - var markup = """ - class C - { - void $$M() { } - } - """; - - var updatedSignature = new[] { - new AddedParameterOrExistingIndex( - new AddedParameter( - null, - "Dictionary>", - "test", - CallSiteKind.Todo), - "System.Collections.Generic.Dictionary>")}; - - var updatedCode = """ - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Threading.Tasks; - - class C - { - void M(Dictionary> test) { } - } - """; + var markup = """ + class C + { + void $$M() { } + } + """; + + var updatedSignature = new[] { + new AddedParameterOrExistingIndex( + new AddedParameter( + null, + "Dictionary>", + "test", + CallSiteKind.Todo), + "System.Collections.Generic.Dictionary>")}; + + var updatedCode = """ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Threading.Tasks; + + class C + { + void M(Dictionary> test) { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task AddParameterAddsOnlyMissingImports() + { + var markup = """ + using System.ComponentModel; + + class C + { + void $$M() { } + } + """; + + var updatedSignature = new[] { + new AddedParameterOrExistingIndex( + new AddedParameter( + null, + "Dictionary>", + "test", + CallSiteKind.Todo), + "System.Collections.Generic.Dictionary>")}; + + var updatedCode = """ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Threading.Tasks; + + class C + { + void M(Dictionary> test) { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameterAddsOnlyMissingImports() - { - var markup = """ - using System.ComponentModel; + [Fact] + public async Task AddParameterAddsImportsOnCascading() + { + var markup = """ + using NS1; - class C + namespace NS1 + { + class B { - void $$M() { } + public virtual void M() { } } - """; - - var updatedSignature = new[] { - new AddedParameterOrExistingIndex( - new AddedParameter( - null, - "Dictionary>", - "test", - CallSiteKind.Todo), - "System.Collections.Generic.Dictionary>")}; - - var updatedCode = """ + } + + namespace NS2 + { using System; using System.Collections.Generic; using System.ComponentModel; using System.Threading.Tasks; - class C + class D : B { - void M(Dictionary> test) { } + public override void $$M() { } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddParameterAddsImportsOnCascading() - { - var markup = """ - using NS1; - - namespace NS1 + } + """; + + var updatedSignature = new[] { + new AddedParameterOrExistingIndex( + new AddedParameter( + null, + "Dictionary>", + "test", + CallSiteKind.Todo), + "System.Collections.Generic.Dictionary>")}; + + var updatedCode = """ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Threading.Tasks; + using NS1; + + namespace NS1 + { + class B { - class B - { - public virtual void M() { } - } + public virtual void M(Dictionary> test) { } } + } - namespace NS2 - { - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Threading.Tasks; - - class D : B - { - public override void $$M() { } - } - } - """; - - var updatedSignature = new[] { - new AddedParameterOrExistingIndex( - new AddedParameter( - null, - "Dictionary>", - "test", - CallSiteKind.Todo), - "System.Collections.Generic.Dictionary>")}; - - var updatedCode = """ + namespace NS2 + { using System; using System.Collections.Generic; using System.ComponentModel; using System.Threading.Tasks; - using NS1; - - namespace NS1 - { - class B - { - public virtual void M(Dictionary> test) { } - } - } - namespace NS2 + class D : B { - using System; - using System.Collections.Generic; - using System.ComponentModel; - using System.Threading.Tasks; - - class D : B - { - public override void M(Dictionary> test) { } - } + public override void M(Dictionary> test) { } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Cascading.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Cascading.cs index f3f7e32f335a1..150f24c700c36 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Cascading.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Cascading.cs @@ -11,470 +11,469 @@ using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task AddParameter_Cascade_ToImplementedMethod() { - [Fact] - public async Task AddParameter_Cascade_ToImplementedMethod() - { - var markup = """ - interface I - { - void M(int x, string y); - } + var markup = """ + interface I + { + void M(int x, string y); + } - class C : I - { - $$public void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - interface I - { - void M(string y, int newIntegerParameter, int x); - } + class C : I + { + $$public void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + interface I + { + void M(string y, int newIntegerParameter, int x); + } - class C : I - { - public void M(string y, int newIntegerParameter, int x) - { } - } - """; + class C : I + { + public void M(string y, int newIntegerParameter, int x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToImplementedMethod_WithTuples() - { - var markup = """ - interface I - { - void M((int, int) x, (string a, string b) y); - } + [Fact] + public async Task AddParameter_Cascade_ToImplementedMethod_WithTuples() + { + var markup = """ + interface I + { + void M((int, int) x, (string a, string b) y); + } - class C : I - { - $$public void M((int, int) x, (string a, string b) y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - interface I - { - void M((string a, string b) y, int newIntegerParameter, (int, int) x); - } + class C : I + { + $$public void M((int, int) x, (string a, string b) y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + interface I + { + void M((string a, string b) y, int newIntegerParameter, (int, int) x); + } - class C : I - { - public void M((string a, string b) y, int newIntegerParameter, (int, int) x) - { } - } - """; + class C : I + { + public void M((string a, string b) y, int newIntegerParameter, (int, int) x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToImplementingMethod() - { - var markup = """ - interface I - { - $$void M(int x, string y); - } + [Fact] + public async Task AddParameter_Cascade_ToImplementingMethod() + { + var markup = """ + interface I + { + $$void M(int x, string y); + } - class C : I - { - public void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - interface I - { - void M(string y, int newIntegerParameter, int x); - } + class C : I + { + public void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + interface I + { + void M(string y, int newIntegerParameter, int x); + } - class C : I - { - public void M(string y, int newIntegerParameter, int x) - { } - } - """; + class C : I + { + public void M(string y, int newIntegerParameter, int x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToOverriddenMethod() - { - var markup = """ - class B - { - public virtual void M(int x, string y) - { } - } + [Fact] + public async Task AddParameter_Cascade_ToOverriddenMethod() + { + var markup = """ + class B + { + public virtual void M(int x, string y) + { } + } - class D : B - { - $$public override void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - class B - { - public virtual void M(string y, int newIntegerParameter, int x) - { } - } + class D : B + { + $$public override void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + class B + { + public virtual void M(string y, int newIntegerParameter, int x) + { } + } - class D : B - { - public override void M(string y, int newIntegerParameter, int x) - { } - } - """; + class D : B + { + public override void M(string y, int newIntegerParameter, int x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToOverridingMethod() - { - var markup = """ - class B - { - $$public virtual void M(int x, string y) - { } - } + [Fact] + public async Task AddParameter_Cascade_ToOverridingMethod() + { + var markup = """ + class B + { + $$public virtual void M(int x, string y) + { } + } - class D : B - { - public override void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - class B - { - public virtual void M(string y, int newIntegerParameter, int x) - { } - } + class D : B + { + public override void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + class B + { + public virtual void M(string y, int newIntegerParameter, int x) + { } + } - class D : B - { - public override void M(string y, int newIntegerParameter, int x) - { } - } - """; + class D : B + { + public override void M(string y, int newIntegerParameter, int x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToOverriddenMethod_Transitive() - { - var markup = """ - class B - { - public virtual void M(int x, string y) - { } - } + [Fact] + public async Task AddParameter_Cascade_ToOverriddenMethod_Transitive() + { + var markup = """ + class B + { + public virtual void M(int x, string y) + { } + } - class D : B - { - public override void M(int x, string y) - { } - } + class D : B + { + public override void M(int x, string y) + { } + } - class D2 : D - { - $$public override void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - class B - { - public virtual void M(string y, int newIntegerParameter, int x) - { } - } + class D2 : D + { + $$public override void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + class B + { + public virtual void M(string y, int newIntegerParameter, int x) + { } + } - class D : B - { - public override void M(string y, int newIntegerParameter, int x) - { } - } + class D : B + { + public override void M(string y, int newIntegerParameter, int x) + { } + } - class D2 : D - { - public override void M(string y, int newIntegerParameter, int x) - { } - } - """; + class D2 : D + { + public override void M(string y, int newIntegerParameter, int x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToOverridingMethod_Transitive() - { - var markup = """ - class B - { - $$public virtual void M(int x, string y) - { } - } + [Fact] + public async Task AddParameter_Cascade_ToOverridingMethod_Transitive() + { + var markup = """ + class B + { + $$public virtual void M(int x, string y) + { } + } - class D : B - { - public override void M(int x, string y) - { } - } + class D : B + { + public override void M(int x, string y) + { } + } - class D2 : D - { - public override void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - class B - { - public virtual void M(string y, int newIntegerParameter, int x) - { } - } + class D2 : D + { + public override void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + class B + { + public virtual void M(string y, int newIntegerParameter, int x) + { } + } - class D : B - { - public override void M(string y, int newIntegerParameter, int x) - { } - } + class D : B + { + public override void M(string y, int newIntegerParameter, int x) + { } + } - class D2 : D - { - public override void M(string y, int newIntegerParameter, int x) - { } - } - """; + class D2 : D + { + public override void M(string y, int newIntegerParameter, int x) + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameter_Cascade_ToMethods_Complex() - { - //// B I I2 - //// \ / \ / - //// D (I3) - //// / \ \ - //// $$D2 D3 C - - var markup = """ - class B { public virtual void M(int x, string y) { } } - class D : B, I { public override void M(int x, string y) { } } - class D2 : D { public override void $$M(int x, string y) { } } - class D3 : D { public override void M(int x, string y) { } } - interface I { void M(int x, string y); } - interface I2 { void M(int x, string y); } - interface I3 : I, I2 { } - class C : I3 { public void M(int x, string y) { } } - """; - - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - class B { public virtual void M(string y, int newIntegerParameter, int x) { } } - class D : B, I { public override void M(string y, int newIntegerParameter, int x) { } } - class D2 : D { public override void M(string y, int newIntegerParameter, int x) { } } - class D3 : D { public override void M(string y, int newIntegerParameter, int x) { } } - interface I { void M(string y, int newIntegerParameter, int x); } - interface I2 { void M(string y, int newIntegerParameter, int x); } - interface I3 : I, I2 { } - class C : I3 { public void M(string y, int newIntegerParameter, int x) { } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddParameter_Cascade_ToMethods_WithDifferentParameterNames() - { - var markup = """ - public class B - { - /// - /// - public virtual int M(int x, string y) - { - return 1; - } - } + [Fact] + public async Task AddParameter_Cascade_ToMethods_Complex() + { + //// B I I2 + //// \ / \ / + //// D (I3) + //// / \ \ + //// $$D2 D3 C + + var markup = """ + class B { public virtual void M(int x, string y) { } } + class D : B, I { public override void M(int x, string y) { } } + class D2 : D { public override void $$M(int x, string y) { } } + class D3 : D { public override void M(int x, string y) { } } + interface I { void M(int x, string y); } + interface I2 { void M(int x, string y); } + interface I3 : I, I2 { } + class C : I3 { public void M(int x, string y) { } } + """; + + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + class B { public virtual void M(string y, int newIntegerParameter, int x) { } } + class D : B, I { public override void M(string y, int newIntegerParameter, int x) { } } + class D2 : D { public override void M(string y, int newIntegerParameter, int x) { } } + class D3 : D { public override void M(string y, int newIntegerParameter, int x) { } } + interface I { void M(string y, int newIntegerParameter, int x); } + interface I2 { void M(string y, int newIntegerParameter, int x); } + interface I3 : I, I2 { } + class C : I3 { public void M(string y, int newIntegerParameter, int x) { } } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - public class D : B + [Fact] + public async Task AddParameter_Cascade_ToMethods_WithDifferentParameterNames() + { + var markup = """ + public class B + { + /// + /// + public virtual int M(int x, string y) { - /// - /// - public override int M(int a, string b) - { - return 1; - } + return 1; } + } - public class D2 : D + public class D : B + { + /// + /// + public override int M(int a, string b) { - /// - /// - public override int $$M(int y, string x) - { - M(1, "Two"); - ((D)this).M(1, "Two"); - ((B)this).M(1, "Two"); - - M(1, x: "Two"); - ((D)this).M(1, b: "Two"); - ((B)this).M(1, y: "Two"); - - return 1; - } + return 1; } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(0) - }; - var updatedCode = """ - public class B + } + + public class D2 : D + { + /// + /// + public override int $$M(int y, string x) + { + M(1, "Two"); + ((D)this).M(1, "Two"); + ((B)this).M(1, "Two"); + + M(1, x: "Two"); + ((D)this).M(1, b: "Two"); + ((B)this).M(1, y: "Two"); + + return 1; + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(0) + }; + var updatedCode = """ + public class B + { + /// + /// + /// + public virtual int M(string y, int newIntegerParameter, int x) { - /// - /// - /// - public virtual int M(string y, int newIntegerParameter, int x) - { - return 1; - } + return 1; } + } - public class D : B + public class D : B + { + /// + /// + /// + public override int M(string b, int newIntegerParameter, int a) { - /// - /// - /// - public override int M(string b, int newIntegerParameter, int a) - { - return 1; - } + return 1; } + } - public class D2 : D + public class D2 : D + { + /// + /// + /// + public override int M(string x, int newIntegerParameter, int y) { - /// - /// - /// - public override int M(string x, int newIntegerParameter, int y) - { - M("Two", 12345, 1); - ((D)this).M("Two", 12345, 1); - ((B)this).M("Two", 12345, 1); - - M(x: "Two", newIntegerParameter: 12345, y: 1); - ((D)this).M(b: "Two", newIntegerParameter: 12345, a: 1); - ((B)this).M(y: "Two", newIntegerParameter: 12345, x: 1); - - return 1; - } + M("Two", 12345, 1); + ((D)this).M("Two", 12345, 1); + ((B)this).M("Two", 12345, 1); + + M(x: "Two", newIntegerParameter: 12345, y: 1); + ((D)this).M(b: "Two", newIntegerParameter: 12345, a: 1); + ((B)this).M(y: "Two", newIntegerParameter: 12345, x: 1); + + return 1; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/53091")] + public async Task AddParameter_Cascade_Record() + { + var markup = """ + record $$BaseR(int A, int B); - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/53091")] - public async Task AddParameter_Cascade_Record() + record DerivedR() : BaseR(0, 1); + """; + var permutation = new AddedParameterOrExistingIndex[] { - var markup = """ - record $$BaseR(int A, int B); + new(1), + new(new AddedParameter(null, "int", "C", CallSiteKind.Value, "3"), "int"), + new(0) + }; + var updatedCode = """ + record BaseR(int B, int C, int A); - record DerivedR() : BaseR(0, 1); - """; - var permutation = new AddedParameterOrExistingIndex[] - { - new(1), - new(new AddedParameter(null, "int", "C", CallSiteKind.Value, "3"), "int"), - new(0) - }; - var updatedCode = """ - record BaseR(int B, int C, int A); + record DerivedR() : BaseR(1, 3, 0); + """; - record DerivedR() : BaseR(1, 3, 0); - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/53091")] + public async Task AddParameter_Cascade_PrimaryConstructor() + { + var markup = """ + class $$BaseR(int A, int B); - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/53091")] - public async Task AddParameter_Cascade_PrimaryConstructor() + class DerivedR() : BaseR(0, 1); + """; + var permutation = new AddedParameterOrExistingIndex[] { - var markup = """ - class $$BaseR(int A, int B); - - class DerivedR() : BaseR(0, 1); - """; - var permutation = new AddedParameterOrExistingIndex[] - { - new(1), - new(new AddedParameter(null, "int", "C", CallSiteKind.Value, "3"), "int"), - new(0) - }; - var updatedCode = """ - class BaseR(int B, int C, int A); + new(1), + new(new AddedParameter(null, "int", "C", CallSiteKind.Value, "3"), "int"), + new(0) + }; + var updatedCode = """ + class BaseR(int B, int C, int A); - class DerivedR() : BaseR(1, 3, 0); - """; + class DerivedR() : BaseR(1, 3, 0); + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Delegates.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Delegates.cs index 12f3e1a8542e9..4d0aa2c832c85 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Delegates.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Delegates.cs @@ -9,942 +9,940 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task AddParameter_Delegates_ImplicitInvokeCalls() { - [Fact] - public async Task AddParameter_Delegates_ImplicitInvokeCalls() - { - var markup = """ - delegate void MyDelegate($$int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = null; - d1(1, "Two", true); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1(true, 12345, "Two"); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); - } + var markup = """ + delegate void MyDelegate($$int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1(1, "Two", true); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1(true, 12345, "Two"); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); + } - [Fact] - public async Task AddParameter_Delegates_ExplicitInvokeCalls() - { - var markup = """ - delegate void MyDelegate(int x, string $$y, bool z); + [Fact] + public async Task AddParameter_Delegates_ExplicitInvokeCalls() + { + var markup = """ + delegate void MyDelegate(int x, string $$y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1.Invoke(1, "Two", true); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1.Invoke(true, 12345, "Two"); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 1); + } - class C - { - void M() - { - MyDelegate d1 = null; - d1.Invoke(1, "Two", true); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); + [Fact] + public async Task AddParameter_Delegates_BeginInvokeCalls() + { + var markup = """ + delegate void MyDelegate(int x, string y, bool z$$); + + class C + { + void M() + { + MyDelegate d1 = null; + d1.BeginInvoke(1, "Two", true, null, null); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1.BeginInvoke(true, 12345, "Two", null, null); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 2); + } - class C - { - void M() - { - MyDelegate d1 = null; - d1.Invoke(true, 12345, "Two"); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 1); - } + [Fact] + public async Task AddParameter_Delegates_AnonymousMethods() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = delegate (int e, string f, bool g) { var x = f.Length + (g ? 0 : 1); }; + d1 = delegate { }; + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = delegate (bool g, int newIntegerParameter, string f) { var x = f.Length + (g ? 0 : 1); }; + d1 = delegate { }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegates_BeginInvokeCalls() - { - var markup = """ - delegate void MyDelegate(int x, string y, bool z$$); + [Fact] + public async Task AddParameter_Delegates_Lambdas() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (r, s, t) => { var x = s.Length + (t ? 0 : 1); }; + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (t, newIntegerParameter, s) => { var x = s.Length + (t ? 0 : 1); }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C - { - void M() - { - MyDelegate d1 = null; - d1.BeginInvoke(1, "Two", true, null, null); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); + [Fact] + public async Task AddParameter_Delegates_Lambdas_RemovingOnlyParameterIntroducesParentheses() + { + var markup = """ + delegate void $$MyDelegate(int x); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (r) => { System.Console.WriteLine("Test"); }; + d1 = r => { System.Console.WriteLine("Test"); }; + d1 = r => { System.Console.WriteLine("Test"); }; + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(int newIntegerParameter); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (newIntegerParameter) => { System.Console.WriteLine("Test"); }; + d1 = (int newIntegerParameter) => { System.Console.WriteLine("Test"); }; + d1 = (int newIntegerParameter) => { System.Console.WriteLine("Test"); }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C - { - void M() - { - MyDelegate d1 = null; - d1.BeginInvoke(true, 12345, "Two", null, null); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 2); - } + [Fact] + public async Task AddParameter_Delegates_CascadeThroughMethodGroups_AssignedToVariable() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = Goo; + Goo(1, "Two", true); + Goo(1, false, false); + } + + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = Goo; + Goo(true, 12345, "Two"); + Goo(1, false, false); + } + + void Goo(bool c, int newIntegerParameter, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegates_AnonymousMethods() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + [Fact] + public async Task AddParameter_Delegates_CascadeThroughMethodGroups_DelegateConstructor() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = new MyDelegate(Goo); + Goo(1, "Two", true); + Goo(1, false, false); + } + + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = new MyDelegate(Goo); + Goo(true, 12345, "Two"); + Goo(1, false, false); + } + + void Goo(bool c, int newIntegerParameter, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C - { - void M() - { - MyDelegate d1 = null; - d1 = delegate (int e, string f, bool g) { var x = f.Length + (g ? 0 : 1); }; - d1 = delegate { }; - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); + [Fact] + public async Task AddParameter_Delegates_CascadeThroughMethodGroups_PassedAsArgument() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - class C + class C + { + void M() { - void M() - { - MyDelegate d1 = null; - d1 = delegate (bool g, int newIntegerParameter, string f) { var x = f.Length + (g ? 0 : 1); }; - d1 = delegate { }; - } + Target(Goo); + Goo(1, "Two", true); + Goo(1, false, false); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_Lambdas() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + void Target(MyDelegate d) { } - class C - { - void M() - { - MyDelegate d1 = null; - d1 = (r, s, t) => { var x = s.Length + (t ? 0 : 1); }; - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + class C + { + void M() { - void M() - { - MyDelegate d1 = null; - d1 = (t, newIntegerParameter, s) => { var x = s.Length + (t ? 0 : 1); }; - } + Target(Goo); + Goo(true, 12345, "Two"); + Goo(1, false, false); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_Lambdas_RemovingOnlyParameterIntroducesParentheses() - { - var markup = """ - delegate void $$MyDelegate(int x); + void Target(MyDelegate d) { } - class C - { - void M() - { - MyDelegate d1 = null; - d1 = (r) => { System.Console.WriteLine("Test"); }; - d1 = r => { System.Console.WriteLine("Test"); }; - d1 = r => { System.Console.WriteLine("Test"); }; - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(int newIntegerParameter); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = (newIntegerParameter) => { System.Console.WriteLine("Test"); }; - d1 = (int newIntegerParameter) => { System.Console.WriteLine("Test"); }; - d1 = (int newIntegerParameter) => { System.Console.WriteLine("Test"); }; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + void Goo(bool c, int newIntegerParameter, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegates_CascadeThroughMethodGroups_AssignedToVariable() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + [Fact] + public async Task AddParameter_Delegates_CascadeThroughMethodGroups_ReturnValue() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - class C + class C + { + void M() { - void M() - { - MyDelegate d1 = null; - d1 = Goo; - Goo(1, "Two", true); - Goo(1, false, false); - } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + MyDelegate d1 = Result(); + Goo(1, "Two", true); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + private MyDelegate Result() { - void M() - { - MyDelegate d1 = null; - d1 = Goo; - Goo(true, 12345, "Two"); - Goo(1, false, false); - } - - void Goo(bool c, int newIntegerParameter, string b) { } - void Goo(int a, object b, bool c) { } + return Goo; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_CascadeThroughMethodGroups_DelegateConstructor() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + class C + { + void M() { - void M() - { - MyDelegate d1 = new MyDelegate(Goo); - Goo(1, "Two", true); - Goo(1, false, false); - } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + MyDelegate d1 = Result(); + Goo(true, 12345, "Two"); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + private MyDelegate Result() { - void M() - { - MyDelegate d1 = new MyDelegate(Goo); - Goo(true, 12345, "Two"); - Goo(1, false, false); - } - - void Goo(bool c, int newIntegerParameter, string b) { } - void Goo(int a, object b, bool c) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task AddParameter_Delegates_CascadeThroughMethodGroups_PassedAsArgument() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - Target(Goo); - Goo(1, "Two", true); - Goo(1, false, false); - } - - void Target(MyDelegate d) { } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + return Goo; } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C - { - void M() - { - Target(Goo); - Goo(true, 12345, "Two"); - Goo(1, false, false); - } - - void Target(MyDelegate d) { } + void Goo(bool c, int newIntegerParameter, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - void Goo(bool c, int newIntegerParameter, string b) { } - void Goo(int a, object b, bool c) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact] + public async Task AddParameter_Delegates_CascadeThroughMethodGroups_YieldReturnValue() + { + var markup = """ + using System.Collections.Generic; - [Fact] - public async Task AddParameter_Delegates_CascadeThroughMethodGroups_ReturnValue() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + delegate void $$MyDelegate(int x, string y, bool z); - class C + class C + { + void M() { - void M() - { - MyDelegate d1 = Result(); - Goo(1, "Two", true); - } - - private MyDelegate Result() - { - return Goo; - } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + Goo(1, "Two", true); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + private IEnumerable Result() { - void M() - { - MyDelegate d1 = Result(); - Goo(true, 12345, "Two"); - } - - private MyDelegate Result() - { - return Goo; - } - - void Goo(bool c, int newIntegerParameter, string b) { } - void Goo(int a, object b, bool c) { } + yield return Goo; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_CascadeThroughMethodGroups_YieldReturnValue() - { - var markup = """ - using System.Collections.Generic; + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + using System.Collections.Generic; - delegate void $$MyDelegate(int x, string y, bool z); + delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + class C + { + void M() { - void M() - { - Goo(1, "Two", true); - } - - private IEnumerable Result() - { - yield return Goo; - } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + Goo(true, 12345, "Two"); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - using System.Collections.Generic; - - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + private IEnumerable Result() { - void M() - { - Goo(true, 12345, "Two"); - } - - private IEnumerable Result() - { - yield return Goo; - } - - void Goo(bool c, int newIntegerParameter, string b) { } - void Goo(int a, object b, bool c) { } + yield return Goo; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_ReferencingLambdas_MethodArgument() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M6() - { - Target((m, n, o) => { var x = n.Length + (o ? 0 : 1); }); - } + void Goo(bool c, int newIntegerParameter, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - void Target(MyDelegate d) { } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); + [Fact] + public async Task AddParameter_Delegates_ReferencingLambdas_MethodArgument() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - class C + class C + { + void M6() { - void M6() - { - Target((o, newIntegerParameter, n) => { var x = n.Length + (o ? 0 : 1); }); - } - - void Target(MyDelegate d) { } + Target((m, n, o) => { var x = n.Length + (o ? 0 : 1); }); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_ReferencingLambdas_YieldReturn() - { - var markup = """ - using System.Collections.Generic; - - delegate void $$MyDelegate(int x, string y, bool z); - class C - { - private IEnumerable Result3() - { - yield return (g, h, i) => { var x = h.Length + (i ? 0 : 1); }; - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - using System.Collections.Generic; + void Target(MyDelegate d) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class C + class C + { + void M6() { - private IEnumerable Result3() - { - yield return (i, newIntegerParameter, h) => { var x = h.Length + (i ? 0 : 1); }; - } + Target((o, newIntegerParameter, n) => { var x = n.Length + (o ? 0 : 1); }); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task AddParameter_Delegates_Recursive() - { - var markup = """ - delegate RecursiveDelegate $$RecursiveDelegate(int x, string y, bool z); - - class C - { - void M() - { - RecursiveDelegate rd = null; - rd(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate RecursiveDelegate RecursiveDelegate(bool z, int newIntegerParameter, string y); + void Target(MyDelegate d) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C - { - void M() - { - RecursiveDelegate rd = null; - rd(true, 12345, "Two")(true, 12345, "Two")(true, 12345, "Two")(true, 12345, "Two")(true, 12345, "Two"); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task AddParameter_Delegates_DocComments() - { - var markup = """ - /// - /// This is , which has these methods: - /// - /// - /// - /// - /// - /// x! - /// y! - /// z! - delegate void $$MyDelegate(int x, string y, bool z); + [Fact] + public async Task AddParameter_Delegates_ReferencingLambdas_YieldReturn() + { + var markup = """ + using System.Collections.Generic; + + delegate void $$MyDelegate(int x, string y, bool z); + class C + { + private IEnumerable Result3() + { + yield return (g, h, i) => { var x = h.Length + (i ? 0 : 1); }; + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + using System.Collections.Generic; + + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + class C + { + private IEnumerable Result3() + { + yield return (i, newIntegerParameter, h) => { var x = h.Length + (i ? 0 : 1); }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C - { - void M() - { - MyDelegate d1 = Goo; - Goo(1, "Two", true); - } + [Fact] + public async Task AddParameter_Delegates_Recursive() + { + var markup = """ + delegate RecursiveDelegate $$RecursiveDelegate(int x, string y, bool z); + + class C + { + void M() + { + RecursiveDelegate rd = null; + rd(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate RecursiveDelegate RecursiveDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + RecursiveDelegate rd = null; + rd(true, 12345, "Two")(true, 12345, "Two")(true, 12345, "Two")(true, 12345, "Two")(true, 12345, "Two"); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - /// - /// - /// - void Goo(int a, string b, bool c) { } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - /// - /// This is , which has these methods: - /// - /// - /// - /// - /// - /// z! + [Fact] + public async Task AddParameter_Delegates_DocComments() + { + var markup = """ + /// + /// This is , which has these methods: + /// + /// + /// + /// + /// + /// x! + /// y! + /// z! + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = Goo; + Goo(1, "Two", true); + } + + /// + /// + /// + void Goo(int a, string b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + /// + /// This is , which has these methods: + /// + /// + /// + /// + /// + /// z! + /// + /// y! + delegate void MyDelegate(bool z, int newIntegerParameter, string y); + + class C + { + void M() + { + MyDelegate d1 = Goo; + Goo(true, 12345, "Two"); + } + + /// /// - /// y! - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - - class C - { - void M() - { - MyDelegate d1 = Goo; - Goo(true, 12345, "Two"); - } - - /// - /// - /// - void Goo(bool c, int newIntegerParameter, string b) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + /// + void Goo(bool c, int newIntegerParameter, string b) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegates_CascadeThroughEventAdd() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + [Fact] + public async Task AddParameter_Delegates_CascadeThroughEventAdd() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - class Program + class Program + { + void M() { - void M() - { - MyEvent += Program_MyEvent; - } - - event MyDelegate MyEvent; - void Program_MyEvent(int a, string b, bool c) { } + MyEvent += Program_MyEvent; } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, int newIntegerParameter, string y); - class Program - { - void M() - { - MyEvent += Program_MyEvent; - } + event MyDelegate MyEvent; + void Program_MyEvent(int a, string b, bool c) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, int newIntegerParameter, string y); - event MyDelegate MyEvent; - void Program_MyEvent(bool c, int newIntegerParameter, string b) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task AddParameter_Delegates_Generics1() - { - var markup = """ - public class DP16a + class Program + { + void M() { - public delegate void D($$T t); - public event D E1; - public event D E2; - - public void M1(int i) { } - public void M2(int i) { } - public void M3(int i) { } - - void B() - { - D d = new D(M1); - E1 += new D(M2); - E2 -= new D(M3); - } + MyEvent += Program_MyEvent; } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - }; - var expectedUpdatedCode = """ - public class DP16a - { - public delegate void D(int newIntegerParameter); - public event D E1; - public event D E2; - - public void M1(int newIntegerParameter) { } - public void M2(int newIntegerParameter) { } - public void M3(int newIntegerParameter) { } - void B() - { - D d = new D(M1); - E1 += new D(M2); - E2 -= new D(M3); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + event MyDelegate MyEvent; + void Program_MyEvent(bool c, int newIntegerParameter, string b) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegates_Generics2() - { - var markup = """ - public class D17 - { - public delegate void $$D(T t); - } - public class D17Test - { - void Test() { var x = new D17.D(M17); } - internal void M17(string s) { } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - }; - var expectedUpdatedCode = """ - public class D17 - { - public delegate void D(int newIntegerParameter); - } - public class D17Test - { - void Test() { var x = new D17.D(M17); } - internal void M17(int newIntegerParameter) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact] + public async Task AddParameter_Delegates_Generics1() + { + var markup = """ + public class DP16a + { + public delegate void D($$T t); + public event D E1; + public event D E2; + + public void M1(int i) { } + public void M2(int i) { } + public void M3(int i) { } + + void B() + { + D d = new D(M1); + E1 += new D(M2); + E2 -= new D(M3); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + }; + var expectedUpdatedCode = """ + public class DP16a + { + public delegate void D(int newIntegerParameter); + public event D E1; + public event D E2; + + public void M1(int newIntegerParameter) { } + public void M2(int newIntegerParameter) { } + public void M3(int newIntegerParameter) { } + + void B() + { + D d = new D(M1); + E1 += new D(M2); + E2 -= new D(M3); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegates_GenericParams() - { - var markup = """ - class DA - { - void M(params int[] i) { } - void B() - { - DP20.D d = new DP20.D(M); - d(); - d(0); - d(0, 1); - } - } - public class DP20 - { - public delegate void $$D(params T[] t); - public void M1(params T[] t) { } + [Fact] + public async Task AddParameter_Delegates_Generics2() + { + var markup = """ + public class D17 + { + public delegate void $$D(T t); + } + public class D17Test + { + void Test() { var x = new D17.D(M17); } + internal void M17(string s) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + }; + var expectedUpdatedCode = """ + public class D17 + { + public delegate void D(int newIntegerParameter); + } + public class D17Test + { + void Test() { var x = new D17.D(M17); } + internal void M17(int newIntegerParameter) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - void B() - { - D d = new D(M1); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - }; - var expectedUpdatedCode = """ - class DA - { - void M(int newIntegerParameter) { } - void B() - { - DP20.D d = new DP20.D(M); - d(12345); - d(12345); - d(12345); - } - } - public class DP20 - { - public delegate void D(int newIntegerParameter); - public void M1(int newIntegerParameter) { } + [Fact] + public async Task AddParameter_Delegates_GenericParams() + { + var markup = """ + class DA + { + void M(params int[] i) { } + void B() + { + DP20.D d = new DP20.D(M); + d(); + d(0); + d(0, 1); + } + } + public class DP20 + { + public delegate void $$D(params T[] t); + public void M1(params T[] t) { } + + void B() + { + D d = new D(M1); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + }; + var expectedUpdatedCode = """ + class DA + { + void M(int newIntegerParameter) { } + void B() + { + DP20.D d = new DP20.D(M); + d(12345); + d(12345); + d(12345); + } + } + public class DP20 + { + public delegate void D(int newIntegerParameter); + public void M1(int newIntegerParameter) { } + + void B() + { + D d = new D(M1); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - void B() - { - D d = new D(M1); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact] + public async Task AddParameter_Delegates_Generic_RemoveArgumentAtReference() + { + var markup = """ + public class CD + { + public delegate void D(T t); + } + class Test + { + public void M() + { + var dele = new CD.$$D((int x) => { }); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int") + }; + var expectedUpdatedCode = """ + public class CD + { + public delegate void D(int newIntegerParameter); + } + class Test + { + public void M() + { + var dele = new CD.D((int newIntegerParameter) => { }); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); + } - [Fact] - public async Task AddParameter_Delegates_Generic_RemoveArgumentAtReference() - { - var markup = """ - public class CD - { - public delegate void D(T t); - } - class Test - { - public void M() - { - var dele = new CD.$$D((int x) => { }); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int") - }; - var expectedUpdatedCode = """ - public class CD - { - public delegate void D(int newIntegerParameter); - } - class Test - { - public void M() - { - var dele = new CD.D((int newIntegerParameter) => { }); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); - } + [Fact] + public async Task AddParameter_Delegate_Generics_RemoveStaticArgument() + { + var markup = """ + public class C2 + { + public delegate void D(T t); + } + + public class D2 + { + public static D2 Instance = null; + void M(D2 m) { } + + void B() + { + C2.D d = new C2.D(M); + $$d(D2.Instance); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int") + }; + var expectedUpdatedCode = """ + public class C2 + { + public delegate void D(int newIntegerParameter); + } + + public class D2 + { + public static D2 Instance = null; + void M(int newIntegerParameter) { } + + void B() + { + C2.D d = new C2.D(M); + d(12345); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Delegate_Generics_RemoveStaticArgument() - { - var markup = """ - public class C2 - { - public delegate void D(T t); - } + [Fact] + public async Task TestAddParameter_Delegates_Relaxation_ParameterlessFunctionToFunction() + { + var markup = """ + class C0 + { + delegate int $$MyFunc(int x, string y, bool z); - public class D2 + class C { - public static D2 Instance = null; - void M(D2 m) { } - - void B() + public void M() { - C2.D d = new C2.D(M); - $$d(D2.Instance); + MyFunc f = Test(); } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int") - }; - var expectedUpdatedCode = """ - public class C2 - { - public delegate void D(int newIntegerParameter); - } - - public class D2 - { - public static D2 Instance = null; - void M(int newIntegerParameter) { } - void B() + private MyFunc Test() { - C2.D d = new C2.D(M); - d(12345); + return null; } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), + new AddedParameterOrExistingIndex(1) + }; + var expectedUpdatedCode = """ + class C0 + { + delegate int MyFunc(bool z, int newIntegerParameter, string y); - [Fact] - public async Task TestAddParameter_Delegates_Relaxation_ParameterlessFunctionToFunction() - { - var markup = """ - class C0 + class C { - delegate int $$MyFunc(int x, string y, bool z); - - class C + public void M() { - public void M() - { - MyFunc f = Test(); - } - - private MyFunc Test() - { - return null; - } + MyFunc f = Test(); } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "int"), - new AddedParameterOrExistingIndex(1) - }; - var expectedUpdatedCode = """ - class C0 - { - delegate int MyFunc(bool z, int newIntegerParameter, string y); - class C + private MyFunc Test() { - public void M() - { - MyFunc f = Test(); - } - - private MyFunc Test() - { - return null; - } + return null; } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Formatting.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Formatting.cs index 4ee01d5145798..479339d579e8f 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Formatting.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.Formatting.cs @@ -13,15 +13,15 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task AddParameter_Formatting_KeepCountsPerLine() { - [Fact] - public async Task AddParameter_Formatting_KeepCountsPerLine() - { - var markup = @" + var markup = @" class C { void $$Method(int a, int b, int c, @@ -33,15 +33,15 @@ class C 4, 5, 6); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(5), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(3), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(5), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(3), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class C { void Method(int f, int e, int d, @@ -53,13 +53,13 @@ void Method(int f, int e, int d, 34, 3, 2, 1); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task AddParameter_Formatting_KeepTrivia() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task AddParameter_Formatting_KeepTrivia() + { + var markup = @" class C { void $$Method( @@ -72,14 +72,14 @@ class C 4, 5, 6); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(3), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(5)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(3), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(5)}; + var expectedUpdatedCode = @" class C { void Method( @@ -92,13 +92,13 @@ void Method( 34, 5, 6); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task AddParameter_Formatting_KeepTrivia_WithArgumentNames() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task AddParameter_Formatting_KeepTrivia_WithArgumentNames() + { + var markup = @" class C { void $$Method( @@ -111,14 +111,14 @@ class C d: 4, e: 5, f: 6); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(3), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(5)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(3), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(5)}; + var expectedUpdatedCode = @" class C { void Method( @@ -131,13 +131,13 @@ void Method( bb: 34, e: 5, f: 6); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_Method() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_Method() + { + var markup = @" class C { void $$Method(int a, @@ -147,11 +147,11 @@ class C 2); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class C { void Method(int b, @@ -161,13 +161,13 @@ void Method(int b, 34, 1); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_Constructor() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_Constructor() + { + var markup = @" class SomeClass { $$SomeClass(int a, @@ -177,11 +177,11 @@ class SomeClass 2); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class SomeClass { SomeClass(int b, @@ -191,13 +191,13 @@ class SomeClass 34, 1); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_Indexer() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_Indexer() + { + var markup = @" class SomeClass { public int $$this[int a, @@ -210,11 +210,11 @@ int b] } } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class SomeClass { public int this[int b, @@ -227,13 +227,13 @@ class SomeClass } } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_Delegate() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_Delegate() + { + var markup = @" class SomeClass { delegate void $$MyDelegate(int a, @@ -247,11 +247,11 @@ void M(int a, 2); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class SomeClass { delegate void MyDelegate(int b, @@ -265,13 +265,13 @@ void M(int b, 34, 1); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_AnonymousMethod() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_AnonymousMethod() + { + var markup = @" class SomeClass { delegate void $$MyDelegate(int a, @@ -286,11 +286,11 @@ void M() }; } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class SomeClass { delegate void MyDelegate(int b, @@ -305,13 +305,13 @@ void M() }; } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_ConstructorInitializers() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_ConstructorInitializers() + { + var markup = @" class B { public $$B(int x, int y) { } @@ -326,11 +326,11 @@ public D() : base(1, 2) { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" class B { public B(int y, byte bb, int x) { } @@ -345,175 +345,175 @@ public D() : base(2, 34, 1) { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task AddParameter_Formatting_Attribute() - { - var markup = @" + [Fact] + public async Task AddParameter_Formatting_Attribute() + { + var markup = @" [Custom(1, 2)] class CustomAttribute : System.Attribute { public $$CustomAttribute(int x, int y) { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var expectedUpdatedCode = @" [Custom(2, 34, 1)] class CustomAttribute : System.Attribute { public CustomAttribute(int y, byte bb, int x) { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task AddParameter_Formatting_Attribute_KeepTrivia() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task AddParameter_Formatting_Attribute_KeepTrivia() + { + var markup = @" [Custom( 1, 2)] class CustomAttribute : System.Attribute { public $$CustomAttribute(int x, int y) { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte") }; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte") }; + var expectedUpdatedCode = @" [Custom( 2, 34)] class CustomAttribute : System.Attribute { public CustomAttribute(int y, byte bb) { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task AddParameter_Formatting_Attribute_KeepTrivia_RemovingSecond() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task AddParameter_Formatting_Attribute_KeepTrivia_RemovingSecond() + { + var markup = @" [Custom( 1, 2)] class CustomAttribute : System.Attribute { public $$CustomAttribute(int x, int y) { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte")}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte")}; + var expectedUpdatedCode = @" [Custom( 1, 34)] class CustomAttribute : System.Attribute { public CustomAttribute(int x, byte bb) { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task AddParameter_Formatting_Attribute_KeepTrivia_RemovingBothAddingNew() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task AddParameter_Formatting_Attribute_KeepTrivia_RemovingBothAddingNew() + { + var markup = @" [Custom( 1, 2)] class CustomAttribute : System.Attribute { public $$CustomAttribute(int x, int y) { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte")}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte")}; + var expectedUpdatedCode = @" [Custom( 34)] class CustomAttribute : System.Attribute { public CustomAttribute(byte bb) { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task AddParameter_Formatting_Attribute_KeepTrivia_RemovingBeforeNewlineComma() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task AddParameter_Formatting_Attribute_KeepTrivia_RemovingBeforeNewlineComma() + { + var markup = @" [Custom(1 , 2, 3)] class CustomAttribute : System.Attribute { public $$CustomAttribute(int x, int y, int z) { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(2)}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(2)}; + var expectedUpdatedCode = @" [Custom(2, 34, 3)] class CustomAttribute : System.Attribute { public CustomAttribute(int y, byte bb, int z) { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/946220")] - public async Task AddParameter_Formatting_LambdaAsArgument() - { - var markup = @"class C + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/946220")] + public async Task AddParameter_Formatting_LambdaAsArgument() + { + var markup = @"class C { void M(System.Action f, int z$$) { M((x, y) => System.Console.WriteLine(x + y), 5); } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte")}; - var expectedUpdatedCode = @"class C + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte")}; + var expectedUpdatedCode = @"class C { void M(System.Action f, byte bb) { M((x, y) => System.Console.WriteLine(x + y), 34); } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46595")] - public async Task AddParameter_Formatting_PreserveIndentBraces() - { - var markup = + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46595")] + public async Task AddParameter_Formatting_PreserveIndentBraces() + { + var markup = @"public class C { public void M$$() { } }"; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "a", CallSiteKind.Value, "12345"), "int")}; - var expectedUpdatedCode = + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "a", CallSiteKind.Value, "12345"), "int")}; + var expectedUpdatedCode = @"public class C { public void M(int a) { } }"; - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, - options: Option(CSharpFormattingOptions2.IndentBraces, true)); - } + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, + options: Option(CSharpFormattingOptions2.IndentBraces, true)); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46595")] - public async Task AddParameter_Formatting_PreserveIndentBraces_Editorconfig() - { - var markup = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/46595")] + public async Task AddParameter_Formatting_PreserveIndentBraces_Editorconfig() + { + var markup = @" @@ -529,9 +529,9 @@ public class C "; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "a", CallSiteKind.Value, "12345"), "int")}; - var expectedUpdatedCode = @" + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "a", CallSiteKind.Value, "12345"), "int")}; + var expectedUpdatedCode = @" public class C { public void M(int a) @@ -540,7 +540,6 @@ public void M(int a) } "; - await TestChangeSignatureViaCommandAsync("XML", markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + await TestChangeSignatureViaCommandAsync("XML", markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Infer.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Infer.cs index e99d7548855bf..c6f51f60f4565 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Infer.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Infer.cs @@ -9,253 +9,251 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_NoOptions() { - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_NoOptions() - { - var markup = """ - class C + var markup = """ + class C + { + void M$$() { - void M$$() - { - M(); - } + M(); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + void M(int a) { - void M(int a) - { - M(TODO); - } + M(TODO); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_SingleLocal() - { - var markup = """ - class C + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_SingleLocal() + { + var markup = """ + class C + { + void M$$() { - void M$$() - { - int x = 7; - M(); - } + int x = 7; + M(); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + void M(int a) { - void M(int a) - { - int x = 7; - M(x); - } + int x = 7; + M(x); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_NotOnInaccessibleLocal() - { - var markup = """ - class C + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_NotOnInaccessibleLocal() + { + var markup = """ + class C + { + void M$$() { - void M$$() - { - M(); - int x = 7; - } + M(); + int x = 7; } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + void M(int a) { - void M(int a) - { - M(TODO); - int x = 7; - } + M(TODO); + int x = 7; } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_MultipleLocals() - { - var markup = """ - class C + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_MultipleLocals() + { + var markup = """ + class C + { + void M$$() { - void M$$() - { - int x = 7; - int y = 8; - M(); - } + int x = 7; + int y = 8; + M(); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + void M(int a) { - void M(int a) - { - int x = 7; - int y = 8; - M(y); - } + int x = 7; + int y = 8; + M(y); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_SingleParameter() - { - var markup = """ - class C + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_SingleParameter() + { + var markup = """ + class C + { + void M$$(int x) { - void M$$(int x) - { - M(1); - } + M(1); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + void M(int x, int a) { - void M(int x, int a) - { - M(1, x); - } + M(1, x); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_SingleField() - { - var markup = """ - class C - { - int x = 8; + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_SingleField() + { + var markup = """ + class C + { + int x = 8; - void M$$() - { - M(); - } - } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + void M$$() { - int x = 8; + M(); + } + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + int x = 8; - void M(int a) - { - M(x); - } + void M(int a) + { + M(x); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_SingleProperty() - { - var markup = """ - class C - { - int X { get; set; } + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_SingleProperty() + { + var markup = """ + class C + { + int X { get; set; } - void M$$() - { - M(); - } - } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; - var updatedCode = """ - class C + void M$$() { - int X { get; set; } + M(); + } + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Inferred) }; + var updatedCode = """ + class C + { + int X { get; set; } - void M(int a) - { - M(X); - } + void M(int a) + { + M(X); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddOptionalParameter_CallsiteInferred_ImplicitlyConvertable() - { - var markup = """ - class B { } - class D : B { } + [Fact] + public async Task AddOptionalParameter_CallsiteInferred_ImplicitlyConvertable() + { + var markup = """ + class B { } + class D : B { } - class C + class C + { + void M$$() { - void M$$() - { - D d = null; - M(); - } + D d = null; + M(); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("B", "b", CallSiteKind.Inferred) }; - var updatedCode = """ - class B { } - class D : B { } + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("B", "b", CallSiteKind.Inferred) }; + var updatedCode = """ + class B { } + class D : B { } - class C + class C + { + void M(B b) { - void M(B b) - { - D d = null; - M(d); - } + D d = null; + M(d); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Omit.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Omit.cs index 3b4207da9baea..632c1a781213c 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Omit.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.Omit.cs @@ -12,160 +12,159 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [WpfFact] + public async Task AddOptionalParameter_ToEmptySignature_CallsiteOmitted() { - [WpfFact] - public async Task AddOptionalParameter_ToEmptySignature_CallsiteOmitted() - { - var markup = """ - class C + var markup = """ + class C + { + void M$$() { - void M$$() - { - M(); - } + M(); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1") }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1") }; + var updatedCode = """ + class C + { + void M(int a = 1) { - void M(int a = 1) - { - M(); - } + M(); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [WpfFact] - public async Task AddOptionalParameter_AfterRequiredParameter_CallsiteOmitted() - { - var markup = """ - class C + [WpfFact] + public async Task AddOptionalParameter_AfterRequiredParameter_CallsiteOmitted() + { + var markup = """ + class C + { + void M$$(int x) { - void M$$(int x) - { - M(1); - } + M(1); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1") }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1") }; + var updatedCode = """ + class C + { + void M(int x, int a = 1) { - void M(int x, int a = 1) - { - M(1); - } + M(1); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [WpfFact] - public async Task AddOptionalParameter_BeforeOptionalParameter_CallsiteOmitted() - { - var markup = """ - class C + [WpfFact] + public async Task AddOptionalParameter_BeforeOptionalParameter_CallsiteOmitted() + { + var markup = """ + class C + { + void M$$(int x = 2) { - void M$$(int x = 2) - { - M() - M(2); - M(x: 2); - } + M() + M(2); + M(x: 2); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1"), - new AddedParameterOrExistingIndex(0) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1"), + new AddedParameterOrExistingIndex(0) }; + var updatedCode = """ + class C + { + void M(int a = 1, int x = 2) { - void M(int a = 1, int x = 2) - { - M() - M(x: 2); - M(x: 2); - } + M() + M(x: 2); + M(x: 2); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [WpfFact] - public async Task AddOptionalParameter_BeforeExpandedParamsArray_CallsiteOmitted() - { - var markup = """ - class C + [WpfFact] + public async Task AddOptionalParameter_BeforeExpandedParamsArray_CallsiteOmitted() + { + var markup = """ + class C + { + void M$$(params int[] p) { - void M$$(params int[] p) - { - M(); - M(1); - M(1, 2); - M(1, 2, 3); - } + M(); + M(1); + M(1, 2); + M(1, 2, 3); } - """; - var updatedSignature = new[] { - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1"), - new AddedParameterOrExistingIndex(0) }; - var updatedCode = """ - class C + } + """; + var updatedSignature = new[] { + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "a", CallSiteKind.Omitted, isRequired: false, defaultValue: "1"), + new AddedParameterOrExistingIndex(0) }; + var updatedCode = """ + class C + { + void M(int a = 1, params int[] p) { - void M(int a = 1, params int[] p) - { - M(); - M(p: new int[] { 1 }); - M(p: new int[] { 1, 2 }); - M(p: new int[] { 1, 2, 3 }); - } + M(); + M(p: new int[] { 1 }); + M(p: new int[] { 1, 2 }); + M(p: new int[] { 1, 2, 3 }); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [WpfFact] - public async Task AddOptionalParameterWithOmittedCallsiteToAttributeConstructor() - { - var markup = """ - [Some(1, 2, 4)] - class SomeAttribute : System.Attribute + [WpfFact] + public async Task AddOptionalParameterWithOmittedCallsiteToAttributeConstructor() + { + var markup = """ + [Some(1, 2, 4)] + class SomeAttribute : System.Attribute + { + public SomeAttribute$$(int a, int b, int y = 4) { - public SomeAttribute$$(int a, int b, int y = 4) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(1), - AddedParameterOrExistingIndex.CreateAdded("int", "x", CallSiteKind.Omitted, isRequired: false, defaultValue: "3"), - new AddedParameterOrExistingIndex(2)}; - var updatedCode = """ - [Some(1, 2, y: 4)] - class SomeAttribute : System.Attribute + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(1), + AddedParameterOrExistingIndex.CreateAdded("int", "x", CallSiteKind.Omitted, isRequired: false, defaultValue: "3"), + new AddedParameterOrExistingIndex(2)}; + var updatedCode = """ + [Some(1, 2, y: 4)] + class SomeAttribute : System.Attribute + { + public SomeAttribute(int a, int b, int x = 3, int y = 4) { - public SomeAttribute(int a, int b, int x = 3, int y = 4) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.SymbolKinds.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.SymbolKinds.cs index f12de90c83934..20d380cb285a4 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.SymbolKinds.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.OptionalParameter.SymbolKinds.cs @@ -12,156 +12,155 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [WpfFact] + public async Task AddOptionalParameter_ToConstructor() { - [WpfFact] - public async Task AddOptionalParameter_ToConstructor() - { - var markup = """ - class B - { - public B() : this(1) { } - public B$$(int a) - { - var q = new B(1); - } - } - - class D : B + var markup = """ + class B + { + public B() : this(1) { } + public B$$(int a) { - public D() : base(1) { } + var q = new B(1); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; - var updatedCode = """ - class B - { - public B() : this(1, 100, z: 102) { } - public B(int a, int x = 10, int y = 11, int z = 12) - { - var q = new B(1, 100, z: 102); - } - } - - class D : B + } + + class D : B + { + public D() : base(1) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; + var updatedCode = """ + class B + { + public B() : this(1, 100, z: 102) { } + public B(int a, int x = 10, int y = 11, int z = 12) { - public D() : base(1, 100, z: 102) { } + var q = new B(1, 100, z: 102); } - """; + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + class D : B + { + public D() : base(1, 100, z: 102) { } + } + """; - [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44126")] - public async Task AddOptionalParameter_ToConstructor_ImplicitObjectCreation() - { - var markup = """ - class B - { - public B() : this(1) { } - public B$$(int a) - { - B q = new(1); - } - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class D : B + [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/44126")] + public async Task AddOptionalParameter_ToConstructor_ImplicitObjectCreation() + { + var markup = """ + class B + { + public B() : this(1) { } + public B$$(int a) { - public D() : base(1) { } + B q = new(1); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; - var updatedCode = """ - class B + } + + class D : B + { + public D() : base(1) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; + var updatedCode = """ + class B + { + public B() : this(1, 100, z: 102) { } + public B(int a, int x = 10, int y = 11, int z = 12) { - public B() : this(1, 100, z: 102) { } - public B(int a, int x = 10, int y = 11, int z = 12) - { - B q = new(1, 100, z: 102); - } + B q = new(1, 100, z: 102); } + } - class D : B - { - public D() : base(1, 100, z: 102) { } - } - """; + class D : B + { + public D() : base(1, 100, z: 102) { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [WpfFact] - public async Task AddOptionalParameter_ToIndexer() - { - var markup = """ - class B - { - public int this$$[int a] { get { return 5; } } - - public void M() - { - var d = this[1]; - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; - var updatedCode = """ - class B - { - public int this[int a, int x = 10, int y = 11, int z = 12] { get { return 5; } } - - public void M() - { - var d = this[1, 100, z: 102]; - } - } - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [WpfFact] + public async Task AddOptionalParameter_ToIndexer() + { + var markup = """ + class B + { + public int this$$[int a] { get { return 5; } } - [WpfFact] - public async Task AddOptionalParameter_ToAttribute() - { - var markup = """ - [My(1)] - class MyAttribute : System.Attribute + public void M() { - public MyAttribute($$int a) { } + var d = this[1]; } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), - AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; - - // TODO: The = in the attribute is a bug. You cannot specify that the attribute should use : instead in the SyntaxGenerator - // https://github.com/dotnet/roslyn/issues/43354 - var updatedCode = """ - [My(1, 100, z = 102)] - class MyAttribute : System.Attribute + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; + var updatedCode = """ + class B + { + public int this[int a, int x = 10, int y = 11, int z = 12] { get { return 5; } } + + public void M() { - public MyAttribute(int a, int x = 10, int y = 11, int z = 12) { } + var d = this[1, 100, z: 102]; } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [WpfFact] + public async Task AddOptionalParameter_ToAttribute() + { + var markup = """ + [My(1)] + class MyAttribute : System.Attribute + { + public MyAttribute($$int a) { } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "x", CallSiteKind.Value, callSiteValue: "100", isRequired: false, defaultValue: "10"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "y", CallSiteKind.Omitted, isRequired: false, defaultValue: "11"), + AddedParameterOrExistingIndex.CreateAdded("System.Int32", "z", CallSiteKind.Value, callSiteValue: "102", isRequired: false, defaultValue: "12")}; + + // TODO: The = in the attribute is a bug. You cannot specify that the attribute should use : instead in the SyntaxGenerator + // https://github.com/dotnet/roslyn/issues/43354 + var updatedCode = """ + [My(1, 100, z = 102)] + class MyAttribute : System.Attribute + { + public MyAttribute(int a, int x = 10, int y = 11, int z = 12) { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs index 26cacb7863980..1c1bfe587e30b 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs @@ -12,1418 +12,1417 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task AddParameters() { - [Fact] - public async Task AddParameters() - { - var markup = """ - static class Ext - { - /// - /// This is a summary of - /// - /// - /// - /// - /// - /// - /// - /// - static void $$M(this object o, int a, string b, bool c, int x = 0, string y = "Zero", params int[] p) - { - object t = new object(); - - M(t, 1, "two", true, 3, "four", new[] { 5, 6 }); - M(t, 1, "two", true, 3, "four", 5, 6); - t.M(1, "two", true, 3, "four", new[] { 5, 6 }); - t.M(1, "two", true, 3, "four", 5, 6); - - M(t, 1, "two", true, 3, "four"); - M(t, 1, "two", true, 3); - M(t, 1, "two", true); - - M(t, 1, "two", c: true); - M(t, 1, "two", true, 3, y: "four"); - - M(t, 1, "two", true, 3, p: new[] { 5 }); - M(t, 1, "two", true, p: new[] { 5 }); - M(t, 1, "two", true, y: "four"); - M(t, 1, "two", true, x: 3); - - M(t, 1, "two", true, y: "four", x: 3); - M(t, 1, y: "four", x: 3, b: "two", c: true); - M(t, y: "four", x: 3, c: true, b: "two", a: 1); - M(t, p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1); - M(p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1, o: t); - } - } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "System.Int32"), - new AddedParameterOrExistingIndex(new AddedParameter(null, "string", "newString", CallSiteKind.Value, ""), "System.String"), - new AddedParameterOrExistingIndex(5)}; - var updatedCode = """ - static class Ext - { - /// - /// This is a summary of - /// - /// - /// - /// - /// - /// - /// - /// - static void M(this object o, string b, int newIntegerParameter, string newString, string y = "Zero") - { - object t = new object(); - - M(t, "two", 12345, , "four"); - M(t, "two", 12345, , "four"); - t.M("two", 12345, , "four"); - t.M("two", 12345, , "four"); - - M(t, "two", 12345, , "four"); - M(t, "two", 12345, ); - M(t, "two", 12345, ); - - M(t, "two", 12345, ); - M(t, "two", 12345, , y: "four"); - - M(t, "two", 12345, ); - M(t, "two", 12345, ); - M(t, "two", 12345, , y: "four"); - M(t, "two", 12345, ); - - M(t, "two", 12345, , y: "four"); - M(t, y: "four", newIntegerParameter: 12345, newString:, b: "two"); - M(t, y: "four", newIntegerParameter: 12345, newString:, b: "two"); - M(t, y: "four", newIntegerParameter: 12345, newString:, b: "two"); - M(y: "four", b: "two", newIntegerParameter: 12345, newString:, o: t); - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + var markup = """ + static class Ext + { + /// + /// This is a summary of + /// + /// + /// + /// + /// + /// + /// + /// + static void $$M(this object o, int a, string b, bool c, int x = 0, string y = "Zero", params int[] p) + { + object t = new object(); + + M(t, 1, "two", true, 3, "four", new[] { 5, 6 }); + M(t, 1, "two", true, 3, "four", 5, 6); + t.M(1, "two", true, 3, "four", new[] { 5, 6 }); + t.M(1, "two", true, 3, "four", 5, 6); + + M(t, 1, "two", true, 3, "four"); + M(t, 1, "two", true, 3); + M(t, 1, "two", true); + + M(t, 1, "two", c: true); + M(t, 1, "two", true, 3, y: "four"); + + M(t, 1, "two", true, 3, p: new[] { 5 }); + M(t, 1, "two", true, p: new[] { 5 }); + M(t, 1, "two", true, y: "four"); + M(t, 1, "two", true, x: 3); + + M(t, 1, "two", true, y: "four", x: 3); + M(t, 1, y: "four", x: 3, b: "two", c: true); + M(t, y: "four", x: 3, c: true, b: "two", a: 1); + M(t, p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1); + M(p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1, o: t); + } + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "System.Int32"), + new AddedParameterOrExistingIndex(new AddedParameter(null, "string", "newString", CallSiteKind.Value, ""), "System.String"), + new AddedParameterOrExistingIndex(5)}; + var updatedCode = """ + static class Ext + { + /// + /// This is a summary of + /// + /// + /// + /// + /// + /// + /// + /// + static void M(this object o, string b, int newIntegerParameter, string newString, string y = "Zero") + { + object t = new object(); + + M(t, "two", 12345, , "four"); + M(t, "two", 12345, , "four"); + t.M("two", 12345, , "four"); + t.M("two", 12345, , "four"); + + M(t, "two", 12345, , "four"); + M(t, "two", 12345, ); + M(t, "two", 12345, ); + + M(t, "two", 12345, ); + M(t, "two", 12345, , y: "four"); + + M(t, "two", 12345, ); + M(t, "two", 12345, ); + M(t, "two", 12345, , y: "four"); + M(t, "two", 12345, ); + + M(t, "two", 12345, , y: "four"); + M(t, y: "four", newIntegerParameter: 12345, newString:, b: "two"); + M(t, y: "four", newIntegerParameter: 12345, newString:, b: "two"); + M(t, y: "four", newIntegerParameter: 12345, newString:, b: "two"); + M(y: "four", b: "two", newIntegerParameter: 12345, newString:, o: t); + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddParameterToParameterlessMethod() - { - var markup = """ - static class Ext + [Fact] + public async Task AddParameterToParameterlessMethod() + { + var markup = """ + static class Ext + { + static void $$M() { - static void $$M() - { - M(); - } + M(); } - """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "System.Int32")}; - var updatedCode = """ - static class Ext + } + """; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, "12345"), "System.Int32")}; + var updatedCode = """ + static class Ext + { + static void M(int newIntegerParameter) { - static void M(int newIntegerParameter) - { - M(12345); - } + M(12345); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderLocalFunctionParametersAndArguments_OnDeclaration() - { - var markup = """ - using System; - class MyClass + [Fact] + public async Task AddAndReorderLocalFunctionParametersAndArguments_OnDeclaration() + { + var markup = """ + using System; + class MyClass + { + public void M() { - public void M() + Goo(1, 2); + void $$Goo(int x, string y) { - Goo(1, 2); - void $$Goo(int x, string y) - { - } } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; + class MyClass + { + public void M() { - public void M() + Goo(2, 34, 1); + void Goo(string y, byte b, int x) { - Goo(2, 34, 1); - void Goo(string y, byte b, int x) - { - } } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderLocalFunctionParametersAndArguments_OnInvocation() - { - var markup = """ - using System; - class MyClass + [Fact] + public async Task AddAndReorderLocalFunctionParametersAndArguments_OnInvocation() + { + var markup = """ + using System; + class MyClass + { + public void M() { - public void M() + $$Goo(1, null); + void Goo(int x, string y) { - $$Goo(1, null); - void Goo(int x, string y) - { - } } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; + class MyClass + { + public void M() { - public void M() + Goo(null, 34, 1); + void Goo(string y, byte b, int x) { - Goo(null, 34, 1); - void Goo(string y, byte b, int x) - { - } } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderMethodParameters() - { - var markup = """ - using System; - class MyClass - { - public void $$Goo(int x, string y) - { - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class MyClass + [Fact] + public async Task AddAndReorderMethodParameters() + { + var markup = """ + using System; + class MyClass + { + public void $$Goo(int x, string y) + { + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, byte b, int x) { - public void Goo(string y, byte b, int x) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderMethodParametersAndArguments() - { - var markup = """ - using System; - class MyClass - { - public void $$Goo(int x, string y) - { - Goo(3, "hello"); - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class MyClass + [Fact] + public async Task AddAndReorderMethodParametersAndArguments() + { + var markup = """ + using System; + class MyClass + { + public void $$Goo(int x, string y) + { + Goo(3, "hello"); + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, byte b, int x) { - public void Goo(string y, byte b, int x) - { - Goo("hello", 34, 3); - } + Goo("hello", 34, 3); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderMethodParametersAndArgumentsOfNestedCalls() - { - var markup = """ - using System; - class MyClass - { - public int $$Goo(int x, string y) - { - return Goo(Goo(4, "inner"), "outer"); - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class MyClass + [Fact] + public async Task AddAndReorderMethodParametersAndArgumentsOfNestedCalls() + { + var markup = """ + using System; + class MyClass + { + public int $$Goo(int x, string y) + { + return Goo(Goo(4, "inner"), "outer"); + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; + class MyClass + { + public int Goo(string y, byte b, int x) { - public int Goo(string y, byte b, int x) - { - return Goo("outer", 34, Goo("inner", 34, 4)); - } + return Goo("outer", 34, Goo("inner", 34, 4)); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderConstructorParametersAndArguments() - { - var markup = """ - using System; + [Fact] + public async Task AddAndReorderConstructorParametersAndArguments() + { + var markup = """ + using System; - class MyClass2 : MyClass + class MyClass2 : MyClass + { + public MyClass2() : base(5, "test2") { - public MyClass2() : base(5, "test2") - { - } } + } - class MyClass + class MyClass + { + public MyClass() : this(2, "test") { - public MyClass() : this(2, "test") - { - } - - public $$MyClass(int x, string y) - { - var t = new MyClass(x, y); - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - AddedParameterOrExistingIndex.CreateAdded("byte", "b", CallSiteKind.Value, "34"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class MyClass2 : MyClass + public $$MyClass(int x, string y) { - public MyClass2() : base("test2", 34, 5) - { - } + var t = new MyClass(x, y); } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + AddedParameterOrExistingIndex.CreateAdded("byte", "b", CallSiteKind.Value, "34"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; - class MyClass + class MyClass2 : MyClass + { + public MyClass2() : base("test2", 34, 5) { - public MyClass() : this("test", 34, 2) - { - } - - public MyClass(string y, byte b, int x) - { - var t = new MyClass(y, 34, x); - } } - """; + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddAndReorderAttributeConstructorParametersAndArguments() - { - var markup = """ - [My("test", 8)] - class MyClass + class MyClass + { + public MyClass() : this("test", 34, 2) { } - class MyAttribute : System.Attribute - { - public MyAttribute(string x, int y)$$ - { - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - [My(8, 34, "test")] - class MyClass + public MyClass(string y, byte b, int x) { + var t = new MyClass(y, 34, x); } + } + """; - class MyAttribute : System.Attribute - { - public MyAttribute(int y, byte b, string x) - { - } - } - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task AddAndReorderAttributeConstructorParametersAndArguments() + { + var markup = """ + [My("test", 8)] + class MyClass + { + } - [Fact] - public async Task AddAndReorderExtensionMethodParametersAndArguments_StaticCall() - { - var markup = """ - public class C - { - static void Main(string[] args) - { - CExt.M(new C(), 1, 2, "three", "four", "five"); - } - } + class MyAttribute : System.Attribute + { + public MyAttribute(string x, int y)$$ + { + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + [My(8, 34, "test")] + class MyClass + { + } - public static class CExt + class MyAttribute : System.Attribute + { + public MyAttribute(int y, byte b, string x) { - public static void M(this $$C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c") - { } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(5), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(3)}; + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - var updatedCode = """ - public class C + [Fact] + public async Task AddAndReorderExtensionMethodParametersAndArguments_StaticCall() + { + var markup = """ + public class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - CExt.M(new C(), 2, 1, 34, "five", "four", "three"); - } + CExt.M(new C(), 1, 2, "three", "four", "five"); } + } - public static class CExt + public static class CExt + { + public static void M(this $$C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c") + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(5), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(3)}; + + var updatedCode = """ + public class C + { + static void Main(string[] args) { - public static void M(this C goo, int y, int x, byte b, string c = "test_c", string b = "test_b", string a = "test_a") - { } + CExt.M(new C(), 2, 1, 34, "five", "four", "three"); } - """; + } - // Although the `ParameterConfig` has 0 for the `SelectedIndex`, the UI dialog will make an adjustment - // and select parameter `y` instead because the `this` parameter cannot be moved or removed. - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } + public static class CExt + { + public static void M(this C goo, int y, int x, byte b, string c = "test_c", string b = "test_b", string a = "test_a") + { } + } + """; + + // Although the `ParameterConfig` has 0 for the `SelectedIndex`, the UI dialog will make an adjustment + // and select parameter `y` instead because the `this` parameter cannot be moved or removed. + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } - [Fact] - public async Task AddAndReorderExtensionMethodParametersAndArguments_ExtensionCall() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderExtensionMethodParametersAndArguments_ExtensionCall() + { + var markup = """ + public class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - new C().M(1, 2, "three", "four", "five"); - } + new C().M(1, 2, "three", "four", "five"); } + } - public static class CExt - { - public static void M(this C goo, int x$$, int y, string a = "test_a", string b = "test_b", string c = "test_c") - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(5), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(3)}; - var updatedCode = """ - public class C + public static class CExt + { + public static void M(this C goo, int x$$, int y, string a = "test_a", string b = "test_b", string c = "test_c") + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(5), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(3)}; + var updatedCode = """ + public class C + { + static void Main(string[] args) { - static void Main(string[] args) - { - new C().M(2, 1, 34, "five", "four", "three"); - } + new C().M(2, 1, 34, "five", "four", "three"); } + } - public static class CExt - { - public static void M(this C goo, int y, int x, byte b, string c = "test_c", string b = "test_b", string a = "test_a") - { } - } - """; + public static class CExt + { + public static void M(this C goo, int y, int x, byte b, string c = "test_c", string b = "test_b", string a = "test_a") + { } + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); + } - [Fact] - public async Task AddParameterWithOmittedArgument_ParamsAsArray() - { - var markup = """ - public class C + [Fact] + public async Task AddParameterWithOmittedArgument_ParamsAsArray() + { + var markup = """ + public class C + { + void $$M(int x, int y, params int[] p) + { + M(x, y, p: p); + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(1), + AddedParameterOrExistingIndex.CreateAdded("int", "z", CallSiteKind.Omitted, isRequired: false, defaultValue: "3"), + new AddedParameterOrExistingIndex(2)}; + var updatedCode = """ + public class C + { + void M(int x, int y, int z = 3, params int[] p) { - void $$M(int x, int y, params int[] p) - { - M(x, y, p: p); - } + M(x, y, p: p); } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(1), - AddedParameterOrExistingIndex.CreateAdded("int", "z", CallSiteKind.Omitted, isRequired: false, defaultValue: "3"), - new AddedParameterOrExistingIndex(2)}; - var updatedCode = """ - public class C + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task AddAndReorderParamsMethodParametersAndArguments_ParamsAsArray() + { + var markup = """ + public class C + { + void $$M(int x, int y, params int[] p) + { + M(x, y, new[] { 1, 2, 3 }); + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(2)}; + var updatedCode = """ + public class C + { + void M(int y, int x, byte b, params int[] p) { - void M(int x, int y, int z = 3, params int[] p) - { - M(x, y, p: p); - } + M(y, x, 34, new[] { 1, 2, 3 }); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamsMethodParametersAndArguments_ParamsAsArray() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamsMethodParametersAndArguments_ParamsExpanded() + { + var markup = """ + public class C + { + void $$M(int x, int y, params int[] p) { - void $$M(int x, int y, params int[] p) - { - M(x, y, new[] { 1, 2, 3 }); - } + M(x, y, 1, 2, 3); } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(2)}; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(2)}; + + var updatedCode = """ + public class C + { + void M(int y, int x, byte b, params int[] p) { - void M(int y, int x, byte b, params int[] p) - { - M(y, x, 34, new[] { 1, 2, 3 }); - } + M(y, x, 34, 1, 2, 3); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamsMethodParametersAndArguments_ParamsExpanded() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderExtensionAndParamsMethodParametersAndArguments_VariedCallsites() + { + var markup = """ + public class C + { + static void Main(string[] args) { - void $$M(int x, int y, params int[] p) - { - M(x, y, 1, 2, 3); - } + CExt.M(new C(), 1, 2, "three", "four", "five", new[] { 6, 7, 8 }); + CExt.M(new C(), 1, 2, "three", "four", "five", 6, 7, 8); + new C().M(1, 2, "three", "four", "five", new[] { 6, 7, 8 }); + new C().M(1, 2, "three", "four", "five", 6, 7, 8); } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(2)}; + } - var updatedCode = """ - public class C + public static class CExt + { + public static void $$M(this C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c", params int[] p) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(5), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(3), + new AddedParameterOrExistingIndex(6)}; + var updatedCode = """ + public class C + { + static void Main(string[] args) { - void M(int y, int x, byte b, params int[] p) - { - M(y, x, 34, 1, 2, 3); - } + CExt.M(new C(), 2, 1, 34, "five", "four", "three", new[] { 6, 7, 8 }); + CExt.M(new C(), 2, 1, 34, "five", "four", "three", 6, 7, 8); + new C().M(2, 1, 34, "five", "four", "three", new[] { 6, 7, 8 }); + new C().M(2, 1, 34, "five", "four", "three", 6, 7, 8); } - """; + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + public static class CExt + { + public static void M(this C goo, int y, int x, byte b, string c = "test_c", string b = "test_b", string a = "test_a", params int[] p) + { } + } + """; - [Fact] - public async Task AddAndReorderExtensionAndParamsMethodParametersAndArguments_VariedCallsites() - { - var markup = """ - public class C + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } + + [Fact] + public async Task AddAndReorderIndexerParametersAndArguments() + { + var markup = """ + class Program + { + void M() { - static void Main(string[] args) - { - CExt.M(new C(), 1, 2, "three", "four", "five", new[] { 6, 7, 8 }); - CExt.M(new C(), 1, 2, "three", "four", "five", 6, 7, 8); - new C().M(1, 2, "three", "four", "five", new[] { 6, 7, 8 }); - new C().M(1, 2, "three", "four", "five", 6, 7, 8); - } + var x = new Program()[1, 2]; + new Program()[1, 2] = x; } - public static class CExt + public int this[int x, int y]$$ { - public static void $$M(this C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c", params int[] p) - { } + get { return 5; } + set { } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(5), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(3), - new AddedParameterOrExistingIndex(6)}; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + class Program + { + void M() { - static void Main(string[] args) - { - CExt.M(new C(), 2, 1, 34, "five", "four", "three", new[] { 6, 7, 8 }); - CExt.M(new C(), 2, 1, 34, "five", "four", "three", 6, 7, 8); - new C().M(2, 1, 34, "five", "four", "three", new[] { 6, 7, 8 }); - new C().M(2, 1, 34, "five", "four", "three", 6, 7, 8); - } + var x = new Program()[2, 34, 1]; + new Program()[2, 34, 1] = x; } - public static class CExt + public int this[int y, byte b, int x] { - public static void M(this C goo, int y, int x, byte b, string c = "test_c", string b = "test_b", string a = "test_a", params int[] p) - { } + get { return 5; } + set { } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } + } + """; - [Fact] - public async Task AddAndReorderIndexerParametersAndArguments() - { - var markup = """ - class Program - { - void M() - { - var x = new Program()[1, 2]; - new Program()[1, 2] = x; - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - public int this[int x, int y]$$ - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - class Program + [Fact] + public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_OnIndividualLines() + { + var markup = """ + public class C + { + /// + /// + /// + void $$Goo(int a, int b, int c) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + /// + /// + void Goo(int c, int b, byte bb, int a) { - void M() - { - var x = new Program()[2, 34, 1]; - new Program()[2, 34, 1] = x; - } - public int this[int y, byte b, int x] - { - get { return 5; } - set { } - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_OnIndividualLines() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_OnSameLine() + { + var markup = """ + public class C + { + /// a is funb is func is fun + void $$Goo(int a, int b, int c) { - /// - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - /// - /// - void Goo(int c, int b, byte bb, int a) - { - - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_OnSameLine() - { - var markup = """ - public class C + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// c is funb is fun + /// a is fun + void Goo(int c, int b, byte bb, int a) { - /// a is funb is func is fun - void $$Goo(int a, int b, int c) - { - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// c is funb is fun - /// a is fun - void Goo(int c, int b, byte bb, int a) - { - - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_MixedLineDistribution() - { - var markup = """ - public class C - { - /// - /// - /// - /// Comments spread - /// over several - /// lines - void $$Goo(int a, int b, int c, int d, int e, int f) - { + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(5), - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(3), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// Comments spread - /// over several - /// lines - /// - /// - /// - /// - void Goo(int f, int e, int d, int c, byte bb, int b, int a) - { + [Fact] + public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_MixedLineDistribution() + { + var markup = """ + public class C + { + /// + /// + /// + /// Comments spread + /// over several + /// lines + void $$Goo(int a, int b, int c, int d, int e, int f) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(5), + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(3), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// Comments spread + /// over several + /// lines + /// + /// + /// + /// + void Goo(int f, int e, int d, int c, byte bb, int b, int a) + { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_MixedWithRegularComments() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamTagsInDocComments_SingleLineDocComments_MixedWithRegularComments() + { + var markup = """ + public class C + { + /// + // Why is there a regular comment here? + /// + void $$Goo(int a, int b, int c, int d, int e) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(4), + new AddedParameterOrExistingIndex(3), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + // Why is there a regular comment here? + /// + /// + void Goo(int e, int d, int c, byte b, int b, int a) { - /// - // Why is there a regular comment here? - /// - void $$Goo(int a, int b, int c, int d, int e) - { - - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(4), - new AddedParameterOrExistingIndex(3), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - // Why is there a regular comment here? - /// - /// - void Goo(int e, int d, int c, byte b, int b, int a) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_MultiLineDocComments_OnSeparateLines1() - { - var markup = """ - class Program + [Fact] + public async Task AddAndReorderParamTagsInDocComments_MultiLineDocComments_OnSeparateLines1() + { + var markup = """ + class Program + { + /** + * x! + * y! + * z! + */ + static void $$M(int x, int y, int z) + { + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + class Program + { + /** + * z! + * + * y! + */ + /// x! + static void M(int z, byte b, int y, int x) { - /** - * x! - * y! - * z! - */ - static void $$M(int x, int y, int z) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - class Program - { - /** - * z! - * - * y! - */ - /// x! - static void M(int z, byte b, int y, int x) - { - } - } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_MultiLineDocComments_OnSingleLine() - { - var markup = """ - class Program + [Fact] + public async Task AddAndReorderParamTagsInDocComments_MultiLineDocComments_OnSingleLine() + { + var markup = """ + class Program + { + /** x!y!z! */ + static void $$M(int x, int y, int z) + { + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + class Program + { + /** z!y! */ + /// x! + static void M(int z, byte b, int y, int x) { - /** x!y!z! */ - static void $$M(int x, int y, int z) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - class Program - { - /** z!y! */ - /// x! - static void M(int z, byte b, int y, int x) - { - } - } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_IncorrectOrder_MaintainsOrder() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamTagsInDocComments_IncorrectOrder_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + /// + void $$Goo(int a, int b, int c) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + /// + void Goo(int c, byte bb, int b, int a) { - /// - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - /// - void Goo(int c, byte bb, int b, int a) - { - - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_WrongNames_MaintainsOrder() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamTagsInDocComments_WrongNames_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + /// + void $$Goo(int a, int b, int c) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + /// + void Goo(int c, byte b, int b, int a) { - /// - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - /// - void Goo(int c, byte b, int b, int a) - { - - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_InsufficientTags_MaintainsOrder() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamTagsInDocComments_InsufficientTags_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + void $$Goo(int a, int b, int c) { - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - void Goo(int c, byte b, int b, int a) - { + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + void Goo(int c, byte b, int b, int a) + { - } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddAndReorderParamTagsInDocComments_ExcessiveTags_MaintainsOrder() - { - var markup = """ - public class C - { - /// - /// - /// - /// - void $$Goo(int a, int b, int c) - { + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - /// - /// - void Goo(int c, byte bb, int b, int a) - { + [Fact] + public async Task AddAndReorderParamTagsInDocComments_ExcessiveTags_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + /// + /// + void $$Goo(int a, int b, int c) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + /// + /// + void Goo(int c, byte bb, int b, int a) + { - } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_OnConstructors() - { - var markup = """ - public class C + [Fact] + public async Task AddAndReorderParamTagsInDocComments_OnConstructors() + { + var markup = """ + public class C + { + /// + /// + /// + public $$C(int a, int b, int c) + { + + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + /// + /// + public C(int c, byte bb, int b, int a) { - /// - /// - /// - public $$C(int a, int b, int c) - { - } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - /// - /// - public C(int c, byte bb, int b, int a) - { + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task AddAndReorderParamTagsInDocComments_OnIndexers() + { + var markup = """ + public class C + { + /// + /// + /// + public int $$this[int a, int b, int c] + { + get { return 5; } + set { } + } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + public class C + { + /// + /// + /// + /// + public int this[int c, byte bb, int b, int a] + { + get { return 5; } + set { } + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParamTagsInDocComments_OnIndexers() - { - var markup = """ - public class C - { - /// - /// - /// - public int $$this[int a, int b, int c] - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "bb", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - public class C - { - /// - /// - /// - /// - public int this[int c, byte bb, int b, int a] - { - get { return 5; } - set { } - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task AddAndReorderParametersInCrefs() + { + var markup = """ + class C + { + /// + /// See and + /// + $$void M(int x, string y) + { } + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + class C + { + /// + /// See and + /// + void M(string y, byte b, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParametersInCrefs() - { - var markup = """ - class C - { - /// - /// See and - /// - $$void M(int x, string y) - { } - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - class C - { - /// - /// See and - /// - void M(string y, byte b, int x) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddAndReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType1() - { - var markup = """ - interface I - { - $$void M(int x, string y); - } + [Fact] + public async Task AddAndReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType1() + { + var markup = """ + interface I + { + $$void M(int x, string y); + } - class C + class C + { + public void M(int x, string y) { - public void M(int x, string y) - { - } } + } - class D : C, I - { - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - interface I - { - void M(string y, byte b, int x); - } + class D : C, I + { + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + interface I + { + void M(string y, byte b, int x); + } - class C + class C + { + public void M(string y, byte b, int x) { - public void M(string y, byte b, int x) - { - } } + } - class D : C, I - { - } - """; + class D : C, I + { + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task AddAndReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType2() - { - var markup = """ - interface I - { - void M(int x, string y); - } + [Fact] + public async Task AddAndReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType2() + { + var markup = """ + interface I + { + void M(int x, string y); + } - class C + class C + { + $$public void M(int x, string y) { - $$public void M(int x, string y) - { - } } + } - class D : C, I - { - } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - interface I - { - void M(string y, byte b, int x); - } + class D : C, I + { + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + interface I + { + void M(string y, byte b, int x); + } - class C + class C + { + public void M(string y, byte b, int x) { - public void M(string y, byte b, int x) - { - } } + } - class D : C, I - { - } - """; + class D : C, I + { + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43664")] - public async Task AddParameterOnUnparenthesizedLambda() - { - var markup = """ - using System.Linq; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43664")] + public async Task AddParameterOnUnparenthesizedLambda() + { + var markup = """ + using System.Linq; - namespace ConsoleApp426 + namespace ConsoleApp426 + { + class Program { - class Program + static void M(string[] args) { - static void M(string[] args) + if (args.All(b$$ => Test())) { - if (args.All(b$$ => Test())) - { - } } - - static bool Test() { return true; } } + + static bool Test() { return true; } } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(0), - AddedParameterOrExistingIndex.CreateAdded("byte", "bb", CallSiteKind.Value, callSiteValue: "34") }; + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(0), + AddedParameterOrExistingIndex.CreateAdded("byte", "bb", CallSiteKind.Value, callSiteValue: "34") }; - var updatedCode = """ - using System.Linq; + var updatedCode = """ + using System.Linq; - namespace ConsoleApp426 + namespace ConsoleApp426 + { + class Program { - class Program + static void M(string[] args) { - static void M(string[] args) + if (args.All((b, byte bb) => Test())) { - if (args.All((b, byte bb) => Test())) - { - } } - - static bool Test() { return true; } } + + static bool Test() { return true; } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44126")] - public async Task AddAndReorderImplicitObjectCreationParameter() - { - var markup = """ - using System; - class C + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44126")] + public async Task AddAndReorderImplicitObjectCreationParameter() + { + var markup = """ + using System; + class C + { + $$C(int x, string y) { - $$C(int x, string y) - { - } + } - public void M() - { - C _ = new(1, "y"); - } + public void M() + { + C _ = new(1, "y"); } - """; - var permutation = new[] { - new AddedParameterOrExistingIndex(1), - new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, callSiteValue: "34"), "byte"), - new AddedParameterOrExistingIndex(0)}; - var updatedCode = """ - using System; - class C + } + """; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", CallSiteKind.Value, callSiteValue: "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = """ + using System; + class C + { + C(string y, byte b, int x) { - C(string y, byte b, int x) - { - } + } - public void M() - { - C _ = new("y", 34, 1); - } + public void M() + { + C _ = new("y", 34, 1); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44558")] - public async Task AddParameters_Record() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44558")] + public async Task AddParameters_Record() + { + var markup = """ + /// + /// + /// + record $$R(int First, int Second, int Third) + { + static R M() => new R(1, 2, 3); + } + """; + var updatedSignature = new AddedParameterOrExistingIndex[] { - var markup = """ - /// - /// - /// - record $$R(int First, int Second, int Third) - { - static R M() => new R(1, 2, 3); - } - """; - var updatedSignature = new AddedParameterOrExistingIndex[] - { - new(0), - new(2), - new(1), - new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32") - }; - var updatedCode = """ - /// - /// - /// - /// - record R(int First, int Third, int Second, int Forth) - { - static R M() => new R(1, 3, 2, 12345); - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddParameters_PrimaryConstructor_Class() + new(0), + new(2), + new(1), + new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32") + }; + var updatedCode = """ + /// + /// + /// + /// + record R(int First, int Third, int Second, int Forth) + { + static R M() => new R(1, 3, 2, 12345); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task AddParameters_PrimaryConstructor_Class() + { + var markup = """ + /// + /// + /// + class $$R(int First, int Second, int Third) + { + static R M() => new R(1, 2, 3); + } + """; + var updatedSignature = new AddedParameterOrExistingIndex[] { - var markup = """ - /// - /// - /// - class $$R(int First, int Second, int Third) - { - static R M() => new R(1, 2, 3); - } - """; - var updatedSignature = new AddedParameterOrExistingIndex[] - { - new(0), - new(2), - new(1), - new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32") - }; - var updatedCode = """ - /// - /// - /// - /// - class R(int First, int Third, int Second, int Forth) - { - static R M() => new R(1, 3, 2, 12345); - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task AddParameters_PrimaryConstructor_Struct() + new(0), + new(2), + new(1), + new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32") + }; + var updatedCode = """ + /// + /// + /// + /// + class R(int First, int Third, int Second, int Forth) + { + static R M() => new R(1, 3, 2, 12345); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task AddParameters_PrimaryConstructor_Struct() + { + var markup = """ + /// + /// + /// + struct $$R(int First, int Second, int Third) + { + static R M() => new R(1, 2, 3); + } + """; + var updatedSignature = new AddedParameterOrExistingIndex[] { - var markup = """ - /// - /// - /// - struct $$R(int First, int Second, int Third) - { - static R M() => new R(1, 2, 3); - } - """; - var updatedSignature = new AddedParameterOrExistingIndex[] - { - new(0), - new(2), - new(1), - new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32") - }; - var updatedCode = """ - /// - /// - /// - /// - struct R(int First, int Third, int Second, int Forth) - { - static R M() => new R(1, 3, 2, 12345); - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + new(0), + new(2), + new(1), + new(new AddedParameter(null, "int", "Forth", CallSiteKind.Value, "12345"), "System.Int32") + }; + var updatedCode = """ + /// + /// + /// + /// + struct R(int First, int Third, int Second, int Forth) + { + static R M() => new R(1, 3, 2, 12345); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignatureTests.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignatureTests.cs index bb92dc075eb2f..1efd0baf65198 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignatureTests.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignatureTests.cs @@ -10,284 +10,283 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/8333")] + public async Task TestNotInExpressionBody() + { + var markup = """ + class Ext + { + void Goo(int a, int b) => [||]0; + } + """; + + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1905")] + public async Task TestAfterSemicolonForInvocationInExpressionStatement_ViaCommand() { - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/8333")] - public async Task TestNotInExpressionBody() - { - var markup = """ - class Ext + var markup = """ + class Program + { + static void Main(string[] args) { - void Goo(int a, int b) => [||]0; + M1(1, 2);$$ + M2(1, 2, 3); } - """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + static void M1(int x, int y) { } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/1905")] - public async Task TestAfterSemicolonForInvocationInExpressionStatement_ViaCommand() - { - var markup = """ - class Program + static void M2(int x, int y, int z) { } + } + """; + var expectedCode = """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - M1(1, 2);$$ - M2(1, 2, 3); - } + M1(2, 1); + M2(1, 2, 3); + } - static void M1(int x, int y) { } + static void M1(int y, int x) { } - static void M2(int x, int y, int z) { } - } - """; - var expectedCode = """ - class Program - { - static void Main(string[] args) - { - M1(2, 1); - M2(1, 2, 3); - } + static void M2(int x, int y, int z) { } + } + """; - static void M1(int y, int x) { } + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, + markup: markup, + updatedSignature: new[] { 1, 0 }, + expectedUpdatedInvocationDocumentCode: expectedCode); + } - static void M2(int x, int y, int z) { } - } - """; - - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, - markup: markup, - updatedSignature: new[] { 1, 0 }, - expectedUpdatedInvocationDocumentCode: expectedCode); - } - - [Fact] - public async Task TestOnLambdaWithTwoDiscardParameters_ViaCommand() - { - var markup = """ - class Program + [Fact] + public async Task TestOnLambdaWithTwoDiscardParameters_ViaCommand() + { + var markup = """ + class Program + { + static void M() { - static void M() - { - System.Func f = $$(int _, string _) => 1; - } + System.Func f = $$(int _, string _) => 1; } - """; - var expectedCode = """ - class Program + } + """; + var expectedCode = """ + class Program + { + static void M() { - static void M() - { - System.Func f = (string _, int _) => 1; - } + System.Func f = (string _, int _) => 1; } - """; - - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, - markup: markup, - updatedSignature: new[] { 1, 0 }, - expectedUpdatedInvocationDocumentCode: expectedCode); - } - - [Fact] - public async Task TestOnAnonymousMethodWithTwoParameters_ViaCommand() - { - var markup = """ - class Program + } + """; + + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, + markup: markup, + updatedSignature: new[] { 1, 0 }, + expectedUpdatedInvocationDocumentCode: expectedCode); + } + + [Fact] + public async Task TestOnAnonymousMethodWithTwoParameters_ViaCommand() + { + var markup = """ + class Program + { + static void M() { - static void M() - { - System.Func f = [||]delegate(int x, string y) { return 1; }; - } + System.Func f = [||]delegate(int x, string y) { return 1; }; } - """; - await TestMissingAsync(markup); - } - - [Fact] - public async Task TestOnAnonymousMethodWithTwoDiscardParameters_ViaCommand() - { - var markup = """ - class Program + } + """; + await TestMissingAsync(markup); + } + + [Fact] + public async Task TestOnAnonymousMethodWithTwoDiscardParameters_ViaCommand() + { + var markup = """ + class Program + { + static void M() { - static void M() - { - System.Func f = [||]delegate(int _, string _) { return 1; }; - } + System.Func f = [||]delegate(int _, string _) { return 1; }; } - """; - await TestMissingAsync(markup); - } - - [Fact] - public async Task TestAfterSemicolonForInvocationInExpressionStatement_ViaCodeAction() - { - var markup = """ - class Program + } + """; + await TestMissingAsync(markup); + } + + [Fact] + public async Task TestAfterSemicolonForInvocationInExpressionStatement_ViaCodeAction() + { + var markup = """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - M1(1, 2);[||] - M2(1, 2, 3); - } + M1(1, 2);[||] + M2(1, 2, 3); + } - static void M1(int x, int y) { } + static void M1(int x, int y) { } - static void M2(int x, int y, int z) { } - } - """; + static void M2(int x, int y, int z) { } + } + """; - await TestMissingAsync(markup); - } + await TestMissingAsync(markup); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingWhitespace() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingWhitespace() + { + var markup = """ + class Ext + { + [||] + void Goo(int a, int b) { - [||] - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingTrivia() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingTrivia() + { + var markup = """ + class Ext + { + // [||] + void Goo(int a, int b) { - // [||] - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingTrivia2() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingTrivia2() + { + var markup = """ + class Ext + { + [||]// + void Goo(int a, int b) { - [||]// - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingDocComment() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingDocComment() + { + var markup = """ + class Ext + { + /// [||] + void Goo(int a, int b) { - /// [||] - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingDocComment2() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingDocComment2() + { + var markup = """ + class Ext + { + [||]/// + void Goo(int a, int b) { - [||]/// - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingAttributes1() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingAttributes1() + { + var markup = """ + class Ext + { + [||][X] + void Goo(int a, int b) { - [||][X] - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingAttributes2() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingAttributes2() + { + var markup = """ + class Ext + { + [[||]X] + void Goo(int a, int b) { - [[||]X] - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInLeadingAttributes3() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInLeadingAttributes3() + { + var markup = """ + class Ext + { + [X][||] + void Goo(int a, int b) { - [X][||] - void Goo(int a, int b) - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] - public async Task TestNotInConstraints() - { - var markup = """ - class Ext + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17309")] + public async Task TestNotInConstraints() + { + var markup = """ + class Ext + { + void Goo(int a, int b) where [||]T : class { - void Goo(int a, int b) where [||]T : class - { - }; - } - """; + }; + } + """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_CheckAllSignatureChanges.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_CheckAllSignatureChanges.cs index 863abae8fd43d..33a15263d2912 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_CheckAllSignatureChanges.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_CheckAllSignatureChanges.cs @@ -8,179 +8,177 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests - { - [Theory] + [Theory] #pragma warning disable xUnit1019 - // There is a bug in xUnit analyzer might generate false alarm, temporary disable it - // https://github.com/xunit/xunit/issues/1968 - [MemberData(nameof(AbstractChangeSignatureTests.GetAllSignatureSpecificationsForTheory), new[] { 1, 3, 2, 1 }, MemberType = typeof(AbstractChangeSignatureTests))] + // There is a bug in xUnit analyzer might generate false alarm, temporary disable it + // https://github.com/xunit/xunit/issues/1968 + [MemberData(nameof(AbstractChangeSignatureTests.GetAllSignatureSpecificationsForTheory), new[] { 1, 3, 2, 1 }, MemberType = typeof(AbstractChangeSignatureTests))] #pragma warning restore xUnit1019 - public async Task TestAllSignatureChanges_1This_3Regular_2Default_1Params(int totalParameters, int[] signature) - { - var markup = """ - static class Ext + public async Task TestAllSignatureChanges_1This_3Regular_2Default_1Params(int totalParameters, int[] signature) + { + var markup = """ + static class Ext + { + /// + /// This is a summary of + /// + /// + /// + /// + /// + /// + /// + /// + static void $$M(this object o, int a, string b, bool c, int x = 0, string y = "Zero", params int[] p) { - /// - /// This is a summary of - /// - /// - /// - /// - /// - /// - /// - /// - static void $$M(this object o, int a, string b, bool c, int x = 0, string y = "Zero", params int[] p) - { - object t = new object(); - - M(t, 1, "two", true, 3, "four", new[] { 5, 6 }); - M(t, 1, "two", true, 3, "four", 5, 6); - t.M(1, "two", true, 3, "four", new[] { 5, 6 }); - t.M(1, "two", true, 3, "four", 5, 6); - - M(t, 1, "two", true, 3, "four"); - M(t, 1, "two", true, 3); - M(t, 1, "two", true); - - M(t, 1, "two", c: true); - M(t, 1, "two", true, 3, y: "four"); - - M(t, 1, "two", true, 3, p: new[] { 5 }); - M(t, 1, "two", true, p: new[] { 5 }); - M(t, 1, "two", true, y: "four"); - M(t, 1, "two", true, x: 3); - - M(t, 1, "two", true, y: "four", x: 3); - M(t, 1, y: "four", x: 3, b: "two", c: true); - M(t, y: "four", x: 3, c: true, b: "two", a: 1); - M(t, p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1); - M(p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1, o: t); - } + object t = new object(); + + M(t, 1, "two", true, 3, "four", new[] { 5, 6 }); + M(t, 1, "two", true, 3, "four", 5, 6); + t.M(1, "two", true, 3, "four", new[] { 5, 6 }); + t.M(1, "two", true, 3, "four", 5, 6); + + M(t, 1, "two", true, 3, "four"); + M(t, 1, "two", true, 3); + M(t, 1, "two", true); + + M(t, 1, "two", c: true); + M(t, 1, "two", true, 3, y: "four"); + + M(t, 1, "two", true, 3, p: new[] { 5 }); + M(t, 1, "two", true, p: new[] { 5 }); + M(t, 1, "two", true, y: "four"); + M(t, 1, "two", true, x: 3); + + M(t, 1, "two", true, y: "four", x: 3); + M(t, 1, y: "four", x: 3, b: "two", c: true); + M(t, y: "four", x: 3, c: true, b: "two", a: 1); + M(t, p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1); + M(p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1, o: t); } - """; - - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, - markup, - expectedSuccess: true, - updatedSignature: signature, - totalParameters: totalParameters, - verifyNoDiagnostics: true); - } - - [Theory] + } + """; + + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, + markup, + expectedSuccess: true, + updatedSignature: signature, + totalParameters: totalParameters, + verifyNoDiagnostics: true); + } + + [Theory] #pragma warning disable xUnit1019 - // There is a bug in xUnit analyzer might generate false alarm, temporary disable it - // https://github.com/xunit/xunit/issues/1968 - [MemberData(nameof(AbstractChangeSignatureTests.GetAllSignatureSpecificationsForTheory), new[] { 0, 3, 0, 0 }, MemberType = typeof(AbstractChangeSignatureTests))] + // There is a bug in xUnit analyzer might generate false alarm, temporary disable it + // https://github.com/xunit/xunit/issues/1968 + [MemberData(nameof(AbstractChangeSignatureTests.GetAllSignatureSpecificationsForTheory), new[] { 0, 3, 0, 0 }, MemberType = typeof(AbstractChangeSignatureTests))] #pragma warning restore xUnit1019 - public async Task TestAllSignatureChanges_OnDelegate_3Regular(int totalParameters, int[] signature) - { - var markup = """ - using System; - using System.Collections.Generic; - using System.Linq; - - /// - /// This is , which has these methods: - /// - /// - /// - /// - /// - /// x! - /// y! - /// z! - delegate void $$MyDelegate(int x, string y, bool z); - - class C + public async Task TestAllSignatureChanges_OnDelegate_3Regular(int totalParameters, int[] signature) + { + var markup = """ + using System; + using System.Collections.Generic; + using System.Linq; + + /// + /// This is , which has these methods: + /// + /// + /// + /// + /// + /// x! + /// y! + /// z! + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() { - void M() - { - MyDelegate d1 = null; - - // Inline updates - d1(1, "Two", true); - d1.Invoke(1, "Two", true); - // d1.BeginInvoke(1, "Two", null, null); - d1.EndInvoke(null); - d1 = delegate (int e, string f, bool g) { var x = e + (g ? f.Length : 0); }; - d1 = delegate { }; - d1 = (r, s, t) => { var x = r + (t ? s.Length : 0); }; - - // Cascade through method groups - d1 = Goo1; - d1 = new MyDelegate(Goo2); - Target(Goo3); - Target((m, n, o) => { var x = m + (o ? n.Length : 0); }); - d1 = Result(); - d1 = Result2().First(); - d1 = Result3().First(); - - // And references to those methods - Goo1(1, "Two", true); - Goo2(1, "Two", true); - Goo2(1, false, false); // shouldn't change - Goo3(1, "Two", true); - Goo4(1, "Two", true); - Goo5(1, "Two", true); - } - - private MyDelegate Result() { return Goo4; } - private IEnumerable Result2() { yield return Goo5; } - private IEnumerable Result3() { yield return (g, h, i) => { var x = g + (i ? h.Length : 0); }; } - - void Target(MyDelegate d) { } - void TargetTakesAction(Action a) { } - - /// - /// - /// - void Goo1(int a, string b, bool c) { } - - /// - /// - /// - void Goo2(int a, string b, bool c) { } - - /// - /// - /// - void Goo2(int a, object b, bool c) { } - - /// - /// - /// - void Goo3(int a, string b, bool c) { } - - /// - /// - /// - void Goo4(int a, string b, bool c) { } - - /// - /// - /// - void Goo5(int a, string b, bool c) { } + MyDelegate d1 = null; + + // Inline updates + d1(1, "Two", true); + d1.Invoke(1, "Two", true); + // d1.BeginInvoke(1, "Two", null, null); + d1.EndInvoke(null); + d1 = delegate (int e, string f, bool g) { var x = e + (g ? f.Length : 0); }; + d1 = delegate { }; + d1 = (r, s, t) => { var x = r + (t ? s.Length : 0); }; + + // Cascade through method groups + d1 = Goo1; + d1 = new MyDelegate(Goo2); + Target(Goo3); + Target((m, n, o) => { var x = m + (o ? n.Length : 0); }); + d1 = Result(); + d1 = Result2().First(); + d1 = Result3().First(); + + // And references to those methods + Goo1(1, "Two", true); + Goo2(1, "Two", true); + Goo2(1, false, false); // shouldn't change + Goo3(1, "Two", true); + Goo4(1, "Two", true); + Goo5(1, "Two", true); } - """; - - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, - markup, - expectedSuccess: true, - updatedSignature: signature, - totalParameters: totalParameters, - verifyNoDiagnostics: true, - parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7)); - } + + private MyDelegate Result() { return Goo4; } + private IEnumerable Result2() { yield return Goo5; } + private IEnumerable Result3() { yield return (g, h, i) => { var x = g + (i ? h.Length : 0); }; } + + void Target(MyDelegate d) { } + void TargetTakesAction(Action a) { } + + /// + /// + /// + void Goo1(int a, string b, bool c) { } + + /// + /// + /// + void Goo2(int a, string b, bool c) { } + + /// + /// + /// + void Goo2(int a, object b, bool c) { } + + /// + /// + /// + void Goo3(int a, string b, bool c) { } + + /// + /// + /// + void Goo4(int a, string b, bool c) { } + + /// + /// + /// + void Goo5(int a, string b, bool c) { } + } + """; + + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, + markup, + expectedSuccess: true, + updatedSignature: signature, + totalParameters: totalParameters, + verifyNoDiagnostics: true, + parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7)); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Delegates.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Delegates.cs index 7aa037caef223..c8b7205b61b85 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Delegates.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Delegates.cs @@ -10,827 +10,825 @@ using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) + => new ChangeSignatureCodeRefactoringProvider(); + + protected internal override string GetLanguage() + => LanguageNames.CSharp; + + [Fact] + public async Task ChangeSignature_Delegates_ImplicitInvokeCalls() { - protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) - => new ChangeSignatureCodeRefactoringProvider(); - - protected internal override string GetLanguage() - => LanguageNames.CSharp; - - [Fact] - public async Task ChangeSignature_Delegates_ImplicitInvokeCalls() - { - var markup = """ - delegate void MyDelegate($$int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = null; - d1(1, "Two", true); - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1(true, "Two"); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); - } - - [Fact] - public async Task ChangeSignature_Delegates_ExplicitInvokeCalls() - { - var markup = """ - delegate void MyDelegate(int x, string $$y, bool z); - - class C - { - void M() - { - MyDelegate d1 = null; - d1.Invoke(1, "Two", true); - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1.Invoke(true, "Two"); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 1); - } - - [Fact] - public async Task ChangeSignature_Delegates_BeginInvokeCalls() - { - var markup = """ - delegate void MyDelegate(int x, string y, bool z$$); - - class C - { - void M() - { - MyDelegate d1 = null; - d1.BeginInvoke(1, "Two", true, null, null); - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1.BeginInvoke(true, "Two", null, null); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 2); - } - - [Fact] - public async Task ChangeSignature_Delegates_AnonymousMethods() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = delegate (int e, string f, bool g) { var x = f.Length + (g ? 0 : 1); }; - d1 = delegate { }; - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = delegate (bool g, string f) { var x = f.Length + (g ? 0 : 1); }; - d1 = delegate { }; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_Lambdas() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = (r, s, t) => { var x = s.Length + (t ? 0 : 1); }; - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = (t, s) => { var x = s.Length + (t ? 0 : 1); }; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_Lambdas_RemovingOnlyParameterIntroducesParentheses() - { - var markup = """ - delegate void $$MyDelegate(int x); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = (r) => { System.Console.WriteLine("Test"); }; - d1 = r => { System.Console.WriteLine("Test"); }; - d1 = r => { System.Console.WriteLine("Test"); }; - } - } - """; - var updatedSignature = Array.Empty(); - var expectedUpdatedCode = """ - delegate void MyDelegate(); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = () => { System.Console.WriteLine("Test"); }; - d1 = () => { System.Console.WriteLine("Test"); }; - d1 = () => { System.Console.WriteLine("Test"); }; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_AssignedToVariable() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = Goo; - Goo(1, "Two", true); - Goo(1, false, false); - } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = null; - d1 = Goo; - Goo(true, "Two"); - Goo(1, false, false); - } - - void Goo(bool c, string b) { } - void Goo(int a, object b, bool c) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_DelegateConstructor() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = new MyDelegate(Goo); - Goo(1, "Two", true); - Goo(1, false, false); - } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = new MyDelegate(Goo); - Goo(true, "Two"); - Goo(1, false, false); - } - - void Goo(bool c, string b) { } - void Goo(int a, object b, bool c) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_PassedAsArgument() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - Target(Goo); - Goo(1, "Two", true); - Goo(1, false, false); - } - - void Target(MyDelegate d) { } - - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - Target(Goo); - Goo(true, "Two"); - Goo(1, false, false); - } - - void Target(MyDelegate d) { } + var markup = """ + delegate void MyDelegate($$int x, string y, bool z); - void Goo(bool c, string b) { } - void Goo(int a, object b, bool c) { } + class C + { + void M() + { + MyDelegate d1 = null; + d1(1, "Two", true); + } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1(true, "Two"); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_ReturnValue() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = Result(); - Goo(1, "Two", true); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); + } - private MyDelegate Result() - { - return Goo; - } + [Fact] + public async Task ChangeSignature_Delegates_ExplicitInvokeCalls() + { + var markup = """ + delegate void MyDelegate(int x, string $$y, bool z); - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + class C + { + void M() + { + MyDelegate d1 = null; + d1.Invoke(1, "Two", true); } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); - class C + class C + { + void M() { - void M() - { - MyDelegate d1 = Result(); - Goo(true, "Two"); - } + MyDelegate d1 = null; + d1.Invoke(true, "Two"); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 1); + } - private MyDelegate Result() - { - return Goo; - } + [Fact] + public async Task ChangeSignature_Delegates_BeginInvokeCalls() + { + var markup = """ + delegate void MyDelegate(int x, string y, bool z$$); - void Goo(bool c, string b) { } - void Goo(int a, object b, bool c) { } + class C + { + void M() + { + MyDelegate d1 = null; + d1.BeginInvoke(1, "Two", true, null, null); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); - [Fact] - public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_YieldReturnValue() - { - var markup = """ - using System.Collections.Generic; + class C + { + void M() + { + MyDelegate d1 = null; + d1.BeginInvoke(true, "Two", null, null); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 2); + } - delegate void $$MyDelegate(int x, string y, bool z); + [Fact] + public async Task ChangeSignature_Delegates_AnonymousMethods() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = delegate (int e, string f, bool g) { var x = f.Length + (g ? 0 : 1); }; + d1 = delegate { }; + } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = delegate (bool g, string f) { var x = f.Length + (g ? 0 : 1); }; + d1 = delegate { }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C - { - void M() - { - Goo(1, "Two", true); - } + [Fact] + public async Task ChangeSignature_Delegates_Lambdas() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - private IEnumerable Result() - { - yield return Goo; - } + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (r, s, t) => { var x = s.Length + (t ? 0 : 1); }; + } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); - void Goo(int a, string b, bool c) { } - void Goo(int a, object b, bool c) { } + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (t, s) => { var x = s.Length + (t ? 0 : 1); }; } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - using System.Collections.Generic; + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_Lambdas_RemovingOnlyParameterIntroducesParentheses() + { + var markup = """ + delegate void $$MyDelegate(int x); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = (r) => { System.Console.WriteLine("Test"); }; + d1 = r => { System.Console.WriteLine("Test"); }; + d1 = r => { System.Console.WriteLine("Test"); }; + } + } + """; + var updatedSignature = Array.Empty(); + var expectedUpdatedCode = """ + delegate void MyDelegate(); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = () => { System.Console.WriteLine("Test"); }; + d1 = () => { System.Console.WriteLine("Test"); }; + d1 = () => { System.Console.WriteLine("Test"); }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - delegate void MyDelegate(bool z, string y); + [Fact] + public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_AssignedToVariable() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = Goo; + Goo(1, "Two", true); + Goo(1, false, false); + } + + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class C + { + void M() + { + MyDelegate d1 = null; + d1 = Goo; + Goo(true, "Two"); + Goo(1, false, false); + } + + void Goo(bool c, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class C + [Fact] + public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_DelegateConstructor() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() { - void M() - { - Goo(true, "Two"); - } + MyDelegate d1 = new MyDelegate(Goo); + Goo(1, "Two", true); + Goo(1, false, false); + } - private IEnumerable Result() - { - yield return Goo; - } + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); - void Goo(bool c, string b) { } - void Goo(int a, object b, bool c) { } + class C + { + void M() + { + MyDelegate d1 = new MyDelegate(Goo); + Goo(true, "Two"); + Goo(1, false, false); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_ReferencingLambdas_MethodArgument() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M6() - { - Target((m, n, o) => { var x = n.Length + (o ? 0 : 1); }); - } - - void Target(MyDelegate d) { } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class C - { - void M6() - { - Target((o, n) => { var x = n.Length + (o ? 0 : 1); }); - } - - void Target(MyDelegate d) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_ReferencingLambdas_YieldReturn() - { - var markup = """ - using System.Collections.Generic; - - delegate void $$MyDelegate(int x, string y, bool z); - class C - { - private IEnumerable Result3() - { - yield return (g, h, i) => { var x = h.Length + (i ? 0 : 1); }; - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - using System.Collections.Generic; - - delegate void MyDelegate(bool z, string y); - class C - { - private IEnumerable Result3() - { - yield return (i, h) => { var x = h.Length + (i ? 0 : 1); }; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_Recursive() - { - var markup = """ - delegate RecursiveDelegate $$RecursiveDelegate(int x, string y, bool z); - - class C - { - void M() - { - RecursiveDelegate rd = null; - rd(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true); - } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate RecursiveDelegate RecursiveDelegate(bool z, string y); - - class C - { - void M() - { - RecursiveDelegate rd = null; - rd(true, "Two")(true, "Two")(true, "Two")(true, "Two")(true, "Two"); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_DocComments() - { - var markup = """ - /// - /// This is , which has these methods: - /// - /// - /// - /// - /// - /// x! - /// y! - /// z! - delegate void $$MyDelegate(int x, string y, bool z); - - class C - { - void M() - { - MyDelegate d1 = Goo; - Goo(1, "Two", true); - } - - /// - /// - /// - void Goo(int a, string b, bool c) { } - } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - /// - /// This is , which has these methods: - /// - /// - /// - /// - /// - /// z! - /// y! - /// - delegate void MyDelegate(bool z, string y); - - class C - { - void M() - { - MyDelegate d1 = Goo; - Goo(true, "Two"); - } - - /// - /// - /// - void Goo(bool c, string b) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task ChangeSignature_Delegates_CascadeThroughEventAdd() - { - var markup = """ - delegate void $$MyDelegate(int x, string y, bool z); + void Goo(bool c, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_PassedAsArgument() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - class Program + class C + { + void M() { - void M() - { - MyEvent += Program_MyEvent; - } - - event MyDelegate MyEvent; - void Program_MyEvent(int a, string b, bool c) { } + Target(Goo); + Goo(1, "Two", true); + Goo(1, false, false); } - """; - var updatedSignature = new[] { 2, 1 }; - var expectedUpdatedCode = """ - delegate void MyDelegate(bool z, string y); - - class Program - { - void M() - { - MyEvent += Program_MyEvent; - } - - event MyDelegate MyEvent; - void Program_MyEvent(bool c, string b) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_Generics1() - { - var markup = """ - public class DP16a - { - public delegate void D($$T t); - public event D E1; - public event D E2; - - public void M1(int i) { } - public void M2(int i) { } - public void M3(int i) { } - - void B() - { - D d = new D(M1); - E1 += new D(M2); - E2 -= new D(M3); - } - } - """; - var updatedSignature = Array.Empty(); - var expectedUpdatedCode = """ - public class DP16a - { - public delegate void D(); - public event D E1; - public event D E2; - - public void M1() { } - public void M2() { } - public void M3() { } - - void B() - { - D d = new D(M1); - E1 += new D(M2); - E2 -= new D(M3); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_Generics2() - { - var markup = """ - public class D17 - { - public delegate void $$D(T t); - } - public class D17Test - { - void Test() { var x = new D17.D(M17); } - internal void M17(string s) { } - } - """; - var updatedSignature = Array.Empty(); - var expectedUpdatedCode = """ - public class D17 - { - public delegate void D(); - } - public class D17Test - { - void Test() { var x = new D17.D(M17); } - internal void M17() { } + + void Target(MyDelegate d) { } + + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class C + { + void M() + { + Target(Goo); + Goo(true, "Two"); + Goo(1, false, false); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - - [Fact] - public async Task ChangeSignature_Delegates_GenericParams() - { - var markup = """ - class DA - { - void M(params int[] i) { } - void B() - { - DP20.D d = new DP20.D(M); - d(); - d(0); - d(0, 1); - } + + void Target(MyDelegate d) { } + + void Goo(bool c, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_ReturnValue() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = Result(); + Goo(1, "Two", true); } - public class DP20 + + private MyDelegate Result() { - public delegate void $$D(params T[] t); - public void M1(params T[] t) { } + return Goo; + } - void B() - { - D d = new D(M1); - } + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class C + { + void M() + { + MyDelegate d1 = Result(); + Goo(true, "Two"); } - """; - var updatedSignature = Array.Empty(); - var expectedUpdatedCode = """ - class DA + + private MyDelegate Result() { - void M() { } - void B() - { - DP20.D d = new DP20.D(M); - d(); - d(); - d(); - } + return Goo; } - public class DP20 + + void Goo(bool c, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_CascadeThroughMethodGroups_YieldReturnValue() + { + var markup = """ + using System.Collections.Generic; + + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() { - public delegate void D(); - public void M1() { } + Goo(1, "Two", true); + } - void B() - { - D d = new D(M1); - } + private IEnumerable Result() + { + yield return Goo; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } - [Fact] - public async Task ChangeSignature_Delegates_Generic_RemoveArgumentAtReference() - { - var markup = """ - public class CD + void Goo(int a, string b, bool c) { } + void Goo(int a, object b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + using System.Collections.Generic; + + delegate void MyDelegate(bool z, string y); + + class C + { + void M() { - public delegate void D(T t); + Goo(true, "Two"); } - class Test + + private IEnumerable Result() { - public void M() - { - var dele = new CD.$$D((int x) => { }); - } + yield return Goo; } - """; - var updatedSignature = Array.Empty(); - var expectedUpdatedCode = """ - public class CD + + void Goo(bool c, string b) { } + void Goo(int a, object b, bool c) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_ReferencingLambdas_MethodArgument() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M6() { - public delegate void D(); + Target((m, n, o) => { var x = n.Length + (o ? 0 : 1); }); } - class Test + + void Target(MyDelegate d) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class C + { + void M6() { - public void M() - { - var dele = new CD.D(() => { }); - } + Target((o, n) => { var x = n.Length + (o ? 0 : 1); }); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, - expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); - } - [Fact] - public async Task ChangeSignature_Delegate_Generics_RemoveStaticArgument() - { - var markup = """ - public class C2 + void Target(MyDelegate d) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_ReferencingLambdas_YieldReturn() + { + var markup = """ + using System.Collections.Generic; + + delegate void $$MyDelegate(int x, string y, bool z); + class C + { + private IEnumerable Result3() { - public delegate void D(T t); + yield return (g, h, i) => { var x = h.Length + (i ? 0 : 1); }; } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + using System.Collections.Generic; - public class D2 + delegate void MyDelegate(bool z, string y); + class C + { + private IEnumerable Result3() { - public static D2 Instance = null; - void M(D2 m) { } + yield return (i, h) => { var x = h.Length + (i ? 0 : 1); }; + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - void B() - { - C2.D d = new C2.D(M); - $$d(D2.Instance); - } + [Fact] + public async Task ChangeSignature_Delegates_Recursive() + { + var markup = """ + delegate RecursiveDelegate $$RecursiveDelegate(int x, string y, bool z); + + class C + { + void M() + { + RecursiveDelegate rd = null; + rd(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true)(1, "Two", true); } - """; - var updatedSignature = Array.Empty(); - var expectedUpdatedCode = """ - public class C2 + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate RecursiveDelegate RecursiveDelegate(bool z, string y); + + class C + { + void M() { - public delegate void D(); + RecursiveDelegate rd = null; + rd(true, "Two")(true, "Two")(true, "Two")(true, "Two")(true, "Two"); } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_DocComments() + { + var markup = """ + /// + /// This is , which has these methods: + /// + /// + /// + /// + /// + /// x! + /// y! + /// z! + delegate void $$MyDelegate(int x, string y, bool z); + + class C + { + void M() + { + MyDelegate d1 = Goo; + Goo(1, "Two", true); + } + + /// + /// + /// + void Goo(int a, string b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + /// + /// This is , which has these methods: + /// + /// + /// + /// + /// + /// z! + /// y! + /// + delegate void MyDelegate(bool z, string y); + + class C + { + void M() + { + MyDelegate d1 = Goo; + Goo(true, "Two"); + } + + /// + /// + /// + void Goo(bool c, string b) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_CascadeThroughEventAdd() + { + var markup = """ + delegate void $$MyDelegate(int x, string y, bool z); - public class D2 + class Program + { + void M() { - public static D2 Instance = null; - void M() { } + MyEvent += Program_MyEvent; + } - void B() - { - C2.D d = new C2.D(M); - d(); - } + event MyDelegate MyEvent; + void Program_MyEvent(int a, string b, bool c) { } + } + """; + var updatedSignature = new[] { 2, 1 }; + var expectedUpdatedCode = """ + delegate void MyDelegate(bool z, string y); + + class Program + { + void M() + { + MyEvent += Program_MyEvent; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + + event MyDelegate MyEvent; + void Program_MyEvent(bool c, string b) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_Generics1() + { + var markup = """ + public class DP16a + { + public delegate void D($$T t); + public event D E1; + public event D E2; + + public void M1(int i) { } + public void M2(int i) { } + public void M3(int i) { } + + void B() + { + D d = new D(M1); + E1 += new D(M2); + E2 -= new D(M3); + } + } + """; + var updatedSignature = Array.Empty(); + var expectedUpdatedCode = """ + public class DP16a + { + public delegate void D(); + public event D E1; + public event D E2; + + public void M1() { } + public void M2() { } + public void M3() { } + + void B() + { + D d = new D(M1); + E1 += new D(M2); + E2 -= new D(M3); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_Generics2() + { + var markup = """ + public class D17 + { + public delegate void $$D(T t); + } + public class D17Test + { + void Test() { var x = new D17.D(M17); } + internal void M17(string s) { } + } + """; + var updatedSignature = Array.Empty(); + var expectedUpdatedCode = """ + public class D17 + { + public delegate void D(); + } + public class D17Test + { + void Test() { var x = new D17.D(M17); } + internal void M17() { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_GenericParams() + { + var markup = """ + class DA + { + void M(params int[] i) { } + void B() + { + DP20.D d = new DP20.D(M); + d(); + d(0); + d(0, 1); + } + } + public class DP20 + { + public delegate void $$D(params T[] t); + public void M1(params T[] t) { } + + void B() + { + D d = new D(M1); + } + } + """; + var updatedSignature = Array.Empty(); + var expectedUpdatedCode = """ + class DA + { + void M() { } + void B() + { + DP20.D d = new DP20.D(M); + d(); + d(); + d(); + } + } + public class DP20 + { + public delegate void D(); + public void M1() { } + + void B() + { + D d = new D(M1); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact] + public async Task ChangeSignature_Delegates_Generic_RemoveArgumentAtReference() + { + var markup = """ + public class CD + { + public delegate void D(T t); + } + class Test + { + public void M() + { + var dele = new CD.$$D((int x) => { }); + } + } + """; + var updatedSignature = Array.Empty(); + var expectedUpdatedCode = """ + public class CD + { + public delegate void D(); + } + class Test + { + public void M() + { + var dele = new CD.D(() => { }); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, + expectedUpdatedInvocationDocumentCode: expectedUpdatedCode, expectedSelectedIndex: 0); + } + + [Fact] + public async Task ChangeSignature_Delegate_Generics_RemoveStaticArgument() + { + var markup = """ + public class C2 + { + public delegate void D(T t); + } + + public class D2 + { + public static D2 Instance = null; + void M(D2 m) { } + + void B() + { + C2.D d = new C2.D(M); + $$d(D2.Instance); + } + } + """; + var updatedSignature = Array.Empty(); + var expectedUpdatedCode = """ + public class C2 + { + public delegate void D(); + } + + public class D2 + { + public static D2 Instance = null; + void M() { } + + void B() + { + C2.D d = new C2.D(M); + d(); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Formatting.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Formatting.cs index 3f4a7e820eb97..b1af32b7ab185 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Formatting.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ChangeSignature_Formatting.cs @@ -10,457 +10,456 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task ChangeSignature_Formatting_KeepCountsPerLine() { - [Fact] - public async Task ChangeSignature_Formatting_KeepCountsPerLine() - { - var markup = """ - class C - { - void $$Method(int a, int b, int c, - int d, int e, - int f) - { - Method(1, - 2, 3, - 4, 5, 6); - } - } - """; - var updatedSignature = new[] { 5, 4, 3, 2, 1, 0 }; - var expectedUpdatedCode = """ - class C - { - void Method(int f, int e, int d, - int c, int b, - int a) - { - Method(6, - 5, 4, - 3, 2, 1); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + var markup = """ + class C + { + void $$Method(int a, int b, int c, + int d, int e, + int f) + { + Method(1, + 2, 3, + 4, 5, 6); + } + } + """; + var updatedSignature = new[] { 5, 4, 3, 2, 1, 0 }; + var expectedUpdatedCode = """ + class C + { + void Method(int f, int e, int d, + int c, int b, + int a) + { + Method(6, + 5, 4, + 3, 2, 1); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task ChangeSignature_Formatting_KeepTrivia() - { - var markup = """ - class C - { - void $$Method( - int a, int b, int c, - int d, int e, - int f) - { - Method( - 1, 2, 3, - 4, 5, 6); - } - } - """; - var updatedSignature = new[] { 1, 2, 3, 4, 5 }; - var expectedUpdatedCode = """ - class C - { - void Method( - int b, int c, int d, - int e, int f) - { - Method( - 2, 3, 4, - 5, 6); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task ChangeSignature_Formatting_KeepTrivia() + { + var markup = """ + class C + { + void $$Method( + int a, int b, int c, + int d, int e, + int f) + { + Method( + 1, 2, 3, + 4, 5, 6); + } + } + """; + var updatedSignature = new[] { 1, 2, 3, 4, 5 }; + var expectedUpdatedCode = """ + class C + { + void Method( + int b, int c, int d, + int e, int f) + { + Method( + 2, 3, 4, + 5, 6); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task ChangeSignature_Formatting_KeepTrivia_WithArgumentNames() - { - var markup = """ - class C - { - void $$Method( - int a, int b, int c, - int d, int e, - int f) - { - Method( - a: 1, b: 2, c: 3, - d: 4, e: 5, f: 6); - } - } - """; - var updatedSignature = new[] { 1, 2, 3, 4, 5 }; - var expectedUpdatedCode = """ - class C - { - void Method( - int b, int c, int d, - int e, int f) - { - Method( - b: 2, c: 3, d: 4, - e: 5, f: 6); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task ChangeSignature_Formatting_KeepTrivia_WithArgumentNames() + { + var markup = """ + class C + { + void $$Method( + int a, int b, int c, + int d, int e, + int f) + { + Method( + a: 1, b: 2, c: 3, + d: 4, e: 5, f: 6); + } + } + """; + var updatedSignature = new[] { 1, 2, 3, 4, 5 }; + var expectedUpdatedCode = """ + class C + { + void Method( + int b, int c, int d, + int e, int f) + { + Method( + b: 2, c: 3, d: 4, + e: 5, f: 6); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task ChangeSignature_Formatting_Method() - { - var markup = """ - class C - { - void $$Method(int a, - int b) - { - Method(1, - 2); - } - } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - class C - { - void Method(int b, - int a) - { - Method(2, - 1); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact] + public async Task ChangeSignature_Formatting_Method() + { + var markup = """ + class C + { + void $$Method(int a, + int b) + { + Method(1, + 2); + } + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + class C + { + void Method(int b, + int a) + { + Method(2, + 1); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task ChangeSignature_Formatting_Constructor() - { - var markup = """ - class SomeClass - { - $$SomeClass(int a, - int b) - { - new SomeClass(1, - 2); - } - } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - class SomeClass - { - SomeClass(int b, - int a) - { - new SomeClass(2, - 1); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact] + public async Task ChangeSignature_Formatting_Constructor() + { + var markup = """ + class SomeClass + { + $$SomeClass(int a, + int b) + { + new SomeClass(1, + 2); + } + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + class SomeClass + { + SomeClass(int b, + int a) + { + new SomeClass(2, + 1); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task ChangeSignature_Formatting_Indexer() - { - var markup = """ - class SomeClass + [Fact] + public async Task ChangeSignature_Formatting_Indexer() + { + var markup = """ + class SomeClass + { + public int $$this[int a, + int b] { - public int $$this[int a, - int b] + get { - get - { - return new SomeClass()[1, - 2]; - } + return new SomeClass()[1, + 2]; } } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - class SomeClass + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + class SomeClass + { + public int this[int b, + int a] { - public int this[int b, - int a] + get { - get - { - return new SomeClass()[2, - 1]; - } + return new SomeClass()[2, + 1]; } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task ChangeSignature_Formatting_Delegate() - { - var markup = """ - class SomeClass - { - delegate void $$MyDelegate(int a, - int b); + [Fact] + public async Task ChangeSignature_Formatting_Delegate() + { + var markup = """ + class SomeClass + { + delegate void $$MyDelegate(int a, + int b); - void M(int a, - int b) - { - var myDel = new MyDelegate(M); - myDel(1, - 2); - } - } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - class SomeClass - { - delegate void MyDelegate(int b, - int a); + void M(int a, + int b) + { + var myDel = new MyDelegate(M); + myDel(1, + 2); + } + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + class SomeClass + { + delegate void MyDelegate(int b, + int a); - void M(int b, - int a) - { - var myDel = new MyDelegate(M); - myDel(2, - 1); - } + void M(int b, + int a) + { + var myDel = new MyDelegate(M); + myDel(2, + 1); } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact] - public async Task ChangeSignature_Formatting_AnonymousMethod() - { - var markup = """ - class SomeClass - { - delegate void $$MyDelegate(int a, - int b); + [Fact] + public async Task ChangeSignature_Formatting_AnonymousMethod() + { + var markup = """ + class SomeClass + { + delegate void $$MyDelegate(int a, + int b); - void M() - { - MyDelegate myDel = delegate (int x, - int y) - { - // Nothing - }; - } - } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - class SomeClass + void M() { - delegate void MyDelegate(int b, - int a); - - void M() + MyDelegate myDel = delegate (int x, + int y) { - MyDelegate myDel = delegate (int y, - int x) - { - // Nothing - }; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + // Nothing + }; + } + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + class SomeClass + { + delegate void MyDelegate(int b, + int a); - [Fact] - public async Task ChangeSignature_Formatting_ConstructorInitializers() - { - var markup = """ - class B + void M() { - public $$B(int x, int y) { } - public B() : this(1, - 2) - { } + MyDelegate myDel = delegate (int y, + int x) + { + // Nothing + }; } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - class D : B - { - public D() : base(1, - 2) - { } - } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - class B - { - public B(int y, int x) { } - public B() : this(2, - 1) - { } - } + [Fact] + public async Task ChangeSignature_Formatting_ConstructorInitializers() + { + var markup = """ + class B + { + public $$B(int x, int y) { } + public B() : this(1, + 2) + { } + } - class D : B - { - public D() : base(2, - 1) - { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + class D : B + { + public D() : base(1, + 2) + { } + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + class B + { + public B(int y, int x) { } + public B() : this(2, + 1) + { } + } - [Fact] - public async Task ChangeSignature_Formatting_Attribute() - { - var markup = """ - [Custom(1, - 2)] - class CustomAttribute : System.Attribute - { - public $$CustomAttribute(int x, int y) { } - } - """; - var updatedSignature = new[] { 1, 0 }; - var expectedUpdatedCode = """ - [Custom(2, - 1)] - class CustomAttribute : System.Attribute - { - public CustomAttribute(int y, int x) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + class D : B + { + public D() : base(2, + 1) + { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task ChangeSignature_Formatting_Attribute_KeepTrivia() - { - var markup = """ - [Custom( - 1, 2)] - class CustomAttribute : System.Attribute - { - public $$CustomAttribute(int x, int y) { } - } - """; - var updatedSignature = new[] { 1 }; - var expectedUpdatedCode = """ - [Custom( - 2)] - class CustomAttribute : System.Attribute - { - public CustomAttribute(int y) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact] + public async Task ChangeSignature_Formatting_Attribute() + { + var markup = """ + [Custom(1, + 2)] + class CustomAttribute : System.Attribute + { + public $$CustomAttribute(int x, int y) { } + } + """; + var updatedSignature = new[] { 1, 0 }; + var expectedUpdatedCode = """ + [Custom(2, + 1)] + class CustomAttribute : System.Attribute + { + public CustomAttribute(int y, int x) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task ChangeSignature_Formatting_Attribute_KeepTrivia_RemovingSecond() - { - var markup = """ - [Custom( - 1, 2)] - class CustomAttribute : System.Attribute - { - public $$CustomAttribute(int x, int y) { } - } - """; - var updatedSignature = new[] { 0 }; - var expectedUpdatedCode = """ - [Custom( - 1)] - class CustomAttribute : System.Attribute - { - public CustomAttribute(int x) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task ChangeSignature_Formatting_Attribute_KeepTrivia() + { + var markup = """ + [Custom( + 1, 2)] + class CustomAttribute : System.Attribute + { + public $$CustomAttribute(int x, int y) { } + } + """; + var updatedSignature = new[] { 1 }; + var expectedUpdatedCode = """ + [Custom( + 2)] + class CustomAttribute : System.Attribute + { + public CustomAttribute(int y) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task ChangeSignature_Formatting_Attribute_KeepTrivia_RemovingBoth() - { - var markup = """ - [Custom( - 1, 2)] - class CustomAttribute : System.Attribute - { - public $$CustomAttribute(int x, int y) { } - } - """; - var updatedSignature = new int[] { }; - var expectedUpdatedCode = """ - [Custom( - )] - class CustomAttribute : System.Attribute - { - public CustomAttribute() { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task ChangeSignature_Formatting_Attribute_KeepTrivia_RemovingSecond() + { + var markup = """ + [Custom( + 1, 2)] + class CustomAttribute : System.Attribute + { + public $$CustomAttribute(int x, int y) { } + } + """; + var updatedSignature = new[] { 0 }; + var expectedUpdatedCode = """ + [Custom( + 1)] + class CustomAttribute : System.Attribute + { + public CustomAttribute(int x) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] - public async Task ChangeSignature_Formatting_Attribute_KeepTrivia_RemovingBeforeNewlineComma() - { - var markup = """ - [Custom(1 - , 2, 3)] - class CustomAttribute : System.Attribute - { - public $$CustomAttribute(int x, int y, int z) { } - } - """; - var updatedSignature = new[] { 1, 2 }; - var expectedUpdatedCode = """ - [Custom(2, 3)] - class CustomAttribute : System.Attribute - { - public CustomAttribute(int y, int z) { } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task ChangeSignature_Formatting_Attribute_KeepTrivia_RemovingBoth() + { + var markup = """ + [Custom( + 1, 2)] + class CustomAttribute : System.Attribute + { + public $$CustomAttribute(int x, int y) { } + } + """; + var updatedSignature = new int[] { }; + var expectedUpdatedCode = """ + [Custom( + )] + class CustomAttribute : System.Attribute + { + public CustomAttribute() { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/946220")] - public async Task ChangeSignature_Formatting_LambdaAsArgument() - { - var markup = """ - class C - { - void M(System.Action f, int z$$) - { - M((x, y) => System.Console.WriteLine(x + y), 5); - } - } - """; - var updatedSignature = new[] { 0 }; - var expectedUpdatedCode = """ - class C - { - void M(System.Action f) - { - M((x, y) => System.Console.WriteLine(x + y)); - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28156")] + public async Task ChangeSignature_Formatting_Attribute_KeepTrivia_RemovingBeforeNewlineComma() + { + var markup = """ + [Custom(1 + , 2, 3)] + class CustomAttribute : System.Attribute + { + public $$CustomAttribute(int x, int y, int z) { } + } + """; + var updatedSignature = new[] { 1, 2 }; + var expectedUpdatedCode = """ + [Custom(2, 3)] + class CustomAttribute : System.Attribute + { + public CustomAttribute(int y, int z) { } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); + } + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/946220")] + public async Task ChangeSignature_Formatting_LambdaAsArgument() + { + var markup = """ + class C + { + void M(System.Action f, int z$$) + { + M((x, y) => System.Console.WriteLine(x + y), 5); + } + } + """; + var updatedSignature = new[] { 0 }; + var expectedUpdatedCode = """ + class C + { + void M(System.Action f) + { + M((x, y) => System.Console.WriteLine(x + y)); + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: expectedUpdatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/RemoveParametersTests.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/RemoveParametersTests.cs index fb18fdb980f8c..beea703624a9f 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/RemoveParametersTests.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/RemoveParametersTests.cs @@ -14,194 +14,193 @@ using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.ChangeSignature; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + public async Task RemoveParameters1() { - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public async Task RemoveParameters1() - { - var markup = """ - static class Ext + var markup = """ + static class Ext + { + /// + /// This is a summary of + /// + /// + /// + /// + /// + /// + /// + /// + static void $$M(this object o, int a, string b, bool c, int x = 0, string y = "Zero", params int[] p) { - /// - /// This is a summary of - /// - /// - /// - /// - /// - /// - /// - /// - static void $$M(this object o, int a, string b, bool c, int x = 0, string y = "Zero", params int[] p) - { - object t = new object(); - - M(t, 1, "two", true, 3, "four", new[] { 5, 6 }); - M(t, 1, "two", true, 3, "four", 5, 6); - t.M(1, "two", true, 3, "four", new[] { 5, 6 }); - t.M(1, "two", true, 3, "four", 5, 6); - - M(t, 1, "two", true, 3, "four"); - M(t, 1, "two", true, 3); - M(t, 1, "two", true); - - M(t, 1, "two", c: true); - M(t, 1, "two", true, 3, y: "four"); - - M(t, 1, "two", true, 3, p: new[] { 5 }); - M(t, 1, "two", true, p: new[] { 5 }); - M(t, 1, "two", true, y: "four"); - M(t, 1, "two", true, x: 3); - - M(t, 1, "two", true, y: "four", x: 3); - M(t, 1, y: "four", x: 3, b: "two", c: true); - M(t, y: "four", x: 3, c: true, b: "two", a: 1); - M(t, p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1); - M(p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1, o: t); - } + object t = new object(); + + M(t, 1, "two", true, 3, "four", new[] { 5, 6 }); + M(t, 1, "two", true, 3, "four", 5, 6); + t.M(1, "two", true, 3, "four", new[] { 5, 6 }); + t.M(1, "two", true, 3, "four", 5, 6); + + M(t, 1, "two", true, 3, "four"); + M(t, 1, "two", true, 3); + M(t, 1, "two", true); + + M(t, 1, "two", c: true); + M(t, 1, "two", true, 3, y: "four"); + + M(t, 1, "two", true, 3, p: new[] { 5 }); + M(t, 1, "two", true, p: new[] { 5 }); + M(t, 1, "two", true, y: "four"); + M(t, 1, "two", true, x: 3); + + M(t, 1, "two", true, y: "four", x: 3); + M(t, 1, y: "four", x: 3, b: "two", c: true); + M(t, y: "four", x: 3, c: true, b: "two", a: 1); + M(t, p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1); + M(p: new[] { 5 }, y: "four", x: 3, c: true, b: "two", a: 1, o: t); } - """; - var updatedSignature = new[] { 0, 2, 5 }; - var updatedCode = """ - static class Ext + } + """; + var updatedSignature = new[] { 0, 2, 5 }; + var updatedCode = """ + static class Ext + { + /// + /// This is a summary of + /// + /// + /// + /// + /// + /// + /// + /// + static void M(this object o, string b, string y = "Zero") { - /// - /// This is a summary of - /// - /// - /// - /// - /// - /// - /// - /// - static void M(this object o, string b, string y = "Zero") - { - object t = new object(); - - M(t, "two", "four"); - M(t, "two", "four"); - t.M("two", "four"); - t.M("two", "four"); - - M(t, "two", "four"); - M(t, "two"); - M(t, "two"); - - M(t, "two"); - M(t, "two", y: "four"); - - M(t, "two"); - M(t, "two"); - M(t, "two", y: "four"); - M(t, "two"); - - M(t, "two", y: "four"); - M(t, y: "four", b: "two"); - M(t, y: "four", b: "two"); - M(t, y: "four", b: "two"); - M(y: "four", b: "two", o: t); - } + object t = new object(); + + M(t, "two", "four"); + M(t, "two", "four"); + t.M("two", "four"); + t.M("two", "four"); + + M(t, "two", "four"); + M(t, "two"); + M(t, "two"); + + M(t, "two"); + M(t, "two", y: "four"); + + M(t, "two"); + M(t, "two"); + M(t, "two", y: "four"); + M(t, "two"); + + M(t, "two", y: "four"); + M(t, y: "four", b: "two"); + M(t, y: "four", b: "two"); + M(t, y: "four", b: "two"); + M(y: "four", b: "two", o: t); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public async Task RemoveParameters_GenericParameterType() - { - var markup = """ - class DA - { - void M(params int[] i) { } + [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + public async Task RemoveParameters_GenericParameterType() + { + var markup = """ + class DA + { + void M(params int[] i) { } - void B() - { - DP20.D d = new DP20.D(M); + void B() + { + DP20.D d = new DP20.D(M); - /*DA19*/$$d(0); - d(); - d(0, 1); - } + /*DA19*/$$d(0); + d(); + d(0, 1); } - public class DP20 - { - public delegate void /*DP20*/D(params T[] t); - public event D E1; - public event D E2; + } + public class DP20 + { + public delegate void /*DP20*/D(params T[] t); + public event D E1; + public event D E2; - public void M1(params T[] t) { } - public void M2(params T[] t) { } - public void M3(params T[] t) { } + public void M1(params T[] t) { } + public void M2(params T[] t) { } + public void M3(params T[] t) { } - void B() - { - D d = new D(M1); - E1 += new D(M2); - E2 -= new D(M3); - } - } - """; - var updatedSignature = Array.Empty(); - var updatedCode = """ - class DA + void B() { - void M() { } + D d = new D(M1); + E1 += new D(M2); + E2 -= new D(M3); + } + } + """; + var updatedSignature = Array.Empty(); + var updatedCode = """ + class DA + { + void M() { } - void B() - { - DP20.D d = new DP20.D(M); + void B() + { + DP20.D d = new DP20.D(M); - /*DA19*/d(); - d(); - d(); - } + /*DA19*/d(); + d(); + d(); } - public class DP20 - { - public delegate void /*DP20*/D(); - public event D E1; - public event D E2; + } + public class DP20 + { + public delegate void /*DP20*/D(); + public event D E1; + public event D E2; - public void M1() { } - public void M2() { } - public void M3() { } + public void M1() { } + public void M2() { } + public void M3() { } - void B() - { - D d = new D(M1); - E1 += new D(M2); - E2 -= new D(M3); - } + void B() + { + D d = new D(M1); + E1 += new D(M2); + E2 -= new D(M3); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1102830")] - [WorkItem("https://github.com/dotnet/roslyn/issues/784")] - public async Task RemoveParameters_ExtensionMethodInAnotherFile() - { - var workspaceXml = """ - - - """; + [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1102830")] + [WorkItem("https://github.com/dotnet/roslyn/issues/784")] + public async Task RemoveParameters_ExtensionMethodInAnotherFile() + { + var workspaceXml = """ + + + """; - for (var i = 0; i <= 4; i++) - { - workspaceXml += $@" + for (var i = 0; i <= 4; i++) + { + workspaceXml += $@" class C{i} {{ @@ -212,26 +211,26 @@ void M() }} }} "; - } + } - workspaceXml += """ - - public class C5 - { - } + workspaceXml += """ + + public class C5 + { + } - public static class C5Ext + public static class C5Ext + { + public void $$Ext(this C5 c, int i, string s) { - public void $$Ext(this C5 c, int i, string s) - { - } } - - """; + } + + """; - for (var i = 6; i <= 9; i++) - { - workspaceXml += $@" + for (var i = 6; i <= 9; i++) + { + workspaceXml += $@" class C{i} {{ @@ -242,50 +241,50 @@ void M() }} }} "; - } + } - workspaceXml += """ - - - """; + workspaceXml += """ + + + """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(2) }; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(2) }; - using var testState = ChangeSignatureTestState.Create(XElement.Parse(workspaceXml)); - testState.TestChangeSignatureOptionsService.UpdatedSignature = updatedSignature; - var result = await testState.ChangeSignatureAsync().ConfigureAwait(false); + using var testState = ChangeSignatureTestState.Create(XElement.Parse(workspaceXml)); + testState.TestChangeSignatureOptionsService.UpdatedSignature = updatedSignature; + var result = await testState.ChangeSignatureAsync().ConfigureAwait(false); - Assert.True(result.Succeeded); - Assert.Null(result.ChangeSignatureFailureKind); + Assert.True(result.Succeeded); + Assert.Null(result.ChangeSignatureFailureKind); - foreach (var updatedDocument in testState.Workspace.Documents.Select(d => result.UpdatedSolution.GetDocument(d.Id))) + foreach (var updatedDocument in testState.Workspace.Documents.Select(d => result.UpdatedSolution.GetDocument(d.Id))) + { + if (updatedDocument.Name == "C5.cs") { - if (updatedDocument.Name == "C5.cs") - { - Assert.Contains("void Ext(this C5 c, string s)", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); - } - else - { - Assert.Contains(@"c.Ext(""two"");", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); - } + Assert.Contains("void Ext(this C5 c, string s)", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); + } + else + { + Assert.Contains(@"c.Ext(""two"");", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); } } + } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1102830")] - [WorkItem("https://github.com/dotnet/roslyn/issues/784")] - public async Task AddRemoveParameters_ExtensionMethodInAnotherFile() - { - var workspaceXml = """ - - - """; + [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1102830")] + [WorkItem("https://github.com/dotnet/roslyn/issues/784")] + public async Task AddRemoveParameters_ExtensionMethodInAnotherFile() + { + var workspaceXml = """ + + + """; - for (var i = 0; i <= 4; i++) - { - workspaceXml += $@" + for (var i = 0; i <= 4; i++) + { + workspaceXml += $@" class C{i} {{ @@ -296,26 +295,26 @@ void M() }} }} "; - } + } - workspaceXml += """ - - public class C5 - { - } + workspaceXml += """ + + public class C5 + { + } - public static class C5Ext + public static class C5Ext + { + public void $$Ext(this C5 c, int i, string s) { - public void $$Ext(this C5 c, int i, string s) - { - } } - - """; + } + + """; - for (var i = 6; i <= 9; i++) - { - workspaceXml += $@" + for (var i = 6; i <= 9; i++) + { + workspaceXml += $@" class C{i} {{ @@ -326,124 +325,123 @@ void M() }} }} "; - } + } - workspaceXml += """ - - - """; + workspaceXml += """ + + + """; - var updatedSignature = new[] { - new AddedParameterOrExistingIndex(0), - new AddedParameterOrExistingIndex(2), - new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, callSiteValue:"123"), "int") }; + var updatedSignature = new[] { + new AddedParameterOrExistingIndex(0), + new AddedParameterOrExistingIndex(2), + new AddedParameterOrExistingIndex(new AddedParameter(null, "int", "newIntegerParameter", CallSiteKind.Value, callSiteValue:"123"), "int") }; - using var testState = ChangeSignatureTestState.Create(XElement.Parse(workspaceXml)); - testState.TestChangeSignatureOptionsService.UpdatedSignature = updatedSignature; - var result = await testState.ChangeSignatureAsync().ConfigureAwait(false); + using var testState = ChangeSignatureTestState.Create(XElement.Parse(workspaceXml)); + testState.TestChangeSignatureOptionsService.UpdatedSignature = updatedSignature; + var result = await testState.ChangeSignatureAsync().ConfigureAwait(false); - Assert.True(result.Succeeded); - Assert.Null(result.ChangeSignatureFailureKind); + Assert.True(result.Succeeded); + Assert.Null(result.ChangeSignatureFailureKind); - foreach (var updatedDocument in testState.Workspace.Documents.Select(d => result.UpdatedSolution.GetDocument(d.Id))) + foreach (var updatedDocument in testState.Workspace.Documents.Select(d => result.UpdatedSolution.GetDocument(d.Id))) + { + if (updatedDocument.Name == "C5.cs") { - if (updatedDocument.Name == "C5.cs") - { - Assert.Contains("void Ext(this C5 c, string s, int newIntegerParameter)", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); - } - else - { - Assert.Contains(@"c.Ext(""two"", 123);", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); - } + Assert.Contains("void Ext(this C5 c, string s, int newIntegerParameter)", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); + } + else + { + Assert.Contains(@"c.Ext(""two"", 123);", (await updatedDocument.GetTextAsync(CancellationToken.None)).ToString()); } } + } - [WpfFact] - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - [Trait(Traits.Feature, Traits.Features.Interactive)] - public void ChangeSignatureCommandDisabledInSubmission() - { - using var workspace = EditorTestWorkspace.Create(XElement.Parse(""" - - - class C + [WpfFact] + [Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [Trait(Traits.Feature, Traits.Features.Interactive)] + public void ChangeSignatureCommandDisabledInSubmission() + { + using var workspace = EditorTestWorkspace.Create(XElement.Parse(""" + + + class C + { + void M$$(int x) { - void M$$(int x) - { - } } - - - """), - workspaceKind: WorkspaceKind.Interactive, - composition: EditorTestCompositions.EditorFeaturesWpf); - // Force initialization. - workspace.GetOpenDocumentIds().Select(id => workspace.GetTestDocument(id).GetTextView()).ToList(); + } + + + """), + workspaceKind: WorkspaceKind.Interactive, + composition: EditorTestCompositions.EditorFeaturesWpf); + // Force initialization. + workspace.GetOpenDocumentIds().Select(id => workspace.GetTestDocument(id).GetTextView()).ToList(); - var textView = workspace.Documents.Single().GetTextView(); + var textView = workspace.Documents.Single().GetTextView(); - var handler = workspace.ExportProvider.GetCommandHandler(PredefinedCommandHandlerNames.ChangeSignature, ContentTypeNames.CSharpContentType); + var handler = workspace.ExportProvider.GetCommandHandler(PredefinedCommandHandlerNames.ChangeSignature, ContentTypeNames.CSharpContentType); - var state = handler.GetCommandState(new RemoveParametersCommandArgs(textView, textView.TextBuffer)); - Assert.True(state.IsUnspecified); + var state = handler.GetCommandState(new RemoveParametersCommandArgs(textView, textView.TextBuffer)); + Assert.True(state.IsUnspecified); - state = handler.GetCommandState(new ReorderParametersCommandArgs(textView, textView.TextBuffer)); - Assert.True(state.IsUnspecified); - } + state = handler.GetCommandState(new ReorderParametersCommandArgs(textView, textView.TextBuffer)); + Assert.True(state.IsUnspecified); + } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] - [WorkItem("https://github.com/dotnet/roslyn/issues/44126")] - public async Task RemoveParameters_ImplicitObjectCreation() - { - var markup = """ - public class C - { - public $$C(int a, string b) { } + [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WorkItem("https://github.com/dotnet/roslyn/issues/44126")] + public async Task RemoveParameters_ImplicitObjectCreation() + { + var markup = """ + public class C + { + public $$C(int a, string b) { } - void M() - { - C c = new(1, "b"); - } - } - """; - var updatedSignature = new[] { 1 }; - var updatedCode = """ - public class C + void M() { - public C(string b) { } - - void M() - { - C c = new("b"); - } + C c = new(1, "b"); } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + var updatedSignature = new[] { 1 }; + var updatedCode = """ + public class C + { + public C(string b) { } - [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] - [WorkItem("https://github.com/dotnet/roslyn/issues/66547")] - public async Task RemoveParameters_SpecialSymbolNamedParameter() - { - var markup = """ - void $$m(object? param, bool @new = true) + void M() { + C c = new("b"); } + } + """; - m(null, @new: false); - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); + } - var updatedSignature = new[] { 1 }; - var updatedCode = """ - void m(bool @new = true) - { - } + [Fact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WorkItem("https://github.com/dotnet/roslyn/issues/66547")] + public async Task RemoveParameters_SpecialSymbolNamedParameter() + { + var markup = """ + void $$m(object? param, bool @new = true) + { + } - m(@new: false); - """; + m(null, @new: false); + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); - } + var updatedSignature = new[] { 1 }; + var updatedCode = """ + void m(bool @new = true) + { + } + + m(@new: false); + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: updatedSignature, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.Cascading.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.Cascading.cs index 66c240851c7e9..60a67ef49bee3 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.Cascading.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.Cascading.cs @@ -7,388 +7,386 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task ReorderParameters_Cascade_ToImplementedMethod() { - [Fact] - public async Task ReorderParameters_Cascade_ToImplementedMethod() - { - var markup = """ - interface I - { - void M(int x, string y); - } - - class C : I - { - $$public void M(int x, string y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - interface I - { - void M(string y, int x); - } - - class C : I - { - public void M(string y, int x) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParameters_Cascade_ToImplementedMethod_WithTuples() - { - var markup = """ - interface I - { - void M((int, int) x, (string a, string b) y); - } - - class C : I - { - $$public void M((int, int) x, (string a, string b) y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - interface I - { - void M((string a, string b) y, (int, int) x); - } - - class C : I - { - public void M((string a, string b) y, (int, int) x) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParameters_Cascade_ToImplementingMethod() - { - var markup = """ - interface I - { - $$void M(int x, string y); - } - - class C : I - { - public void M(int x, string y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - interface I - { - void M(string y, int x); - } - - class C : I - { - public void M(string y, int x) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParameters_Cascade_ToOverriddenMethod() - { - var markup = """ - class B - { - public virtual void M(int x, string y) - { } - } - - class D : B - { - $$public override void M(int x, string y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class B - { - public virtual void M(string y, int x) - { } - } - - class D : B - { - public override void M(string y, int x) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParameters_Cascade_ToOverridingMethod() - { - var markup = """ - class B - { - $$public virtual void M(int x, string y) - { } - } - - class D : B - { - public override void M(int x, string y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class B - { - public virtual void M(string y, int x) - { } - } - - class D : B - { - public override void M(string y, int x) - { } - } - """; + var markup = """ + interface I + { + void M(int x, string y); + } + + class C : I + { + $$public void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + interface I + { + void M(string y, int x); + } + + class C : I + { + public void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParameters_Cascade_ToImplementedMethod_WithTuples() + { + var markup = """ + interface I + { + void M((int, int) x, (string a, string b) y); + } + + class C : I + { + $$public void M((int, int) x, (string a, string b) y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + interface I + { + void M((string a, string b) y, (int, int) x); + } + + class C : I + { + public void M((string a, string b) y, (int, int) x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParameters_Cascade_ToOverriddenMethod_Transitive() - { - var markup = """ - class B - { - public virtual void M(int x, string y) - { } - } + [Fact] + public async Task ReorderParameters_Cascade_ToImplementingMethod() + { + var markup = """ + interface I + { + $$void M(int x, string y); + } + + class C : I + { + public void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + interface I + { + void M(string y, int x); + } + + class C : I + { + public void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class D : B - { - public override void M(int x, string y) - { } - } + [Fact] + public async Task ReorderParameters_Cascade_ToOverriddenMethod() + { + var markup = """ + class B + { + public virtual void M(int x, string y) + { } + } + + class D : B + { + $$public override void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class B + { + public virtual void M(string y, int x) + { } + } + + class D : B + { + public override void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class D2 : D - { - $$public override void M(int x, string y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class B - { - public virtual void M(string y, int x) - { } - } + [Fact] + public async Task ReorderParameters_Cascade_ToOverridingMethod() + { + var markup = """ + class B + { + $$public virtual void M(int x, string y) + { } + } + + class D : B + { + public override void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class B + { + public virtual void M(string y, int x) + { } + } + + class D : B + { + public override void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class D : B - { - public override void M(string y, int x) - { } - } + [Fact] + public async Task ReorderParameters_Cascade_ToOverriddenMethod_Transitive() + { + var markup = """ + class B + { + public virtual void M(int x, string y) + { } + } + + class D : B + { + public override void M(int x, string y) + { } + } + + class D2 : D + { + $$public override void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class B + { + public virtual void M(string y, int x) + { } + } + + class D : B + { + public override void M(string y, int x) + { } + } + + class D2 : D + { + public override void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class D2 : D - { - public override void M(string y, int x) - { } - } - """; + [Fact] + public async Task ReorderParameters_Cascade_ToOverridingMethod_Transitive() + { + var markup = """ + class B + { + $$public virtual void M(int x, string y) + { } + } + + class D : B + { + public override void M(int x, string y) + { } + } + + class D2 : D + { + public override void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class B + { + public virtual void M(string y, int x) + { } + } + + class D : B + { + public override void M(string y, int x) + { } + } + + class D2 : D + { + public override void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParameters_Cascade_ToMethods_Complex() + { + //// B I I2 + //// \ / \ / + //// D (I3) + //// / \ \ + //// $$D2 D3 C + + var markup = """ + class B { public virtual void M(int x, string y) { } } + class D : B, I { public override void M(int x, string y) { } } + class D2 : D { public override void $$M(int x, string y) { } } + class D3 : D { public override void M(int x, string y) { } } + interface I { void M(int x, string y); } + interface I2 { void M(int x, string y); } + interface I3 : I, I2 { } + class C : I3 { public void M(int x, string y) { } } + """; + + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class B { public virtual void M(string y, int x) { } } + class D : B, I { public override void M(string y, int x) { } } + class D2 : D { public override void M(string y, int x) { } } + class D3 : D { public override void M(string y, int x) { } } + interface I { void M(string y, int x); } + interface I2 { void M(string y, int x); } + interface I3 : I, I2 { } + class C : I3 { public void M(string y, int x) { } } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParameters_Cascade_ToOverridingMethod_Transitive() - { - var markup = """ - class B + [Fact] + public async Task ReorderParameters_Cascade_ToMethods_WithDifferentParameterNames() + { + var markup = """ + public class B + { + /// + /// + public virtual int M(int x, string y) { - $$public virtual void M(int x, string y) - { } + return 1; } + } - class D : B + public class D : B + { + /// + /// + public override int M(int a, string b) { - public override void M(int x, string y) - { } + return 1; } + } - class D2 : D + public class D2 : D + { + /// + /// + public override int $$M(int y, string x) { - public override void M(int x, string y) - { } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class B - { - public virtual void M(string y, int x) - { } - } + M(1, "Two"); + ((D)this).M(1, "Two"); + ((B)this).M(1, "Two"); - class D : B - { - public override void M(string y, int x) - { } - } + M(1, x: "Two"); + ((D)this).M(1, b: "Two"); + ((B)this).M(1, y: "Two"); - class D2 : D - { - public override void M(string y, int x) - { } + return 1; } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParameters_Cascade_ToMethods_Complex() - { - //// B I I2 - //// \ / \ / - //// D (I3) - //// / \ \ - //// $$D2 D3 C - - var markup = """ - class B { public virtual void M(int x, string y) { } } - class D : B, I { public override void M(int x, string y) { } } - class D2 : D { public override void $$M(int x, string y) { } } - class D3 : D { public override void M(int x, string y) { } } - interface I { void M(int x, string y); } - interface I2 { void M(int x, string y); } - interface I3 : I, I2 { } - class C : I3 { public void M(int x, string y) { } } - """; - - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class B { public virtual void M(string y, int x) { } } - class D : B, I { public override void M(string y, int x) { } } - class D2 : D { public override void M(string y, int x) { } } - class D3 : D { public override void M(string y, int x) { } } - interface I { void M(string y, int x); } - interface I2 { void M(string y, int x); } - interface I3 : I, I2 { } - class C : I3 { public void M(string y, int x) { } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParameters_Cascade_ToMethods_WithDifferentParameterNames() - { - var markup = """ - public class B + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + public class B + { + /// + /// + public virtual int M(string y, int x) { - /// - /// - public virtual int M(int x, string y) - { - return 1; - } + return 1; } + } - public class D : B + public class D : B + { + /// + /// + public override int M(string b, int a) { - /// - /// - public override int M(int a, string b) - { - return 1; - } + return 1; } + } - public class D2 : D + public class D2 : D + { + /// + /// + public override int M(string x, int y) { - /// - /// - public override int $$M(int y, string x) - { - M(1, "Two"); - ((D)this).M(1, "Two"); - ((B)this).M(1, "Two"); - - M(1, x: "Two"); - ((D)this).M(1, b: "Two"); - ((B)this).M(1, y: "Two"); - - return 1; - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - public class B - { - /// - /// - public virtual int M(string y, int x) - { - return 1; - } - } + M("Two", 1); + ((D)this).M("Two", 1); + ((B)this).M("Two", 1); - public class D : B - { - /// - /// - public override int M(string b, int a) - { - return 1; - } - } + M(x: "Two", y: 1); + ((D)this).M(b: "Two", a: 1); + ((B)this).M(y: "Two", x: 1); - public class D2 : D - { - /// - /// - public override int M(string x, int y) - { - M("Two", 1); - ((D)this).M("Two", 1); - ((B)this).M("Two", 1); - - M(x: "Two", y: 1); - ((D)this).M(b: "Two", a: 1); - ((B)this).M(y: "Two", x: 1); - - return 1; - } + return 1; } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationErrors.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationErrors.cs index e77c9faef8170..e37bdba03425c 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationErrors.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationErrors.cs @@ -8,69 +8,67 @@ using Microsoft.CodeAnalysis.ChangeSignature; using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task ReorderMethodParameters_InvokeOnClassName_ShouldFail() { - [Fact] - public async Task ReorderMethodParameters_InvokeOnClassName_ShouldFail() - { - var markup = """ - using System; - class MyClass$$ + var markup = """ + using System; + class MyClass$$ + { + public void Goo(int x, string y) { - public void Goo(int x, string y) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); + } - [Fact] - public async Task ReorderMethodParameters_InvokeOnField_ShouldFail() - { - var markup = """ - using System; - class MyClass - { - int t$$ = 2; + [Fact] + public async Task ReorderMethodParameters_InvokeOnField_ShouldFail() + { + var markup = """ + using System; + class MyClass + { + int t$$ = 2; - public void Goo(int x, string y) - { - } + public void Goo(int x, string y) + { } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); + } - [Fact] - public async Task ReorderMethodParameters_CanBeStartedEvenWithNoParameters() - { - var markup = @"class C { void $$M() { } }"; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: true); - } + [Fact] + public async Task ReorderMethodParameters_CanBeStartedEvenWithNoParameters() + { + var markup = @"class C { void $$M() { } }"; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: true); + } - [Fact] - public async Task ReorderMethodParameters_InvokeOnOverloadedOperator_ShouldFail() - { - var markup = """ - class C + [Fact] + public async Task ReorderMethodParameters_InvokeOnOverloadedOperator_ShouldFail() + { + var markup = """ + class C + { + public static C $$operator +(C a, C b) { - public static C $$operator +(C a, C b) - { - return null; - } + return null; } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); } } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationLocation.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationLocation.cs index 0da679565e7e6..eb2c1478207da 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationLocation.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.InvocationLocation.cs @@ -8,943 +8,941 @@ using Microsoft.CodeAnalysis.ChangeSignature; using Microsoft.CodeAnalysis.Editor.UnitTests.ChangeSignature; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests - { - #region Methods - - [Fact] - public async Task ReorderMethodParameters_InvokeBeforeMethodName() - { - var markup = """ - using System; - class MyClass - { - public void $$Goo(int x, string y) - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(string y, int x) - { - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeInParameterList() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, $$string y) - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(string y, int x) - { - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeAfterParameterList() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y)$$ - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(string y, int x) - { - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeBeforeMethodDeclaration() - { - var markup = """ - using System; - class MyClass - { - $$public void Goo(int x, string y) - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(string y, int x) - { - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnMetadataReference_InIdentifier_ShouldFail() - { - var markup = """ - class C - { - static void Main(string[] args) - { - ((System.IFormattable)null).ToSt$$ring("test", null); - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnMetadataReference_AtBeginningOfInvocation_ShouldFail() - { - var markup = """ - class C - { - static void Main(string[] args) - { - $$((System.IFormattable)null).ToString("test", null); - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnMetadataReference_InArgumentsOfInvocation_ShouldFail() - { - var markup = """ - class C - { - static void Main(string[] args) - { - ((System.IFormattable)null).ToString("test",$$ null); - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnMetadataReference_AfterInvocation_ShouldFail() - { - var markup = """ - class C - { - string s = ((System.IFormattable)null).ToString("test", null)$$; - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeInMethodBody_ViaCommand() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - $$ - } - } - """; - - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, markup, expectedSuccess: false); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeInMethodBody_ViaSmartTag() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - [||] - } - } - """; - - await TestMissingAsync(markup); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_BeginningOfIdentifier() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - $$Bar(x, y); - } - - public void Bar(int x, string y) - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar(y, x); - } - - public void Bar(string y, int x) - { - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_ArgumentList() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - $$Bar(x, y); - } - - public void Bar(int x, string y) - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar(y, x); - } - - public void Bar(string y, int x) - { - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls1() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar($$Baz(x, y), y); - } - - public void Bar(int x, string y) - { - } - - public int Baz(int x, string y) - { - return 1; - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar(Baz(y, x), y); - } - - public void Bar(int x, string y) - { - } - - public int Baz(string y, int x) - { - return 1; - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls2() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar$$(Baz(x, y), y); - } - - public void Bar(int x, string y) - { - } - - public int Baz(int x, string y) - { - return 1; - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar(y, Baz(x, y)); - } - - public void Bar(string y, int x) - { - } - - public int Baz(int x, string y) - { - return 1; - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls3() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar(Baz(x, y), $$y); - } - - public void Bar(int x, string y) - { - } - - public int Baz(int x, string y) - { - return 1; - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - Bar(y, Baz(x, y)); - } - - public void Bar(string y, int x) - { - } - - public int Baz(int x, string y) - { - return 1; - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_Attribute() - { - var markup = """ - using System; - - [$$My(1, 2)] - class MyAttribute : Attribute - { - public MyAttribute(int x, int y) - { - } + #region Methods + + [Fact] + public async Task ReorderMethodParameters_InvokeBeforeMethodName() + { + var markup = """ + using System; + class MyClass + { + public void $$Goo(int x, string y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeInParameterList() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, $$string y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeAfterParameterList() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y)$$ + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeBeforeMethodDeclaration() + { + var markup = """ + using System; + class MyClass + { + $$public void Goo(int x, string y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnMetadataReference_InIdentifier_ShouldFail() + { + var markup = """ + class C + { + static void Main(string[] args) + { + ((System.IFormattable)null).ToSt$$ring("test", null); + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnMetadataReference_AtBeginningOfInvocation_ShouldFail() + { + var markup = """ + class C + { + static void Main(string[] args) + { + $$((System.IFormattable)null).ToString("test", null); + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnMetadataReference_InArgumentsOfInvocation_ShouldFail() + { + var markup = """ + class C + { + static void Main(string[] args) + { + ((System.IFormattable)null).ToString("test",$$ null); + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.DefinedInMetadata); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnMetadataReference_AfterInvocation_ShouldFail() + { + var markup = """ + class C + { + string s = ((System.IFormattable)null).ToString("test", null)$$; + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, expectedSuccess: false, expectedFailureReason: ChangeSignatureFailureKind.IncorrectKind); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeInMethodBody_ViaCommand() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + $$ + } + } + """; + + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, markup, expectedSuccess: false); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeInMethodBody_ViaSmartTag() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + [||] + } + } + """; + + await TestMissingAsync(markup); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_BeginningOfIdentifier() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + $$Bar(x, y); + } + + public void Bar(int x, string y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar(y, x); + } + + public void Bar(string y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_ArgumentList() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + $$Bar(x, y); + } + + public void Bar(int x, string y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar(y, x); + } + + public void Bar(string y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls1() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar($$Baz(x, y), y); + } + + public void Bar(int x, string y) + { + } + + public int Baz(int x, string y) + { + return 1; + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar(Baz(y, x), y); + } + + public void Bar(int x, string y) + { + } + + public int Baz(string y, int x) + { + return 1; + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls2() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar$$(Baz(x, y), y); + } + + public void Bar(int x, string y) + { + } + + public int Baz(int x, string y) + { + return 1; + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar(y, Baz(x, y)); + } + + public void Bar(string y, int x) + { + } + + public int Baz(int x, string y) + { + return 1; + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_NestedCalls3() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar(Baz(x, y), $$y); + } + + public void Bar(int x, string y) + { + } + + public int Baz(int x, string y) + { + return 1; + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(int x, string y) + { + Bar(y, Baz(x, y)); + } + + public void Bar(string y, int x) + { + } + + public int Baz(int x, string y) + { + return 1; + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_Attribute() + { + var markup = """ + using System; + + [$$My(1, 2)] + class MyAttribute : Attribute + { + public MyAttribute(int x, int y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + + [My(2, 1)] + class MyAttribute : Attribute + { + public MyAttribute(int y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_OnlyHasCandidateSymbols() + { + var markup = """ + class Test + { + void M(int x, string y) { } + void M(int x, double y) { } + void M2() { $$M("s", 1); } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Test + { + void M(string y, int x) { } + void M(int x, double y) { } + void M2() { M(1, "s"); } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_CallToOtherConstructor() + { + var markup = """ + class Program + { + public Program(int x, int y) : this(1, 2, 3)$$ + { + } + + public Program(int x, int y, int z) + { + } + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + class Program + { + public Program(int x, int y) : this(3, 2, 1) + { + } + + public Program(int z, int y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_InvokeOnReference_CallToBaseConstructor() + { + var markup = """ + class B + { + public B(int a, int b) + { + } + } + + class D : B + { + public D(int x, int y) : base(1, 2)$$ + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class B + { + public B(int b, int a) + { } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; + } - [My(2, 1)] - class MyAttribute : Attribute + class D : B + { + public D(int x, int y) : base(2, 1) { - public MyAttribute(int y, int x) - { - } } - """; + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + #endregion + + #region Indexers + + [Fact] + public async Task ReorderIndexerParameters_InvokeAtBeginningOfDeclaration() + { + var markup = """ + class Program + { + $$int this[int x, string y] + { + get { return 5; } + set { } + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + int this[string y, int x] + { + get { return 5; } + set { } + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } + + [Fact] + public async Task ReorderIndexerParameters_InParameters() + { + var markup = """ + class Program + { + int this[int x, $$string y] + { + get { return 5; } + set { } + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + int this[string y, int x] + { + get { return 5; } + set { } + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderIndexerParameters_InvokeAtEndOfDeclaration() + { + var markup = """ + class Program + { + int this[int x, string y]$$ + { + get { return 5; } + set { } + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + int this[string y, int x] + { + get { return 5; } + set { } + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_OnlyHasCandidateSymbols() - { - var markup = """ - class Test + [Fact] + public async Task ReorderIndexerParameters_InvokeInAccessor() + { + var markup = """ + class Program + { + int this[int x, string y] { - void M(int x, string y) { } - void M(int x, double y) { } - void M2() { $$M("s", 1); } + get { return $$5; } + set { } } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Test + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + int this[string y, int x] { - void M(string y, int x) { } - void M(int x, double y) { } - void M2() { M(1, "s"); } + get { return 5; } + set { } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_CallToOtherConstructor() - { - var markup = """ - class Program + [Fact] + public async Task ReorderIndexerParameters_InvokeOnReference_BeforeTarget() + { + var markup = """ + class Program + { + void M(Program p) { - public Program(int x, int y) : this(1, 2, 3)$$ - { - } + var t = $$p[5, "test"]; + } - public Program(int x, int y, int z) - { - } + int this[int x, string y] + { + get { return 5; } + set { } } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - class Program + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + void M(Program p) { - public Program(int x, int y) : this(3, 2, 1) - { - } + var t = p["test", 5]; + } - public Program(int z, int y, int x) - { - } + int this[string y, int x] + { + get { return 5; } + set { } } - """; + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderIndexerParameters_InvokeOnReference_InArgumentList() + { + var markup = """ + class Program + { + void M(Program p) + { + var t = p[5, "test"$$]; + } + + int this[int x, string y] + { + get { return 5; } + set { } + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + void M(Program p) + { + var t = p["test", 5]; + } - [Fact] - public async Task ReorderMethodParameters_InvokeOnReference_CallToBaseConstructor() - { - var markup = """ - class B + int this[string y, int x] { - public B(int a, int b) - { - } + get { return 5; } + set { } } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } + + #endregion - class D : B + #region Delegates + + [Fact] + public async Task ReorderDelegateParameters_ObjectCreation1() + { + var markup = """ + public class C + { + void T() { - public D(int x, int y) : base(1, 2)$$ - { - } + var d = new $$D((x, y) => { }); } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class B + + public delegate void D(int x, int y); + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + public class C + { + void T() { - public B(int b, int a) - { - } + var d = new D((y, x) => { }); } - class D : B + public delegate void D(int y, int x); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } + + [Fact] + public async Task ReorderDelegateParameters_ObjectCreation2() + { + var markup = """ + public class CD + { + public delegate void D(T t, T u); + } + class Test + { + public void M() + { + var dele = new CD.$$D((int x, int y) => { }); + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + public class CD + { + public delegate void D(T u, T t); + } + class Test + { + public void M() + { + var dele = new CD.D((int y, int x) => { }); + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } + + #endregion + + #region CodeRefactoring + [Fact] + public async Task ReorderMethodParameters_CodeRefactoring_InvokeBeforeMethodName() + { + var markup = """ + using System; + class MyClass + { + public void [||]Goo(int x, string y) + { + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) + { + } + } + """; + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: true, updatedSignature: permutation, expectedCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_CodeRefactoring_NotInMethodBody() + { + var markup = """ + using System; + class MyClass + { + public void Goo(int x, string y) { - public D(int x, int y) : base(2, 1) - { - } + [||] } - """; + } + """; + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderMethodParameters_CodeRefactoring_InLambda() + { + var markup = """ + class Program + { + void M(int x) + { + System.Func f = (a, b)[||] => { return a; }; + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + void M(int x) + { + System.Func f = (b, a) => { return a; }; + } + } + """; + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: true, updatedSignature: permutation, expectedCode: updatedCode); + } - #endregion - - #region Indexers - - [Fact] - public async Task ReorderIndexerParameters_InvokeAtBeginningOfDeclaration() - { - var markup = """ - class Program - { - $$int this[int x, string y] - { - get { return 5; } - set { } - } + [Fact] + public async Task ReorderMethodParameters_CodeRefactoring_NotInLambdaBody() + { + var markup = """ + class Program + { + void M(int x) + { + System.Func f = (a, b) => { [||]return a; }; } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program + } + """; + await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); + } + + [Fact] + public async Task ReorderMethodParameters_CodeRefactoring_AtCallSite_ViaCommand() + { + var markup = """ + class Program + { + void M(int x, int y) + { + M($$5, 6); + } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + void M(int y, int x) + { + M(6, 5); + } + } + """; + await TestChangeSignatureViaCommandAsync( + LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode); + } + + [Fact] + public async Task ReorderMethodParameters_CodeRefactoring_AtCallSite_ViaCodeAction() + { + var markup = """ + class Program + { + void M(int x, int y) { - int this[string y, int x] - { - get { return 5; } - set { } - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } - - [Fact] - public async Task ReorderIndexerParameters_InParameters() - { - var markup = """ - class Program - { - int this[int x, $$string y] - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - int this[string y, int x] - { - get { return 5; } - set { } - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); - } - - [Fact] - public async Task ReorderIndexerParameters_InvokeAtEndOfDeclaration() - { - var markup = """ - class Program - { - int this[int x, string y]$$ - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - int this[string y, int x] - { - get { return 5; } - set { } - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } - - [Fact] - public async Task ReorderIndexerParameters_InvokeInAccessor() - { - var markup = """ - class Program - { - int this[int x, string y] - { - get { return $$5; } - set { } - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - int this[string y, int x] - { - get { return 5; } - set { } - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderIndexerParameters_InvokeOnReference_BeforeTarget() - { - var markup = """ - class Program - { - void M(Program p) - { - var t = $$p[5, "test"]; - } - - int this[int x, string y] - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - void M(Program p) - { - var t = p["test", 5]; - } - - int this[string y, int x] - { - get { return 5; } - set { } - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderIndexerParameters_InvokeOnReference_InArgumentList() - { - var markup = """ - class Program - { - void M(Program p) - { - var t = p[5, "test"$$]; - } - - int this[int x, string y] - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - void M(Program p) - { - var t = p["test", 5]; - } - - int this[string y, int x] - { - get { return 5; } - set { } - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } - - #endregion - - #region Delegates - - [Fact] - public async Task ReorderDelegateParameters_ObjectCreation1() - { - var markup = """ - public class C - { - void T() - { - var d = new $$D((x, y) => { }); - } - - public delegate void D(int x, int y); - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - public class C - { - void T() - { - var d = new D((y, x) => { }); - } - - public delegate void D(int y, int x); - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } - - [Fact] - public async Task ReorderDelegateParameters_ObjectCreation2() - { - var markup = """ - public class CD - { - public delegate void D(T t, T u); - } - class Test - { - public void M() - { - var dele = new CD.$$D((int x, int y) => { }); - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - public class CD - { - public delegate void D(T u, T t); - } - class Test - { - public void M() - { - var dele = new CD.D((int y, int x) => { }); - } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - #endregion - - #region CodeRefactoring - [Fact] - public async Task ReorderMethodParameters_CodeRefactoring_InvokeBeforeMethodName() - { - var markup = """ - using System; - class MyClass - { - public void [||]Goo(int x, string y) - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass - { - public void Goo(string y, int x) - { - } - } - """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: true, updatedSignature: permutation, expectedCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_CodeRefactoring_NotInMethodBody() - { - var markup = """ - using System; - class MyClass - { - public void Goo(int x, string y) - { - [||] - } - } - """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } - - [Fact] - public async Task ReorderMethodParameters_CodeRefactoring_InLambda() - { - var markup = """ - class Program - { - void M(int x) - { - System.Func f = (a, b)[||] => { return a; }; - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - void M(int x) - { - System.Func f = (b, a) => { return a; }; - } - } - """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: true, updatedSignature: permutation, expectedCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_CodeRefactoring_NotInLambdaBody() - { - var markup = """ - class Program - { - void M(int x) - { - System.Func f = (a, b) => { [||]return a; }; - } - } - """; - await TestChangeSignatureViaCodeActionAsync(markup, expectedCodeAction: false); - } - - [Fact] - public async Task ReorderMethodParameters_CodeRefactoring_AtCallSite_ViaCommand() - { - var markup = """ - class Program - { - void M(int x, int y) - { - M($$5, 6); - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program - { - void M(int y, int x) - { - M(6, 5); - } - } - """; - await TestChangeSignatureViaCommandAsync( - LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderMethodParameters_CodeRefactoring_AtCallSite_ViaCodeAction() - { - var markup = """ - class Program - { - void M(int x, int y) - { - M([||]5, 6); - } - } - """; - await TestMissingAsync(markup); - } - - #endregion + M([||]5, 6); + } + } + """; + await TestMissingAsync(markup); } + + #endregion } diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.cs index 522a17bc28c57..ae84381ad6854 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/ReorderParametersTests.cs @@ -10,1082 +10,1081 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ChangeSignature; + +[Trait(Traits.Feature, Traits.Features.ChangeSignature)] +public partial class ChangeSignatureTests : AbstractChangeSignatureTests { - [Trait(Traits.Feature, Traits.Features.ChangeSignature)] - public partial class ChangeSignatureTests : AbstractChangeSignatureTests + [Fact] + public async Task ReorderLocalFunctionParametersAndArguments_OnDeclaration() { - [Fact] - public async Task ReorderLocalFunctionParametersAndArguments_OnDeclaration() - { - var markup = """ - using System; - class MyClass - { - public void M() + var markup = """ + using System; + class MyClass + { + public void M() + { + Goo(1, 2); + void $$Goo(int x, string y) { - Goo(1, 2); - void $$Goo(int x, string y) - { - } } } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void M() { - public void M() + Goo(2, 1); + void Goo(string y, int x) { - Goo(2, 1); - void Goo(string y, int x) - { - } } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderLocalFunctionParametersAndArguments_OnInvocation() - { - var markup = """ - using System; - class MyClass + [Fact] + public async Task ReorderLocalFunctionParametersAndArguments_OnInvocation() + { + var markup = """ + using System; + class MyClass + { + public void M() { - public void M() + $$Goo(1, null); + void Goo(int x, string y) { - $$Goo(1, null); - void Goo(int x, string y) - { - } } } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void M() { - public void M() + Goo(null, 1); + void Goo(string y, int x) { - Goo(null, 1); - void Goo(string y, int x) - { - } } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderMethodParameters() - { - var markup = """ - using System; - class MyClass + [Fact] + public async Task ReorderMethodParameters() + { + var markup = """ + using System; + class MyClass + { + public void $$Goo(int x, string y) { - public void $$Goo(int x, string y) - { - } } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) { - public void Goo(string y, int x) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderMethodParametersAndArguments() - { - var markup = """ - using System; - class MyClass + [Fact] + public async Task ReorderMethodParametersAndArguments() + { + var markup = """ + using System; + class MyClass + { + public void $$Goo(int x, string y) { - public void $$Goo(int x, string y) - { - Goo(3, "hello"); - } + Goo(3, "hello"); } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public void Goo(string y, int x) { - public void Goo(string y, int x) - { - Goo("hello", 3); - } + Goo("hello", 3); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderMethodParametersAndArgumentsOfNestedCalls() - { - var markup = """ - using System; - class MyClass + [Fact] + public async Task ReorderMethodParametersAndArgumentsOfNestedCalls() + { + var markup = """ + using System; + class MyClass + { + public int $$Goo(int x, string y) { - public int $$Goo(int x, string y) - { - return Goo(Goo(4, "inner"), "outer"); - } + return Goo(Goo(4, "inner"), "outer"); } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; + class MyClass + { + public int Goo(string y, int x) { - public int Goo(string y, int x) - { - return Goo("outer", Goo("inner", 4)); - } + return Goo("outer", Goo("inner", 4)); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderConstructorParametersAndArguments() - { - var markup = """ - using System; + [Fact] + public async Task ReorderConstructorParametersAndArguments() + { + var markup = """ + using System; - class MyClass2 : MyClass + class MyClass2 : MyClass + { + public MyClass2() : base(5, "test2") { - public MyClass2() : base(5, "test2") - { - } } + } - class MyClass + class MyClass + { + public MyClass() : this(2, "test") { - public MyClass() : this(2, "test") - { - } - - public $$MyClass(int x, string y) - { - var t = new MyClass(x, y); - } } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - class MyClass2 : MyClass + public $$MyClass(int x, string y) { - public MyClass2() : base("test2", 5) - { - } + var t = new MyClass(x, y); } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; - class MyClass + class MyClass2 : MyClass + { + public MyClass2() : base("test2", 5) { - public MyClass() : this("test", 2) - { - } - - public MyClass(string y, int x) - { - var t = new MyClass(y, x); - } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44126")] - public async Task ReorderConstructorParametersAndArguments_ImplicitObjectCreation() - { - var markup = """ - using System; + } - class MyClass2 : MyClass + class MyClass + { + public MyClass() : this("test", 2) { - public MyClass2() : base(5, "test2") - { - } } - class MyClass + public MyClass(string y, int x) { - public MyClass() : this(2, "test") - { - } - - public MyClass(int x, string y) - { - MyClass t = new$$(x, y); - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - using System; - - class MyClass2 : MyClass - { - public MyClass2() : base("test2", 5) - { - } + var t = new MyClass(y, x); } + } + """; - class MyClass - { - public MyClass() : this("test", 2) - { - } - - public MyClass(string y, int x) - { - MyClass t = new(y, x); - } - } - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44126")] + public async Task ReorderConstructorParametersAndArguments_ImplicitObjectCreation() + { + var markup = """ + using System; - [Fact] - public async Task ReorderAttributeConstructorParametersAndArguments() - { - var markup = """ - [My("test", 8)] - class MyClass + class MyClass2 : MyClass + { + public MyClass2() : base(5, "test2") { } + } - class MyAttribute : System.Attribute - { - public MyAttribute(string x, int y)$$ - { - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - [My(8, "test")] - class MyClass + class MyClass + { + public MyClass() : this(2, "test") { } - class MyAttribute : System.Attribute + public MyClass(int x, string y) { - public MyAttribute(int y, string x) - { - } + MyClass t = new$$(x, y); } - """; + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + using System; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderExtensionMethodParametersAndArguments_StaticCall() - { - var markup = """ - public class C + class MyClass2 : MyClass + { + public MyClass2() : base("test2", 5) { - static void Main(string[] args) - { - CExt.M(new C(), 1, 2, "three", "four", "five"); - } } + } - public static class CExt - { - public static void M(this $$C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c") - { } - } - """; - var permutation = new[] { 0, 2, 1, 5, 4, 3 }; - var updatedCode = """ - public class C + class MyClass + { + public MyClass() : this("test", 2) { - static void Main(string[] args) - { - CExt.M(new C(), 2, 1, "five", "four", "three"); - } } - public static class CExt + public MyClass(string y, int x) { - public static void M(this C goo, int y, int x, string c = "test_c", string b = "test_b", string a = "test_a") - { } + MyClass t = new(y, x); } - """; + } + """; - // Although the `ParameterConfig` has 0 for the `SelectedIndex`, the UI dialog will make an adjustment - // and select parameter `y` instead because the `this` parameter cannot be moved or removed. - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderExtensionMethodParametersAndArguments_ExtensionCall() - { - var markup = """ - public class C - { - static void Main(string[] args) - { - new C().M(1, 2, "three", "four", "five"); - } - } + [Fact] + public async Task ReorderAttributeConstructorParametersAndArguments() + { + var markup = """ + [My("test", 8)] + class MyClass + { + } - public static class CExt - { - public static void M(this C goo, int x$$, int y, string a = "test_a", string b = "test_b", string c = "test_c") - { } - } - """; - var permutation = new[] { 0, 2, 1, 5, 4, 3 }; - var updatedCode = """ - public class C + class MyAttribute : System.Attribute + { + public MyAttribute(string x, int y)$$ { - static void Main(string[] args) - { - new C().M(2, 1, "five", "four", "three"); - } } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + [My(8, "test")] + class MyClass + { + } - public static class CExt + class MyAttribute : System.Attribute + { + public MyAttribute(int y, string x) { - public static void M(this C goo, int y, int x, string c = "test_c", string b = "test_b", string a = "test_a") - { } } - """; + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); - } + [Fact] + public async Task ReorderExtensionMethodParametersAndArguments_StaticCall() + { + var markup = """ + public class C + { + static void Main(string[] args) + { + CExt.M(new C(), 1, 2, "three", "four", "five"); + } + } + + public static class CExt + { + public static void M(this $$C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c") + { } + } + """; + var permutation = new[] { 0, 2, 1, 5, 4, 3 }; + var updatedCode = """ + public class C + { + static void Main(string[] args) + { + CExt.M(new C(), 2, 1, "five", "four", "three"); + } + } + + public static class CExt + { + public static void M(this C goo, int y, int x, string c = "test_c", string b = "test_b", string a = "test_a") + { } + } + """; + + // Although the `ParameterConfig` has 0 for the `SelectedIndex`, the UI dialog will make an adjustment + // and select parameter `y` instead because the `this` parameter cannot be moved or removed. + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } + + [Fact] + public async Task ReorderExtensionMethodParametersAndArguments_ExtensionCall() + { + var markup = """ + public class C + { + static void Main(string[] args) + { + new C().M(1, 2, "three", "four", "five"); + } + } + + public static class CExt + { + public static void M(this C goo, int x$$, int y, string a = "test_a", string b = "test_b", string c = "test_c") + { } + } + """; + var permutation = new[] { 0, 2, 1, 5, 4, 3 }; + var updatedCode = """ + public class C + { + static void Main(string[] args) + { + new C().M(2, 1, "five", "four", "three"); + } + } + + public static class CExt + { + public static void M(this C goo, int y, int x, string c = "test_c", string b = "test_b", string a = "test_a") + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 1); + } - [Fact] - public async Task ReorderParamsMethodParametersAndArguments_ParamsAsArray() - { - var markup = """ - public class C + [Fact] + public async Task ReorderParamsMethodParametersAndArguments_ParamsAsArray() + { + var markup = """ + public class C + { + void $$M(int x, int y, params int[] p) { - void $$M(int x, int y, params int[] p) - { - M(x, y, new[] { 1, 2, 3 }); - } + M(x, y, new[] { 1, 2, 3 }); } - """; - var permutation = new[] { 1, 0, 2 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 1, 0, 2 }; + var updatedCode = """ + public class C + { + void M(int y, int x, params int[] p) { - void M(int y, int x, params int[] p) - { - M(y, x, new[] { 1, 2, 3 }); - } + M(y, x, new[] { 1, 2, 3 }); } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamsMethodParametersAndArguments_ParamsExpanded() - { - var markup = """ - public class C + [Fact] + public async Task ReorderParamsMethodParametersAndArguments_ParamsExpanded() + { + var markup = """ + public class C + { + void $$M(int x, int y, params int[] p) { - void $$M(int x, int y, params int[] p) - { - M(x, y, 1, 2, 3); - } + M(x, y, 1, 2, 3); } - """; - var permutation = new[] { 1, 0, 2 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 1, 0, 2 }; + var updatedCode = """ + public class C + { + void M(int y, int x, params int[] p) { - void M(int y, int x, params int[] p) - { - M(y, x, 1, 2, 3); - } + M(y, x, 1, 2, 3); } - """; + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderExtensionAndParamsMethodParametersAndArguments_VariedCallsites() + { + var markup = """ + public class C + { + static void Main(string[] args) + { + CExt.M(new C(), 1, 2, "three", "four", "five", new[] { 6, 7, 8 }); + CExt.M(new C(), 1, 2, "three", "four", "five", 6, 7, 8); + new C().M(1, 2, "three", "four", "five", new[] { 6, 7, 8 }); + new C().M(1, 2, "three", "four", "five", 6, 7, 8); + } + } + + public static class CExt + { + public static void $$M(this C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c", params int[] p) + { } + } + """; + var permutation = new[] { 0, 2, 1, 5, 4, 3, 6 }; + var updatedCode = """ + public class C + { + static void Main(string[] args) + { + CExt.M(new C(), 2, 1, "five", "four", "three", new[] { 6, 7, 8 }); + CExt.M(new C(), 2, 1, "five", "four", "three", 6, 7, 8); + new C().M(2, 1, "five", "four", "three", new[] { 6, 7, 8 }); + new C().M(2, 1, "five", "four", "three", 6, 7, 8); + } + } + + public static class CExt + { + public static void M(this C goo, int y, int x, string c = "test_c", string b = "test_b", string a = "test_a", params int[] p) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, + expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); + } - [Fact] - public async Task ReorderExtensionAndParamsMethodParametersAndArguments_VariedCallsites() - { - var markup = """ - public class C + [Fact] + public async Task ReorderIndexerParametersAndArguments() + { + var markup = """ + class Program + { + void M() { - static void Main(string[] args) - { - CExt.M(new C(), 1, 2, "three", "four", "five", new[] { 6, 7, 8 }); - CExt.M(new C(), 1, 2, "three", "four", "five", 6, 7, 8); - new C().M(1, 2, "three", "four", "five", new[] { 6, 7, 8 }); - new C().M(1, 2, "three", "four", "five", 6, 7, 8); - } + var x = new Program()[1, 2]; + new Program()[1, 2] = x; } - public static class CExt + public int this[int x, int y]$$ { - public static void $$M(this C goo, int x, int y, string a = "test_a", string b = "test_b", string c = "test_c", params int[] p) - { } + get { return 5; } + set { } } - """; - var permutation = new[] { 0, 2, 1, 5, 4, 3, 6 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class Program + { + void M() { - static void Main(string[] args) - { - CExt.M(new C(), 2, 1, "five", "four", "three", new[] { 6, 7, 8 }); - CExt.M(new C(), 2, 1, "five", "four", "three", 6, 7, 8); - new C().M(2, 1, "five", "four", "three", new[] { 6, 7, 8 }); - new C().M(2, 1, "five", "four", "three", 6, 7, 8); - } + var x = new Program()[2, 1]; + new Program()[2, 1] = x; } - public static class CExt - { - public static void M(this C goo, int y, int x, string c = "test_c", string b = "test_b", string a = "test_a", params int[] p) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, - expectedUpdatedInvocationDocumentCode: updatedCode, expectedSelectedIndex: 0); - } - - [Fact] - public async Task ReorderIndexerParametersAndArguments() - { - var markup = """ - class Program - { - void M() - { - var x = new Program()[1, 2]; - new Program()[1, 2] = x; - } - - public int this[int x, int y]$$ - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class Program + public int this[int y, int x] { - void M() - { - var x = new Program()[2, 1]; - new Program()[2, 1] = x; - } - - public int this[int y, int x] - { - get { return 5; } - set { } - } + get { return 5; } + set { } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_SingleLineDocComments_OnIndividualLines() - { - var markup = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_SingleLineDocComments_OnIndividualLines() + { + var markup = """ + public class C + { + /// + /// + /// + void $$Goo(int a, int b, int c) { - /// - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + /// + void Goo(int c, int b, int a) { - /// - /// - /// - void Goo(int c, int b, int a) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParamTagsInDocComments_SingleLineDocComments_OnSameLine() - { - var markup = """ - public class C - { - /// a is funb is func is fun - void $$Goo(int a, int b, int c) - { + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - } - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_SingleLineDocComments_OnSameLine() + { + var markup = """ + public class C + { + /// a is funb is func is fun + void $$Goo(int a, int b, int c) { - /// c is funb is funa is fun - void Goo(int c, int b, int a) - { - } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParamTagsInDocComments_SingleLineDocComments_MixedLineDistribution() - { - var markup = """ - public class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// c is funb is funa is fun + void Goo(int c, int b, int a) { - /// - /// - /// - /// Comments spread - /// over several - /// lines - void $$Goo(int a, int b, int c, int d, int e, int f) - { - } } - """; - var permutation = new[] { 5, 4, 3, 2, 1, 0 }; - var updatedCode = """ - public class C - { - /// Comments spread - /// over several - /// lines - /// - /// - /// - void Goo(int f, int e, int d, int c, int b, int a) - { + } + """; - } - } - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParamTagsInDocComments_SingleLineDocComments_MixedLineDistribution() + { + var markup = """ + public class C + { + /// + /// + /// + /// Comments spread + /// over several + /// lines + void $$Goo(int a, int b, int c, int d, int e, int f) + { + + } + } + """; + var permutation = new[] { 5, 4, 3, 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// Comments spread + /// over several + /// lines + /// + /// + /// + void Goo(int f, int e, int d, int c, int b, int a) + { + + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_SingleLineDocComments_MixedWithRegularComments() - { - var markup = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_SingleLineDocComments_MixedWithRegularComments() + { + var markup = """ + public class C + { + /// + // Why is there a regular comment here? + /// + void $$Goo(int a, int b, int c, int d, int e) { - /// - // Why is there a regular comment here? - /// - void $$Goo(int a, int b, int c, int d, int e) - { - } } - """; - var permutation = new[] { 4, 3, 2, 1, 0 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 4, 3, 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + // Why is there a regular comment here? + /// + void Goo(int e, int d, int c, int b, int a) { - /// - // Why is there a regular comment here? - /// - void Goo(int e, int d, int c, int b, int a) - { - } } - """; + } + """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParamTagsInDocComments_MultiLineDocComments_OnSeparateLines1() - { - var markup = """ - class Program - { - /** - * x! - * y! - * z! - */ - static void $$M(int x, int y, int z) - { - } - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - class Program - { - /** - * z! - * y! - * x! - */ - static void M(int z, int y, int x) - { - } - } - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParamTagsInDocComments_MultiLineDocComments_OnSeparateLines1() + { + var markup = """ + class Program + { + /** + * x! + * y! + * z! + */ + static void $$M(int x, int y, int z) + { + } + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + class Program + { + /** + * z! + * y! + * x! + */ + static void M(int z, int y, int x) + { + } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_MultiLineDocComments_OnSingleLine() - { - var markup = """ - class Program - { - /** x!y!z! */ - static void $$M(int x, int y, int z) - { - } - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - class Program + [Fact] + public async Task ReorderParamTagsInDocComments_MultiLineDocComments_OnSingleLine() + { + var markup = """ + class Program + { + /** x!y!z! */ + static void $$M(int x, int y, int z) { - /** z!y!x! */ - static void M(int z, int y, int x) - { - } } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParamTagsInDocComments_IncorrectOrder_MaintainsOrder() - { - var markup = """ - public class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + class Program + { + /** z!y!x! */ + static void M(int z, int y, int x) { - /// - /// - /// - void $$Goo(int a, int b, int c) - { - - } } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C - { - /// - /// - /// - void Goo(int c, int b, int a) - { + } + """; - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_WrongNames_MaintainsOrder() - { - var markup = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_IncorrectOrder_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + /// + void $$Goo(int a, int b, int c) { - /// - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + /// + void Goo(int c, int b, int a) { - /// - /// - /// - void Goo(int c, int b, int a) - { - } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_InsufficientTags_MaintainsOrder() - { - var markup = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_WrongNames_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + /// + void $$Goo(int a, int b, int c) { - /// - /// - void $$Goo(int a, int b, int c) - { - } } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + /// + void Goo(int c, int b, int a) { - /// - /// - void Goo(int c, int b, int a) - { - } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParamTagsInDocComments_ExcessiveTags_MaintainsOrder() - { - var markup = """ - public class C - { - /// - /// - /// - /// - void $$Goo(int a, int b, int c) - { + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - } - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_InsufficientTags_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + void $$Goo(int a, int b, int c) { - /// - /// - /// - /// - void Goo(int c, int b, int a) - { - } } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - - [Fact] - public async Task ReorderParamTagsInDocComments_OnConstructors() - { - var markup = """ - public class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + void Goo(int c, int b, int a) { - /// - /// - /// - public $$C(int a, int b, int c) - { - } } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C - { - /// - /// - /// - public C(int c, int b, int a) - { + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParamTagsInDocComments_ExcessiveTags_MaintainsOrder() + { + var markup = """ + public class C + { + /// + /// + /// + /// + void $$Goo(int a, int b, int c) + { + + } + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + /// + /// + void Goo(int c, int b, int a) + { + + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_OnIndexers() - { - var markup = """ - public class C - { - /// - /// - /// - public int $$this[int a, int b, int c] - { - get { return 5; } - set { } - } - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - public class C + [Fact] + public async Task ReorderParamTagsInDocComments_OnConstructors() + { + var markup = """ + public class C + { + /// + /// + /// + public $$C(int a, int b, int c) { - /// - /// - /// - public int this[int c, int b, int a] - { - get { return 5; } - set { } - } - } - """; - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - [Fact] - public async Task ReorderParametersInCrefs() - { - var markup = """ - class C - { - /// - /// See and - /// - $$void M(int x, string y) - { } } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - class C + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + /// + public C(int c, int b, int a) { - /// - /// See and - /// - void M(string y, int x) - { } - } - """; - - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } - [Fact] - public async Task ReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType1() - { - var markup = """ - interface I - { - $$void M(int x, string y); } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class C - { - public void M(int x, string y) - { - } - } + [Fact] + public async Task ReorderParamTagsInDocComments_OnIndexers() + { + var markup = """ + public class C + { + /// + /// + /// + public int $$this[int a, int b, int c] + { + get { return 5; } + set { } + } + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + public class C + { + /// + /// + /// + public int this[int c, int b, int a] + { + get { return 5; } + set { } + } + } + """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class D : C, I - { - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - interface I - { - void M(string y, int x); - } + [Fact] + public async Task ReorderParametersInCrefs() + { + var markup = """ + class C + { + /// + /// See and + /// + $$void M(int x, string y) + { } + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + class C + { + /// + /// See and + /// + void M(string y, int x) + { } + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class C - { - public void M(string y, int x) - { - } - } + [Fact] + public async Task ReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType1() + { + var markup = """ + interface I + { + $$void M(int x, string y); + } - class D : C, I + class C + { + public void M(int x, string y) { } - """; + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + class D : C, I + { + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + interface I + { + void M(string y, int x); + } - [Fact] - public async Task ReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType2() - { - var markup = """ - interface I + class C + { + public void M(string y, int x) { - void M(int x, string y); } + } - class C - { - $$public void M(int x, string y) - { - } - } + class D : C, I + { + } + """; - class D : C, I - { - } - """; - var permutation = new[] { 1, 0 }; - var updatedCode = """ - interface I - { - void M(string y, int x); - } + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - class C - { - public void M(string y, int x) - { - } - } + [Fact] + public async Task ReorderParametersInMethodThatImplementsInterfaceMethodOnlyThroughADerivedType2() + { + var markup = """ + interface I + { + void M(int x, string y); + } - class D : C, I + class C + { + $$public void M(int x, string y) { } - """; + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + class D : C, I + { + } + """; + var permutation = new[] { 1, 0 }; + var updatedCode = """ + interface I + { + void M(string y, int x); + } - [Fact] - public async Task ReorderParamTagsInDocComments_Record() - { - var markup = """ - /// - /// - /// - record $$R(int A, int B, int C) - { - public static R Instance = new(0, 1, 2); - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - /// - /// - /// - record R(int C, int B, int A) + class C + { + public void M(string y, int x) { - public static R Instance = new(2, 1, 0); } - """; + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + class D : C, I + { + } + """; - [Fact] - public async Task ReorderParamTagsInDocComments_PrimaryConstructor_Class() - { - var markup = """ - /// - /// - /// - class $$R(int A, int B, int C) - { - public static R Instance = new(0, 1, 2); - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - /// - /// - /// - class R(int C, int B, int A) - { - public static R Instance = new(2, 1, 0); - } - """; + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParamTagsInDocComments_Record() + { + var markup = """ + /// + /// + /// + record $$R(int A, int B, int C) + { + public static R Instance = new(0, 1, 2); + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + /// + /// + /// + record R(int C, int B, int A) + { + public static R Instance = new(2, 1, 0); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - [Fact] - public async Task ReorderParamTagsInDocComments_PrimaryConstructor_Struct() - { - var markup = """ - /// - /// - /// - struct $$R(int A, int B, int C) - { - public static R Instance = new(0, 1, 2); - } - """; - var permutation = new[] { 2, 1, 0 }; - var updatedCode = """ - /// - /// - /// - struct R(int C, int B, int A) - { - public static R Instance = new(2, 1, 0); - } - """; + [Fact] + public async Task ReorderParamTagsInDocComments_PrimaryConstructor_Class() + { + var markup = """ + /// + /// + /// + class $$R(int A, int B, int C) + { + public static R Instance = new(0, 1, 2); + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + /// + /// + /// + class R(int C, int B, int A) + { + public static R Instance = new(2, 1, 0); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } - await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); - } + [Fact] + public async Task ReorderParamTagsInDocComments_PrimaryConstructor_Struct() + { + var markup = """ + /// + /// + /// + struct $$R(int A, int B, int C) + { + public static R Instance = new(0, 1, 2); + } + """; + var permutation = new[] { 2, 1, 0 }; + var updatedCode = """ + /// + /// + /// + struct R(int C, int B, int A) + { + public static R Instance = new(2, 1, 0); + } + """; + + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/AbstractCSharpClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/AbstractCSharpClassifierTests.cs index b9820dd1d42d1..20479759207ee 100644 --- a/src/EditorFeatures/CSharpTest/Classification/AbstractCSharpClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/AbstractCSharpClassifierTests.cs @@ -7,32 +7,31 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Classification; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Remote.Testing; using Microsoft.CodeAnalysis.Test.Utilities; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +public abstract class AbstractCSharpClassifierTests : AbstractClassifierTests { - public abstract class AbstractCSharpClassifierTests : AbstractClassifierTests + protected static EditorTestWorkspace CreateWorkspace(string code, ParseOptions options, TestHost testHost) + { + var composition = EditorTestCompositions.EditorFeatures.WithTestHostParts(testHost); + return EditorTestWorkspace.CreateCSharp(code, parseOptions: options, composition: composition, isMarkup: false); + } + + protected override async Task DefaultTestAsync(string code, string allCode, TestHost testHost, FormattedClassification[] expected) { - protected static EditorTestWorkspace CreateWorkspace(string code, ParseOptions options, TestHost testHost) - { - var composition = EditorTestCompositions.EditorFeatures.WithTestHostParts(testHost); - return EditorTestWorkspace.CreateCSharp(code, parseOptions: options, composition: composition, isMarkup: false); - } - - protected override async Task DefaultTestAsync(string code, string allCode, TestHost testHost, FormattedClassification[] expected) - { - await TestAsync(code, allCode, testHost, parseOptions: null, expected); - await TestAsync(code, allCode, testHost, parseOptions: Options.Script, expected); - } - - protected override string WrapInClass(string className, string code) + await TestAsync(code, allCode, testHost, parseOptions: null, expected); + await TestAsync(code, allCode, testHost, parseOptions: Options.Script, expected); + } + + protected override string WrapInClass(string className, string code) => $@"class {className} {{ {code} }}"; - protected override string WrapInExpression(string code) + protected override string WrapInExpression(string code) => $@"class C {{ void M() {{ var q = @@ -40,16 +39,15 @@ void M() {{ }} }}"; - protected override string WrapInMethod(string className, string methodName, string code) + protected override string WrapInMethod(string className, string methodName, string code) => $@"class {className} {{ void {methodName}() {{ {code} }} }}"; - protected override string WrapInNamespace(string code) + protected override string WrapInNamespace(string code) => $@"namespace N {{ {code} }}"; - } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs index c9a0a881e7b99..6554bcdf6543b 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs @@ -9,7 +9,6 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Remote.Testing; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -24,3915 +23,3914 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +[Trait(Traits.Feature, Traits.Features.Classification)] +public partial class SemanticClassifierTests : AbstractCSharpClassifierTests { - [Trait(Traits.Feature, Traits.Features.Classification)] - public partial class SemanticClassifierTests : AbstractCSharpClassifierTests + protected override async Task> GetClassificationSpansAsync(string code, ImmutableArray spans, ParseOptions? options, TestHost testHost) { - protected override async Task> GetClassificationSpansAsync(string code, ImmutableArray spans, ParseOptions? options, TestHost testHost) - { - using var workspace = CreateWorkspace(code, options, testHost); - var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id); + using var workspace = CreateWorkspace(code, options, testHost); + var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id); - return await GetSemanticClassificationsAsync(document, spans); - } + return await GetSemanticClassificationsAsync(document, spans); + } - [Theory, CombinatorialData] - public async Task GenericClassDeclaration(TestHost testHost) - { - await TestInMethodAsync( - className: "Class", - methodName: "M", - @"new Class();", - testHost, - Class("Class")); - } + [Theory, CombinatorialData] + public async Task GenericClassDeclaration(TestHost testHost) + { + await TestInMethodAsync( + className: "Class", + methodName: "M", + @"new Class();", + testHost, + Class("Class")); + } - [Theory, CombinatorialData] - public async Task RefVar(TestHost testHost) - { - await TestInMethodAsync( - @"int i = 0; ref var x = ref i;", - testHost, - Classifications(Keyword("var"), Local("i"))); - } + [Theory, CombinatorialData] + public async Task RefVar(TestHost testHost) + { + await TestInMethodAsync( + @"int i = 0; ref var x = ref i;", + testHost, + Classifications(Keyword("var"), Local("i"))); + } - [Theory, CombinatorialData] - public async Task UsingAlias1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task UsingAlias1(TestHost testHost) + { + await TestAsync( @"using M = System.Math;", - testHost, - Class("M"), - Namespace("System"), - Class("Math"), - Static("Math")); - } + testHost, + Class("M"), + Namespace("System"), + Class("Math"), + Static("Math")); + } - [Theory, CombinatorialData] - public async Task DynamicAsTypeArgument(TestHost testHost) - { - await TestInMethodAsync( - className: "Class", - methodName: "M", - @"new Class();", - testHost, - Classifications(Class("Class"), Keyword("dynamic"))); - } + [Theory, CombinatorialData] + public async Task DynamicAsTypeArgument(TestHost testHost) + { + await TestInMethodAsync( + className: "Class", + methodName: "M", + @"new Class();", + testHost, + Classifications(Class("Class"), Keyword("dynamic"))); + } - [Theory, CombinatorialData] - public async Task UsingTypeAliases(TestHost testHost) - { - var code = """ - using Alias = Test; - class Test { void M() { Test a = new Test(); Alias b = new Alias(); } } - """; - - await TestAsync(code, - code, - testHost, - Class("Alias"), - Class("Test"), - Class("Test"), - Class("Test"), - Class("Alias"), - Class("Alias")); - } + [Theory, CombinatorialData] + public async Task UsingTypeAliases(TestHost testHost) + { + var code = """ + using Alias = Test; + class Test { void M() { Test a = new Test(); Alias b = new Alias(); } } + """; + + await TestAsync(code, + code, + testHost, + Class("Alias"), + Class("Test"), + Class("Test"), + Class("Test"), + Class("Alias"), + Class("Alias")); + } - [Theory, CombinatorialData] - public async Task DynamicTypeAlias(TestHost testHost) - { - await TestAsync( - """ - using dynamic = System.EventArgs; + [Theory, CombinatorialData] + public async Task DynamicTypeAlias(TestHost testHost) + { + await TestAsync( + """ + using dynamic = System.EventArgs; - class C - { - dynamic d = new dynamic(); - } - """, - testHost, - Class("dynamic"), - Namespace("System"), - Class("EventArgs"), - Class("dynamic"), - Class("dynamic")); - } + class C + { + dynamic d = new dynamic(); + } + """, + testHost, + Class("dynamic"), + Namespace("System"), + Class("EventArgs"), + Class("dynamic"), + Class("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsDelegateName(TestHost testHost) - { - await TestAsync( - """ - delegate void dynamic(); + [Theory, CombinatorialData] + public async Task DynamicAsDelegateName(TestHost testHost) + { + await TestAsync( + """ + delegate void dynamic(); - class C + class C + { + void M() { - void M() - { - dynamic d; - } + dynamic d; } - """, - testHost, - Delegate("dynamic")); - } + } + """, + testHost, + Delegate("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsInterfaceName(TestHost testHost) - { - await TestAsync( - """ - interface dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsInterfaceName(TestHost testHost) + { + await TestAsync( + """ + interface dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Interface("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Interface("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsEnumName(TestHost testHost) - { - await TestAsync( - """ - enum dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsEnumName(TestHost testHost) + { + await TestAsync( + """ + enum dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Enum("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Enum("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsClassName(TestHost testHost) - { - await TestAsync( - """ - class dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsClassName(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Class("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Class("dynamic")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/46985")] - public async Task DynamicAsRecordName(TestHost testHost) - { - await TestAsync( - """ - record dynamic - { - } + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/46985")] + public async Task DynamicAsRecordName(TestHost testHost) + { + await TestAsync( + """ + record dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - RecordClass("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + RecordClass("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsClassNameAndLocalVariableName(TestHost testHost) - { - await TestAsync( - """ - class dynamic + [Theory, CombinatorialData] + public async Task DynamicAsClassNameAndLocalVariableName(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + dynamic() { - dynamic() - { - dynamic dynamic; - } + dynamic dynamic; } - """, - testHost, - Class("dynamic")); - } + } + """, + testHost, + Class("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsStructName(TestHost testHost) - { - await TestAsync( - """ - struct dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsStructName(TestHost testHost) + { + await TestAsync( + """ + struct dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Struct("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Struct("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsGenericClassName(TestHost testHost) - { - await TestAsync( - """ - class dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsGenericClassName(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Class("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Class("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsGenericClassNameButOtherArity(TestHost testHost) - { - await TestAsync( - """ - class dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsGenericClassNameButOtherArity(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Keyword("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Keyword("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsUndefinedGenericType(TestHost testHost) - { - await TestAsync( - """ - class dynamic - { - } + [Theory, CombinatorialData] + public async Task DynamicAsUndefinedGenericType(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + } - class C - { - dynamic d; - } - """, - testHost, - Class("dynamic")); - } + class C + { + dynamic d; + } + """, + testHost, + Class("dynamic")); + } - [Theory, CombinatorialData] - public async Task DynamicAsExternAlias(TestHost testHost) - { - await TestAsync( - """ - extern alias dynamic; + [Theory, CombinatorialData] + public async Task DynamicAsExternAlias(TestHost testHost) + { + await TestAsync( + """ + extern alias dynamic; - class C - { - dynamic::Goo a; - } - """, - testHost, - Namespace("dynamic")); - } + class C + { + dynamic::Goo a; + } + """, + testHost, + Namespace("dynamic")); + } - [Theory, CombinatorialData] - public async Task GenericClassNameButOtherArity(TestHost testHost) - { - await TestAsync( - """ - class A - { - } + [Theory, CombinatorialData] + public async Task GenericClassNameButOtherArity(TestHost testHost) + { + await TestAsync( + """ + class A + { + } - class C + class C + { + A d; + } + """, testHost, + Class("A")); + } + + [Theory, CombinatorialData] + public async Task GenericTypeParameter(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - A d; - } - """, testHost, - Class("A")); - } + default(T) } + } + """, + testHost, + TypeParameter("T")); + } - [Theory, CombinatorialData] - public async Task GenericTypeParameter(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task GenericMethodTypeParameter(TestHost testHost) + { + await TestAsync( + """ + class C + { + T M(T t) { - void M() - { - default(T) } + return default(T); } - """, - testHost, - TypeParameter("T")); - } + } + """, + testHost, + TypeParameter("T"), + TypeParameter("T"), + TypeParameter("T")); + } - [Theory, CombinatorialData] - public async Task GenericMethodTypeParameter(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task GenericMethodTypeParameterInLocalVariableDeclaration(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - T M(T t) - { - return default(T); - } + T t; } - """, - testHost, - TypeParameter("T"), - TypeParameter("T"), - TypeParameter("T")); - } + } + """, + testHost, + TypeParameter("T")); + } - [Theory, CombinatorialData] - public async Task GenericMethodTypeParameterInLocalVariableDeclaration(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task ParameterOfLambda1(TestHost testHost) + { + await TestAsync( + """ + class C + { + C() { - void M() - { - T t; - } + Action a = (C p) => { + }; } - """, - testHost, - TypeParameter("T")); - } + } + """, + testHost, + Class("C")); + } - [Theory, CombinatorialData] - public async Task ParameterOfLambda1(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task ParameterOfAnonymousMethod(TestHost testHost) + { + await TestAsync( + """ + class C + { + C() { - C() - { - Action a = (C p) => { - }; - } + Action a = delegate (C p) { + }; } - """, - testHost, - Class("C")); - } + } + """, + testHost, + Class("C")); + } + + [Theory, CombinatorialData] + public async Task GenericTypeParameterAfterWhere(TestHost testHost) + { + await TestAsync( + """ + class C where A : B + { + } + """, + testHost, + TypeParameter("A"), + TypeParameter("B")); + } + + [Theory, CombinatorialData] + public async Task BaseClass(TestHost testHost) + { + await TestAsync( + """ + class C + { + } + + class C2 : C + { + } + """, + testHost, + Class("C")); + } + + [Theory, CombinatorialData] + public async Task BaseInterfaceOnInterface(TestHost testHost) + { + await TestAsync( + """ + interface T + { + } + + interface T2 : T + { + } + """, + testHost, + Interface("T")); + } + + [Theory, CombinatorialData] + public async Task BaseInterfaceOnClass(TestHost testHost) + { + await TestAsync( + """ + interface T + { + } + + class T2 : T + { + } + """, + testHost, + Interface("T")); + } + + [Theory, CombinatorialData] + public async Task InterfaceColorColor(TestHost testHost) + { + await TestAsync( + """ + interface T + { + } + + class T2 : T + { + T T; + } + """, + testHost, + Interface("T"), + Interface("T")); + } + + [Theory, CombinatorialData] + public async Task DelegateColorColor(TestHost testHost) + { + await TestAsync( + """ + delegate void T(); + + class T2 + { + T T; + } + """, + testHost, + Delegate("T")); + } + + [Theory, CombinatorialData] + public async Task DelegateReturnsItself(TestHost testHost) + { + await TestAsync( + """ + delegate T T(); + + class C + { + T T(T t); + } + """, + testHost, + Delegate("T"), + Delegate("T"), + Delegate("T")); + } - [Theory, CombinatorialData] - public async Task ParameterOfAnonymousMethod(TestHost testHost) - { - await TestAsync( - """ - class C - { - C() - { - Action a = delegate (C p) { - }; - } - } - """, - testHost, - Class("C")); - } + [Theory, CombinatorialData] + public async Task StructColorColor(TestHost testHost) + { + await TestAsync( + """ + struct T + { + T T; + } + """, + testHost, + Struct("T")); + } - [Theory, CombinatorialData] - public async Task GenericTypeParameterAfterWhere(TestHost testHost) - { - await TestAsync( - """ - class C where A : B - { - } - """, - testHost, - TypeParameter("A"), - TypeParameter("B")); - } + [Theory, CombinatorialData] + public async Task EnumColorColor(TestHost testHost) + { + await TestAsync( + """ + enum T + { + T, + T + } - [Theory, CombinatorialData] - public async Task BaseClass(TestHost testHost) - { - await TestAsync( - """ - class C - { - } + class C + { + T T; + } + """, + testHost, + Enum("T")); + } - class C2 : C - { - } - """, - testHost, - Class("C")); - } + [Theory, CombinatorialData] + public async Task DynamicAsGenericTypeParameter(TestHost testHost) + { + await TestAsync( + """ + class C + { + dynamic d; + } + """, + testHost, + TypeParameter("dynamic")); + } - [Theory, CombinatorialData] - public async Task BaseInterfaceOnInterface(TestHost testHost) - { - await TestAsync( - """ - interface T - { - } + [Theory, CombinatorialData] + public async Task DynamicAsGenericFieldName(TestHost testHost) + { + await TestAsync( + """ + class A + { + T dynamic; + } + """, + testHost, + TypeParameter("T")); + } - interface T2 : T - { - } - """, - testHost, - Interface("T")); - } + [Theory, CombinatorialData] + public async Task PropertySameNameAsClass(TestHost testHost) + { + await TestAsync( + """ + class N + { + N N { get; set; } - [Theory, CombinatorialData] - public async Task BaseInterfaceOnClass(TestHost testHost) - { - await TestAsync( - """ - interface T + void M() { + N n = N; + N = n; + N = N; } + } + """, + testHost, + Class("N"), + Class("N"), + Property("N"), + Property("N"), + Local("n"), + Property("N"), + Property("N")); + } - class T2 : T - { - } - """, - testHost, - Interface("T")); - } + [Theory, CombinatorialData] + public async Task AttributeWithoutAttributeSuffix(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task InterfaceColorColor(TestHost testHost) - { - await TestAsync( - """ - interface T - { - } + [Obsolete] + class C + { + } + """, + testHost, + Namespace("System"), + Class("Obsolete"), + Obsolete("C")); + } - class T2 : T - { - T T; - } - """, - testHost, - Interface("T"), - Interface("T")); - } + [Theory, CombinatorialData] + public async Task AttributeOnNonExistingMember(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task DelegateColorColor(TestHost testHost) - { - await TestAsync( - """ - delegate void T(); + class A + { + [Obsolete] + } + """, + testHost, + Namespace("System"), + Class("Obsolete")); + } - class T2 - { - T T; - } - """, - testHost, - Delegate("T")); - } + [Theory, CombinatorialData] + public async Task AttributeWithoutAttributeSuffixOnAssembly(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task DelegateReturnsItself(TestHost testHost) - { - await TestAsync( - """ - delegate T T(); + [assembly: My] - class C - { - T T(T t); - } - """, - testHost, - Delegate("T"), - Delegate("T"), - Delegate("T")); - } + class MyAttribute : Attribute + { + } + """, + testHost, + Namespace("System"), + Class("My"), + Class("Attribute")); + } - [Theory, CombinatorialData] - public async Task StructColorColor(TestHost testHost) - { - await TestAsync( - """ - struct T - { - T T; - } - """, - testHost, - Struct("T")); - } + [Theory, CombinatorialData] + public async Task AttributeViaNestedClassOrDerivedClass(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task EnumColorColor(TestHost testHost) - { - await TestAsync( - """ - enum T + [Base.My] + [Derived.My] + class Base + { + public class MyAttribute : Attribute { - T, - T } + } - class C - { - T T; - } - """, - testHost, - Enum("T")); - } + class Derived : Base + { + } + """, + testHost, + Namespace("System"), + Class("Base"), + Class("My"), + Class("Derived"), + Class("My"), + Class("Attribute"), + Class("Base")); + } - [Theory, CombinatorialData] - public async Task DynamicAsGenericTypeParameter(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task NamedAndOptional(TestHost testHost) + { + await TestAsync( + """ + class C + { + void B(C C = null) { - dynamic d; } - """, - testHost, - TypeParameter("dynamic")); - } - [Theory, CombinatorialData] - public async Task DynamicAsGenericFieldName(TestHost testHost) - { - await TestAsync( - """ - class A + void M() { - T dynamic; + B(C: null); } - """, - testHost, - TypeParameter("T")); - } - - [Theory, CombinatorialData] - public async Task PropertySameNameAsClass(TestHost testHost) - { - await TestAsync( - """ - class N - { - N N { get; set; } + } + """, + testHost, + Class("C"), + Method("B"), + Parameter("C")); + } - void M() - { - N n = N; - N = n; - N = N; - } - } - """, - testHost, - Class("N"), - Class("N"), - Property("N"), - Property("N"), - Local("n"), - Property("N"), - Property("N")); - } + [Theory, CombinatorialData] + public async Task PartiallyWrittenGenericName1(TestHost testHost) + { + await TestInMethodAsync( + className: "Class", + methodName: "M", + @"Class", + methodName: "M", + @"Class + /// Instance field should be preferred to type + /// §7.5.4.1 + /// + [Theory, CombinatorialData] + public async Task ColorColor4(TestHost testHost) + { + await TestAsync( + """ + class T + { + T T; - [Base.My] - [Derived.My] - class Base + void M() { - public class MyAttribute : Attribute - { - } + T.T = null; } + } + """, + testHost, + Class("T"), + Field("T"), + Field("T")); + } - class Derived : Base - { - } - """, - testHost, - Namespace("System"), - Class("Base"), - Class("My"), - Class("Derived"), - Class("My"), - Class("Attribute"), - Class("Base")); - } + /// + /// Type should be preferred to a static field + /// §7.5.4.1 + /// + [Theory, CombinatorialData] + public async Task ColorColor5(TestHost testHost) + { + await TestAsync( + """ + class T + { + static T T; - [Theory, CombinatorialData] - public async Task NamedAndOptional(TestHost testHost) - { - await TestAsync( - """ - class C + void M() { - void B(C C = null) - { - } - - void M() - { - B(C: null); - } + T.T = null; } - """, - testHost, - Class("C"), - Method("B"), - Parameter("C")); - } - - [Theory, CombinatorialData] - public async Task PartiallyWrittenGenericName1(TestHost testHost) - { - await TestInMethodAsync( - className: "Class", - methodName: "M", - @"Class", - methodName: "M", - @"Class + /// Needs to prefer the local + /// + [Theory, CombinatorialData] + public async Task ColorColor6(TestHost testHost) + { + await TestAsync( + """ + class T + { + int field; - // The "Color Color" problem is the C# IDE folklore for when - // a property name is the same as a type name - // and the resulting ambiguities that the spec - // resolves in favor of properties - [Theory, CombinatorialData] - public async Task ColorColor(TestHost testHost) - { - await TestAsync( - """ - class Color + void M() { - Color Color; + T T = new T(); + T.field = 0; } - """, - testHost, - Class("Color")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Local("T"), + Field("field")); + } - [Theory, CombinatorialData] - public async Task ColorColor2(TestHost testHost) - { - await TestAsync( - """ - class T + /// + /// Needs to prefer the type + /// + [Theory, CombinatorialData] + public async Task ColorColor7(TestHost testHost) + { + await TestAsync( + """ + class T + { + static int field; + + void M() { T T = new T(); - - T() - { - this.T = new T(); - } + T.field = 0; } - """, - testHost, - Class("T"), - Class("T"), - Field("T"), - Class("T")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Class("T"), + Field("field"), + Static("field")); + } - [Theory, CombinatorialData] - public async Task ColorColor3(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor8(TestHost testHost) + { + await TestAsync( + """ + class T + { + void M(T T) { - T T = new T(); - - void M(); - - T() - { - T.M(); - } } - """, - testHost, - Class("T"), - Class("T"), - Field("T"), - Method("M")); - } - /// - /// Instance field should be preferred to type - /// §7.5.4.1 - /// - [Theory, CombinatorialData] - public async Task ColorColor4(TestHost testHost) - { - await TestAsync( - """ - class T + void M2() { - T T; - - void M() - { - T.T = null; - } + T T = new T(); + M(T); } - """, - testHost, - Class("T"), - Field("T"), - Field("T")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Class("T"), + Method("M"), + Local("T")); + } - /// - /// Type should be preferred to a static field - /// §7.5.4.1 - /// - [Theory, CombinatorialData] - public async Task ColorColor5(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor9(TestHost testHost) + { + await TestAsync( + """ + class T + { + T M(T T) { - static T T; - - void M() - { - T.T = null; - } + T = new T(); + return T; } - """, - testHost, - Class("T"), - Class("T"), - Field("T"), - Static("T")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Parameter("T"), + Class("T"), + Parameter("T")); + } - /// - /// Needs to prefer the local - /// - [Theory, CombinatorialData] - public async Task ColorColor6(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor10(TestHost testHost) + { + // note: 'var' now binds to the type of the local. + await TestAsync( + """ + class T + { + void M() { - int field; - - void M() - { - T T = new T(); - T.field = 0; - } + var T = new object(); + T temp = T as T; } - """, - testHost, - Class("T"), - Class("T"), - Local("T"), - Field("field")); - } + } + """, + testHost, + Keyword("var"), + Class("T"), + Local("T"), + Class("T")); + } - /// - /// Needs to prefer the type - /// - [Theory, CombinatorialData] - public async Task ColorColor7(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor11(TestHost testHost) + { + await TestAsync( + """ + class T + { + void M() { - static int field; - - void M() - { - T T = new T(); - T.field = 0; - } + var T = new object(); + bool b = T is T; } - """, - testHost, - Class("T"), - Class("T"), - Class("T"), - Field("field"), - Static("field")); - } + } + """, + testHost, + Keyword("var"), + Local("T"), + Class("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor8(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor12(TestHost testHost) + { + await TestAsync( + """ + class T + { + void M() { - void M(T T) - { - } - - void M2() - { - T T = new T(); - M(T); - } + T T = new T(); + var t = typeof(T); } - """, - testHost, - Class("T"), - Class("T"), - Class("T"), - Method("M"), - Local("T")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Keyword("var"), + Class("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor9(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor13(TestHost testHost) + { + await TestAsync( + """ + class T + { + void M() { - T M(T T) - { - T = new T(); - return T; - } + T T = new T(); + T t = default(T); } - """, - testHost, - Class("T"), - Class("T"), - Parameter("T"), - Class("T"), - Parameter("T")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Class("T"), + Class("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor10(TestHost testHost) - { - // note: 'var' now binds to the type of the local. - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task ColorColor14(TestHost testHost) + { + await TestAsync( + """ + class T + { + void M() { - void M() - { - var T = new object(); - T temp = T as T; - } + object T = new T(); + T t = (T)T; } - """, - testHost, - Keyword("var"), - Class("T"), - Local("T"), - Class("T")); - } + } + """, + testHost, + Class("T"), + Class("T"), + Class("T"), + Local("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor11(TestHost testHost) - { - await TestAsync( - """ + [Theory, CombinatorialData] + public async Task NamespaceNameSameAsTypeName1(TestHost testHost) + { + await TestAsync( + """ + namespace T + { class T { void M() { - var T = new object(); - bool b = T is T; + T.T T = new T.T(); } } - """, - testHost, - Keyword("var"), - Local("T"), - Class("T")); - } + } + """, + testHost, + Namespace("T"), + Class("T"), + Class("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor12(TestHost testHost) - { - await TestAsync( - """ + [Theory, CombinatorialData] + public async Task NamespaceNameSameAsTypeNameWithGlobal(TestHost testHost) + { + await TestAsync( + """ + namespace T + { class T { void M() { - T T = new T(); - var t = typeof(T); + global::T.T T = new global::T.T(); } } - """, - testHost, - Class("T"), - Class("T"), - Keyword("var"), - Class("T")); - } + } + """, + testHost, + Namespace("T"), + Namespace("T"), + Class("T"), + Namespace("T"), + Class("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor13(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task AmbiguityTypeAsGenericMethodArgumentVsLocal(TestHost testHost) + { + await TestAsync( + """ + class T + { + void M() { - void M() - { - T T = new T(); - T t = default(T); - } + T T; + M(); } - """, - testHost, - Class("T"), - Class("T"), - Class("T"), - Class("T")); - } + } + """, + testHost, + TypeParameter("T"), + Method("M"), + TypeParameter("T")); + } - [Theory, CombinatorialData] - public async Task ColorColor14(TestHost testHost) - { - await TestAsync( - """ - class T + [Theory, CombinatorialData] + public async Task AmbiguityTypeAsGenericArgumentVsLocal(TestHost testHost) + { + await TestAsync( + """ + class T + { + class G { - void M() - { - object T = new T(); - T t = (T)T; - } } - """, - testHost, - Class("T"), - Class("T"), - Class("T"), - Local("T")); - } - [Theory, CombinatorialData] - public async Task NamespaceNameSameAsTypeName1(TestHost testHost) - { - await TestAsync( - """ - namespace T + void M() { - class T - { - void M() - { - T.T T = new T.T(); - } - } + T T; + G g = new G(); } - """, - testHost, - Namespace("T"), - Class("T"), - Class("T")); - } + } + """, + testHost, + Class("T"), + Class("G"), + Class("T"), + Class("G"), + Class("T")); + } - [Theory, CombinatorialData] - public async Task NamespaceNameSameAsTypeNameWithGlobal(TestHost testHost) - { - await TestAsync( - """ - namespace T + [Theory, CombinatorialData] + public async Task AmbiguityTypeAsGenericArgumentVsField(TestHost testHost) + { + await TestAsync( + """ + class T + { + class H { - class T - { - void M() - { - global::T.T T = new global::T.T(); - } - } + public static int f; } - """, - testHost, - Namespace("T"), - Namespace("T"), - Class("T"), - Namespace("T"), - Class("T")); - } - [Theory, CombinatorialData] - public async Task AmbiguityTypeAsGenericMethodArgumentVsLocal(TestHost testHost) - { - await TestAsync( - """ - class T + void M() { - void M() - { - T T; - M(); - } + T T; + int i = H.f; } - """, - testHost, - TypeParameter("T"), - Method("M"), - TypeParameter("T")); - } + } + """, + testHost, + Class("T"), + Class("H"), + Class("T"), + Field("f"), + Static("f")); + } - [Theory, CombinatorialData] - public async Task AmbiguityTypeAsGenericArgumentVsLocal(TestHost testHost) - { - await TestAsync( - """ - class T + /// + /// §7.5.4.2 + /// + [Theory, CombinatorialData] + public async Task GrammarAmbiguity_7_5_4_2(TestHost testHost) + { + await TestAsync( + """ + class M + { + void m() { - class G - { - } + int A = 2; + int B = 3; + F(G(7)); + } - void M() - { - T T; - G g = new G(); - } + void F(bool b) + { } - """, - testHost, - Class("T"), - Class("G"), - Class("T"), - Class("G"), - Class("T")); - } - [Theory, CombinatorialData] - public async Task AmbiguityTypeAsGenericArgumentVsField(TestHost testHost) - { - await TestAsync( - """ - class T + bool G(int a) { - class H - { - public static int f; - } + return true; + } - void M() - { - T T; - int i = H.f; - } + class A + { } - """, - testHost, - Class("T"), - Class("H"), - Class("T"), - Field("f"), - Static("f")); - } - /// - /// §7.5.4.2 - /// - [Theory, CombinatorialData] - public async Task GrammarAmbiguity_7_5_4_2(TestHost testHost) - { - await TestAsync( - """ - class M + class B { - void m() - { - int A = 2; - int B = 3; - F(G(7)); - } + } + } + """, + testHost, + Method("F"), + Method("G"), + Class("A"), + Class("B")); + } - void F(bool b) - { - } + [Theory, CombinatorialData] + public async Task AnonymousTypePropertyName(TestHost testHost) + { + await TestAsync( + """ + using System; - bool G(int a) - { - return true; - } + class C + { + void M() + { + var x = new { String = " }; } } + """, + testHost, + Namespace("System"), + Keyword("var"), + Property("String")); + } - class A - { - } + [Theory, CombinatorialData] + public async Task YieldAsATypeName(TestHost testHost) + { + await TestAsync( + """ + using System.Collections.Generic; - class B - { - } + class yield + { + IEnumerable M() + { + yield yield = new yield(); + yield return yield; } - """, - testHost, - Method("F"), - Method("G"), - Class("A"), - Class("B")); - } - - [Theory, CombinatorialData] - public async Task AnonymousTypePropertyName(TestHost testHost) - { - await TestAsync( - """ - using System; + } + """, + testHost, + Namespace("System"), + Namespace("Collections"), + Namespace("Generic"), + Interface("IEnumerable"), + Class("yield"), + Class("yield"), + Class("yield"), + Local("yield")); + } - class C + [Theory, CombinatorialData] + public async Task TypeNameDottedNames(TestHost testHost) + { + await TestAsync( + """ + class C + { + class Nested { - void M() - { - var x = new { String = " }; } } - """, - testHost, - Namespace("System"), - Keyword("var"), - Property("String")); - } + } - [Theory, CombinatorialData] - public async Task YieldAsATypeName(TestHost testHost) - { - await TestAsync( - """ - using System.Collections.Generic; + C.Nested f; + } + """, + testHost, + Class("C"), + Class("Nested")); + } - class yield - { - IEnumerable M() - { - yield yield = new yield(); - yield return yield; - } - } - """, - testHost, - Namespace("System"), - Namespace("Collections"), - Namespace("Generic"), - Interface("IEnumerable"), - Class("yield"), - Class("yield"), - Class("yield"), - Local("yield")); - } + [Theory, CombinatorialData] + public async Task BindingTypeNameFromBCLViaGlobalAlias(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task TypeNameDottedNames(TestHost testHost) - { - await TestAsync( - """ - class C - { - class Nested - { - } + class C + { + global::System.String f; + } + """, + testHost, + Namespace("System"), + Namespace("System"), + Class("String")); + } - C.Nested f; - } - """, - testHost, - Class("C"), - Class("Nested")); - } + [Theory, CombinatorialData] + public async Task BindingTypeNames(TestHost testHost) + { + var code = """ + using System; + using Str = System.String; + class C + { + class Nested { } + Str UsingAlias; + Nested NestedClass; + String BCL; + C ClassDeclaration; + C.Nested FCNested; + global::C FCN; + global::System.String FCNBCL; + global::Str GlobalUsingAlias; + } + """; + await TestAsync(code, + code, + testHost, + Options.Regular, + Namespace("System"), + Class("Str"), + Namespace("System"), + Class("String"), + Class("Str"), + Class("Nested"), + Class("String"), + Class("C"), + Class("C"), + Class("Nested"), + Class("C"), + Namespace("System"), + Class("String")); + } - [Theory, CombinatorialData] - public async Task BindingTypeNameFromBCLViaGlobalAlias(TestHost testHost) - { - await TestAsync( - """ - using System; + [Theory, CombinatorialData] + public async Task Constructors(TestHost testHost) + { + await TestAsync( + """ + struct S + { + public int i; - class C + public S(int i) { - global::System.String f; + this.i = i; } - """, - testHost, - Namespace("System"), - Namespace("System"), - Class("String")); - } + } - [Theory, CombinatorialData] - public async Task BindingTypeNames(TestHost testHost) - { - var code = """ - using System; - using Str = System.String; - class C + class C + { + public C() { - class Nested { } - Str UsingAlias; - Nested NestedClass; - String BCL; - C ClassDeclaration; - C.Nested FCNested; - global::C FCN; - global::System.String FCNBCL; - global::Str GlobalUsingAlias; - } - """; - await TestAsync(code, - code, - testHost, - Options.Regular, - Namespace("System"), - Class("Str"), - Namespace("System"), - Class("String"), - Class("Str"), - Class("Nested"), - Class("String"), - Class("C"), - Class("C"), - Class("Nested"), - Class("C"), - Namespace("System"), - Class("String")); - } + var s = new S(1); + var c = new C(); + } + } + """, + testHost, + Field("i"), + Parameter("i"), + Keyword("var"), + Struct("S"), + Keyword("var"), + Class("C")); + } - [Theory, CombinatorialData] - public async Task Constructors(TestHost testHost) - { - await TestAsync( - """ - struct S + [Theory, CombinatorialData] + public async Task TypesOfClassMembers(TestHost testHost) + { + await TestAsync( + """ + class Type + { + public Type() { - public int i; - - public S(int i) - { - this.i = i; - } } - class C + static Type() { - public C() - { - var s = new S(1); - var c = new C(); - } } - """, - testHost, - Field("i"), - Parameter("i"), - Keyword("var"), - Struct("S"), - Keyword("var"), - Class("C")); - } - [Theory, CombinatorialData] - public async Task TypesOfClassMembers(TestHost testHost) - { - await TestAsync( - """ - class Type + ~Type() { - public Type() - { - } - - static Type() - { - } - - ~Type() - { - } + } - Type Property { get; set; } + Type Property { get; set; } - Type Method() - { - } + Type Method() + { + } - event Type Event; + event Type Event; - Type this[Type index] { get; set; } + Type this[Type index] { get; set; } - Type field; - const Type constant = null; + Type field; + const Type constant = null; - static operator Type(Type other) - { - } + static operator Type(Type other) + { + } - static operator +(Type other) - { - } + static operator +(Type other) + { + } - static operator int(Type other) - { - } + static operator int(Type other) + { + } - static operator Type(int other) - { - } + static operator Type(int other) + { } - """, - testHost, - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type"), - Class("Type")); - } + } + """, + testHost, + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type"), + Class("Type")); + } - /// - /// NAQ = Namespace Alias Qualifier (?) - /// - [Theory, CombinatorialData] - public async Task NAQTypeNameCtor(TestHost testHost) - { - await TestInMethodAsync( + /// + /// NAQ = Namespace Alias Qualifier (?) + /// + [Theory, CombinatorialData] + public async Task NAQTypeNameCtor(TestHost testHost) + { + await TestInMethodAsync( @"System.IO.BufferedStream b = new global::System.IO.BufferedStream();", - testHost, - Namespace("System"), - Namespace("IO"), - Class("BufferedStream"), - Namespace("System"), - Namespace("IO"), - Class("BufferedStream")); - } + testHost, + Namespace("System"), + Namespace("IO"), + Class("BufferedStream"), + Namespace("System"), + Namespace("IO"), + Class("BufferedStream")); + } - [Theory, CombinatorialData] - public async Task NAQEnum(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task NAQEnum(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - global::System.IO.DriveType d; - } + global::System.IO.DriveType d; } - """, - testHost, - Namespace("System"), - Namespace("IO"), - Enum("DriveType")); - } + } + """, + testHost, + Namespace("System"), + Namespace("IO"), + Enum("DriveType")); + } - [Theory, CombinatorialData] - public async Task NAQDelegate(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task NAQDelegate(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - global::System.AssemblyLoadEventHandler d; - } + global::System.AssemblyLoadEventHandler d; } - """, - testHost, - Namespace("System"), - Delegate("AssemblyLoadEventHandler")); - } + } + """, + testHost, + Namespace("System"), + Delegate("AssemblyLoadEventHandler")); + } - [Theory, CombinatorialData] - public async Task NAQTypeNameMethodCall(TestHost testHost) - { - await TestInMethodAsync(@"global::System.String.Clone("");", - testHost, - Namespace("System"), - Class("String"), - Method("Clone")); - } + [Theory, CombinatorialData] + public async Task NAQTypeNameMethodCall(TestHost testHost) + { + await TestInMethodAsync(@"global::System.String.Clone("");", + testHost, + Namespace("System"), + Class("String"), + Method("Clone")); + } - [Theory, CombinatorialData] - public async Task NAQEventSubscription(TestHost testHost) - { - await TestInMethodAsync( - """ - global::System.AppDomain.CurrentDomain.AssemblyLoad += - delegate (object sender, System.AssemblyLoadEventArgs args) {}; - """, - testHost, - Namespace("System"), - Class("AppDomain"), - Property("CurrentDomain"), - Static("CurrentDomain"), - Event("AssemblyLoad"), - Namespace("System"), - Class("AssemblyLoadEventArgs")); - } + [Theory, CombinatorialData] + public async Task NAQEventSubscription(TestHost testHost) + { + await TestInMethodAsync( + """ + global::System.AppDomain.CurrentDomain.AssemblyLoad += + delegate (object sender, System.AssemblyLoadEventArgs args) {}; + """, + testHost, + Namespace("System"), + Class("AppDomain"), + Property("CurrentDomain"), + Static("CurrentDomain"), + Event("AssemblyLoad"), + Namespace("System"), + Class("AssemblyLoadEventArgs")); + } - [Theory, CombinatorialData] - public async Task AnonymousDelegateParameterType(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task AnonymousDelegateParameterType(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - System.Action a = delegate (System.EventArgs e) { - }; - } + System.Action a = delegate (System.EventArgs e) { + }; } - """, - testHost, - Namespace("System"), - Delegate("Action"), - Namespace("System"), - Class("EventArgs"), - Namespace("System"), - Class("EventArgs")); - } + } + """, + testHost, + Namespace("System"), + Delegate("Action"), + Namespace("System"), + Class("EventArgs"), + Namespace("System"), + Class("EventArgs")); + } - [Theory, CombinatorialData] - public async Task NAQCtor(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task NAQCtor(TestHost testHost) + { + await TestInMethodAsync( @"global::System.Collections.DictionaryEntry de = new global::System.Collections.DictionaryEntry();", - testHost, - Namespace("System"), - Namespace("Collections"), - Struct("DictionaryEntry"), - Namespace("System"), - Namespace("Collections"), - Struct("DictionaryEntry")); - } + testHost, + Namespace("System"), + Namespace("Collections"), + Struct("DictionaryEntry"), + Namespace("System"), + Namespace("Collections"), + Struct("DictionaryEntry")); + } - [Theory, CombinatorialData] - public async Task NAQSameFileClass(TestHost testHost) - { - var code = @"class C { static void M() { global::C.M(); } }"; - - await TestAsync(code, - testHost, - ParseOptions(Options.Regular), - Class("C"), - Method("M"), - Static("M")); - } + [Theory, CombinatorialData] + public async Task NAQSameFileClass(TestHost testHost) + { + var code = @"class C { static void M() { global::C.M(); } }"; + + await TestAsync(code, + testHost, + ParseOptions(Options.Regular), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task InteractiveNAQSameFileClass(TestHost testHost) - { - var code = @"class C { static void M() { global::Script.C.M(); } }"; - - await TestAsync(code, - testHost, - ParseOptions(Options.Script), - Class("Script"), - Class("C"), - Method("M"), - Static("M")); - } + [Theory, CombinatorialData] + public async Task InteractiveNAQSameFileClass(TestHost testHost) + { + var code = @"class C { static void M() { global::Script.C.M(); } }"; + + await TestAsync(code, + testHost, + ParseOptions(Options.Script), + Class("Script"), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task NAQSameFileClassWithNamespace(TestHost testHost) - { - await TestAsync( - """ - using @global = N; + [Theory, CombinatorialData] + public async Task NAQSameFileClassWithNamespace(TestHost testHost) + { + await TestAsync( + """ + using @global = N; - namespace N + namespace N + { + class C { - class C + static void M() { - static void M() - { - global::N.C.M(); - } + global::N.C.M(); } } - """, - testHost, - Namespace("@global"), - Namespace("N"), - Namespace("N"), - Namespace("N"), - Class("C"), - Method("M"), - Static("M")); - } + } + """, + testHost, + Namespace("@global"), + Namespace("N"), + Namespace("N"), + Namespace("N"), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task NAQSameFileClassWithNamespaceAndEscapedKeyword(TestHost testHost) - { - await TestAsync( - """ - using @global = N; + [Theory, CombinatorialData] + public async Task NAQSameFileClassWithNamespaceAndEscapedKeyword(TestHost testHost) + { + await TestAsync( + """ + using @global = N; - namespace N + namespace N + { + class C { - class C + static void M() { - static void M() - { - @global.C.M(); - } + @global.C.M(); } } - """, - testHost, - Namespace("@global"), - Namespace("N"), - Namespace("N"), - Namespace("@global"), - Class("C"), - Method("M"), - Static("M")); - } + } + """, + testHost, + Namespace("@global"), + Namespace("N"), + Namespace("N"), + Namespace("@global"), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task NAQGlobalWarning(TestHost testHost) - { - await TestAsync( - """ - using global = N; + [Theory, CombinatorialData] + public async Task NAQGlobalWarning(TestHost testHost) + { + await TestAsync( + """ + using global = N; - namespace N + namespace N + { + class C { - class C + static void M() { - static void M() - { - global.C.M(); - } + global.C.M(); } } - """, - testHost, - Namespace("global"), - Namespace("N"), - Namespace("N"), - Namespace("global"), - Class("C"), - Method("M"), - Static("M")); - } + } + """, + testHost, + Namespace("global"), + Namespace("N"), + Namespace("N"), + Namespace("global"), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task NAQUserDefinedNAQNamespace(TestHost testHost) - { - await TestAsync( - """ - using goo = N; + [Theory, CombinatorialData] + public async Task NAQUserDefinedNAQNamespace(TestHost testHost) + { + await TestAsync( + """ + using goo = N; - namespace N + namespace N + { + class C { - class C + static void M() { - static void M() - { - goo.C.M(); - } + goo.C.M(); } } - """, - testHost, - Namespace("goo"), - Namespace("N"), - Namespace("N"), - Namespace("goo"), - Class("C"), - Method("M"), - Static("M")); - } + } + """, + testHost, + Namespace("goo"), + Namespace("N"), + Namespace("N"), + Namespace("goo"), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task NAQUserDefinedNAQNamespaceDoubleColon(TestHost testHost) - { - await TestAsync( - """ - using goo = N; + [Theory, CombinatorialData] + public async Task NAQUserDefinedNAQNamespaceDoubleColon(TestHost testHost) + { + await TestAsync( + """ + using goo = N; - namespace N + namespace N + { + class C { - class C + static void M() { - static void M() - { - goo::C.M(); - } + goo::C.M(); } } - """, - testHost, - Namespace("goo"), - Namespace("N"), - Namespace("N"), - Namespace("goo"), - Class("C"), - Method("M"), - Static("M")); - } + } + """, + testHost, + Namespace("goo"), + Namespace("N"), + Namespace("N"), + Namespace("goo"), + Class("C"), + Method("M"), + Static("M")); + } - [Theory, CombinatorialData] - public async Task NAQUserDefinedNamespace1(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task NAQUserDefinedNamespace1(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - A.B.D d; - } + A.B.D d; } + } - namespace A + namespace A + { + namespace B { - namespace B + class D { - class D - { - } } } - """, - testHost, - Namespace("A"), - Namespace("B"), - Class("D"), - Namespace("A"), - Namespace("B")); - } + } + """, + testHost, + Namespace("A"), + Namespace("B"), + Class("D"), + Namespace("A"), + Namespace("B")); + } - [Theory, CombinatorialData] - public async Task NAQUserDefinedNamespaceWithGlobal(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task NAQUserDefinedNamespaceWithGlobal(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M() { - void M() - { - global::A.B.D d; - } + global::A.B.D d; } + } - namespace A + namespace A + { + namespace B { - namespace B + class D { - class D - { - } } } - """, - testHost, - Namespace("A"), - Namespace("B"), - Class("D"), - Namespace("A"), - Namespace("B")); - } + } + """, + testHost, + Namespace("A"), + Namespace("B"), + Class("D"), + Namespace("A"), + Namespace("B")); + } - [Theory, CombinatorialData] - public async Task NAQUserDefinedNAQForClass(TestHost testHost) - { - await TestAsync( - """ - using IO = global::System.IO; + [Theory, CombinatorialData] + public async Task NAQUserDefinedNAQForClass(TestHost testHost) + { + await TestAsync( + """ + using IO = global::System.IO; - class C + class C + { + void M() { - void M() - { - IO::BinaryReader b; - } + IO::BinaryReader b; } - """, - testHost, - Namespace("IO"), - Namespace("System"), - Namespace("IO"), - Namespace("IO"), - Class("BinaryReader")); - } + } + """, + testHost, + Namespace("IO"), + Namespace("System"), + Namespace("IO"), + Namespace("IO"), + Class("BinaryReader")); + } - [Theory, CombinatorialData] - public async Task NAQUserDefinedTypes(TestHost testHost) - { - await TestAsync( - """ - using rabbit = MyNameSpace; + [Theory, CombinatorialData] + public async Task NAQUserDefinedTypes(TestHost testHost) + { + await TestAsync( + """ + using rabbit = MyNameSpace; - class C + class C + { + void M() { - void M() - { - rabbit::MyClass2.method(); - new rabbit::MyClass2().myEvent += null; - rabbit::MyEnum Enum; - rabbit::MyStruct strUct; - object o2 = rabbit::MyClass2.MyProp; - object o3 = rabbit::MyClass2.myField; - rabbit::MyClass2.MyDelegate del = null; - } + rabbit::MyClass2.method(); + new rabbit::MyClass2().myEvent += null; + rabbit::MyEnum Enum; + rabbit::MyStruct strUct; + object o2 = rabbit::MyClass2.MyProp; + object o3 = rabbit::MyClass2.myField; + rabbit::MyClass2.MyDelegate del = null; } + } - namespace MyNameSpace + namespace MyNameSpace + { + namespace OtherNamespace { - namespace OtherNamespace + class A { - class A - { - } } + } - public class MyClass2 - { - public static int myField; - - public delegate void MyDelegate(); - - public event MyDelegate myEvent; - - public static void method() - { - } - - public static int MyProp - { - get - { - return 0; - } - } - } + public class MyClass2 + { + public static int myField; - struct MyStruct - { - } + public delegate void MyDelegate(); - enum MyEnum - { - } - } - """, - testHost, - Namespace("rabbit"), - Namespace("MyNameSpace"), - Namespace("rabbit"), - Class("MyClass2"), - Method("method"), - Static("method"), - Namespace("rabbit"), - Class("MyClass2"), - Event("myEvent"), - Namespace("rabbit"), - Enum("MyEnum"), - Namespace("rabbit"), - Struct("MyStruct"), - Namespace("rabbit"), - Class("MyClass2"), - Property("MyProp"), - Static("MyProp"), - Namespace("rabbit"), - Class("MyClass2"), - Field("myField"), - Static("myField"), - Namespace("rabbit"), - Class("MyClass2"), - Delegate("MyDelegate"), - Namespace("MyNameSpace"), - Namespace("OtherNamespace"), - Delegate("MyDelegate")); - } + public event MyDelegate myEvent; - [Theory, CombinatorialData] - public async Task PreferPropertyOverNestedClass(TestHost testHost) - { - await TestAsync( - """ - class Outer - { - class A + public static void method() { - public int B; } - class B + public static int MyProp { - void M() + get { - A a = new A(); - a.B = 10; + return 0; } } } - """, - testHost, - Class("A"), - Class("A"), - Local("a"), - Field("B")); - } - - [Theory, CombinatorialData] - public async Task TypeNameInsideNestedClass(TestHost testHost) - { - await TestAsync( - """ - using System; - class Outer + struct MyStruct { - class C - { - void M() - { - Console.WriteLine(); - Console.WriteLine(); - } - } } - """, - testHost, - Namespace("System"), - Class("Console"), - Static("Console"), - Method("WriteLine"), - Static("WriteLine"), - Class("Console"), - Static("Console"), - Method("WriteLine"), - Static("WriteLine")); - } - - [Theory, CombinatorialData] - public async Task StructEnumTypeNames(TestHost testHost) - { - await TestAsync( - """ - using System; - class C + enum MyEnum { - enum MyEnum - { - } + } + } + """, + testHost, + Namespace("rabbit"), + Namespace("MyNameSpace"), + Namespace("rabbit"), + Class("MyClass2"), + Method("method"), + Static("method"), + Namespace("rabbit"), + Class("MyClass2"), + Event("myEvent"), + Namespace("rabbit"), + Enum("MyEnum"), + Namespace("rabbit"), + Struct("MyStruct"), + Namespace("rabbit"), + Class("MyClass2"), + Property("MyProp"), + Static("MyProp"), + Namespace("rabbit"), + Class("MyClass2"), + Field("myField"), + Static("myField"), + Namespace("rabbit"), + Class("MyClass2"), + Delegate("MyDelegate"), + Namespace("MyNameSpace"), + Namespace("OtherNamespace"), + Delegate("MyDelegate")); + } - struct MyStruct - { - } + [Theory, CombinatorialData] + public async Task PreferPropertyOverNestedClass(TestHost testHost) + { + await TestAsync( + """ + class Outer + { + class A + { + public int B; + } - static void Main() + class B + { + void M() { - ConsoleColor c; - Int32 i; + A a = new A(); + a.B = 10; } } - """, - testHost, - Namespace("System"), - Enum("ConsoleColor"), - Struct("Int32")); - } + } + """, + testHost, + Class("A"), + Class("A"), + Local("a"), + Field("B")); + } - [Theory, CombinatorialData] - public async Task PreferFieldOverClassWithSameName(TestHost testHost) - { - await TestAsync( - """ + [Theory, CombinatorialData] + public async Task TypeNameInsideNestedClass(TestHost testHost) + { + await TestAsync( + """ + using System; + + class Outer + { class C { - public int C; - void M() { - C = 0; + Console.WriteLine(); + Console.WriteLine(); } } - """, testHost, - Field("C")); - } + } + """, + testHost, + Namespace("System"), + Class("Console"), + Static("Console"), + Method("WriteLine"), + Static("WriteLine"), + Class("Console"), + Static("Console"), + Method("WriteLine"), + Static("WriteLine")); + } - [Theory, CombinatorialData] - public async Task AttributeBinding(TestHost testHost) - { - await TestAsync( - """ - using System; + [Theory, CombinatorialData] + public async Task StructEnumTypeNames(TestHost testHost) + { + await TestAsync( + """ + using System; - [Serializable] // Binds to System.SerializableAttribute; colorized - class Serializable + class C + { + enum MyEnum { } - [SerializableAttribute] // Binds to System.SerializableAttribute; colorized - class Serializable + struct MyStruct { } - [NonSerialized] // Binds to global::NonSerializedAttribute; colorized - class NonSerializedAttribute + static void Main() { + ConsoleColor c; + Int32 i; } + } + """, + testHost, + Namespace("System"), + Enum("ConsoleColor"), + Struct("Int32")); + } - [NonSerializedAttribute] // Binds to global::NonSerializedAttribute; colorized - class NonSerializedAttribute - { - } + [Theory, CombinatorialData] + public async Task PreferFieldOverClassWithSameName(TestHost testHost) + { + await TestAsync( + """ + class C + { + public int C; - [Obsolete] // Binds to global::Obsolete; colorized - class Obsolete : Attribute + void M() { + C = 0; } + } + """, testHost, + Field("C")); + } - [ObsoleteAttribute] // Binds to global::Obsolete; colorized - class ObsoleteAttribute : Attribute - { - } - """, - testHost, - Namespace("System"), - Class("Serializable"), - Class("SerializableAttribute"), - Class("NonSerialized"), - Class("NonSerializedAttribute"), - Class("Obsolete"), - Class("Attribute"), - Class("ObsoleteAttribute"), - Class("Attribute")); - } + [Theory, CombinatorialData] + public async Task AttributeBinding(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task ShouldNotClassifyNamespacesAsTypes(TestHost testHost) - { - await TestAsync( - """ - using System; + [Serializable] // Binds to System.SerializableAttribute; colorized + class Serializable + { + } - namespace Roslyn.Compilers.Internal - { - } - """, - testHost, - Namespace("System"), - Namespace("Roslyn"), - Namespace("Compilers"), - Namespace("Internal")); - } + [SerializableAttribute] // Binds to System.SerializableAttribute; colorized + class Serializable + { + } - [Theory, CombinatorialData] - public async Task NestedTypeCantHaveSameNameAsParentType(TestHost testHost) - { - await TestAsync( - """ - class Program - { - class Program - { - } + [NonSerialized] // Binds to global::NonSerializedAttribute; colorized + class NonSerializedAttribute + { + } - static void Main(Program p) - { - } + [NonSerializedAttribute] // Binds to global::NonSerializedAttribute; colorized + class NonSerializedAttribute + { + } - Program.Program p2; - } - """, - testHost, - Class("Program"), - Class("Program")); - } + [Obsolete] // Binds to global::Obsolete; colorized + class Obsolete : Attribute + { + } - [Theory, CombinatorialData] - public async Task NestedTypeCantHaveSameNameAsParentTypeWithGlobalNamespaceAlias(TestHost testHost) - { - var code = """ - class Program - { - class Program { } - static void Main(Program p) { } - global::Program.Program p; - } - """; + [ObsoleteAttribute] // Binds to global::Obsolete; colorized + class ObsoleteAttribute : Attribute + { + } + """, + testHost, + Namespace("System"), + Class("Serializable"), + Class("SerializableAttribute"), + Class("NonSerialized"), + Class("NonSerializedAttribute"), + Class("Obsolete"), + Class("Attribute"), + Class("ObsoleteAttribute"), + Class("Attribute")); + } - await TestAsync(code, - testHost, - ParseOptions(Options.Regular), - Class("Program"), - Class("Program"), - Class("Program")); - } + [Theory, CombinatorialData] + public async Task ShouldNotClassifyNamespacesAsTypes(TestHost testHost) + { + await TestAsync( + """ + using System; - [Theory, CombinatorialData] - public async Task InteractiveNestedTypeCantHaveSameNameAsParentTypeWithGlobalNamespaceAlias(TestHost testHost) - { - var code = """ + namespace Roslyn.Compilers.Internal + { + } + """, + testHost, + Namespace("System"), + Namespace("Roslyn"), + Namespace("Compilers"), + Namespace("Internal")); + } + + [Theory, CombinatorialData] + public async Task NestedTypeCantHaveSameNameAsParentType(TestHost testHost) + { + await TestAsync( + """ + class Program + { class Program { - class Program { } - static void Main(Program p) { } - global::Script.Program.Program p; } - """; - - await TestAsync(code, - testHost, - ParseOptions(Options.Script), - Class("Program"), - Class("Script"), - Class("Program"), - Class("Program")); - } - [Theory, CombinatorialData] - public async Task EnumFieldWithSameNameShouldBePreferredToType(TestHost testHost) - { - await TestAsync( - """ - enum E + static void Main(Program p) { - E, - F = E } - """, testHost, - EnumMember("E")); - } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541150")] - [CombinatorialData] - public async Task TestGenericVarClassification(TestHost testHost) - { - await TestAsync( - """ - using System; + Program.Program p2; + } + """, + testHost, + Class("Program"), + Class("Program")); + } + + [Theory, CombinatorialData] + public async Task NestedTypeCantHaveSameNameAsParentTypeWithGlobalNamespaceAlias(TestHost testHost) + { + var code = """ + class Program + { + class Program { } + static void Main(Program p) { } + global::Program.Program p; + } + """; + + await TestAsync(code, + testHost, + ParseOptions(Options.Regular), + Class("Program"), + Class("Program"), + Class("Program")); + } + + [Theory, CombinatorialData] + public async Task InteractiveNestedTypeCantHaveSameNameAsParentTypeWithGlobalNamespaceAlias(TestHost testHost) + { + var code = """ + class Program + { + class Program { } + static void Main(Program p) { } + global::Script.Program.Program p; + } + """; + + await TestAsync(code, + testHost, + ParseOptions(Options.Script), + Class("Program"), + Class("Script"), + Class("Program"), + Class("Program")); + } - static class Program + [Theory, CombinatorialData] + public async Task EnumFieldWithSameNameShouldBePreferredToType(TestHost testHost) + { + await TestAsync( + """ + enum E + { + E, + F = E + } + """, testHost, + EnumMember("E")); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541150")] + [CombinatorialData] + public async Task TestGenericVarClassification(TestHost testHost) + { + await TestAsync( + """ + using System; + + static class Program + { + static void Main() { - static void Main() - { - var x = 1; - } + var x = 1; } + } - class var + class var + { + } + """, + testHost, + Namespace("System"), + Keyword("var")); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541154")] + [CombinatorialData] + public async Task TestInaccessibleVarClassification(TestHost testHost) + { + await TestAsync( + """ + using System; + + class A + { + private class var { } - """, - testHost, - Namespace("System"), - Keyword("var")); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541154")] - [CombinatorialData] - public async Task TestInaccessibleVarClassification(TestHost testHost) - { - await TestAsync( - """ - using System; + } - class A + class B : A + { + static void Main() { - private class var - { - } + var x = 1; } + } + """, + testHost, + Namespace("System"), + Class("A"), + Keyword("var")); + } - class B : A + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541154")] + [CombinatorialData] + public async Task TestVarNamedTypeClassification(TestHost testHost) + { + await TestAsync( + """ + class var + { + static void Main() { - static void Main() - { - var x = 1; - } + var x; } - """, - testHost, - Namespace("System"), - Class("A"), - Keyword("var")); - } + } + """, + testHost, + Keyword("var")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541154")] - [CombinatorialData] - public async Task TestVarNamedTypeClassification(TestHost testHost) - { - await TestAsync( - """ - class var + [Theory, WorkItem(9513, "DevDiv_Projects/Roslyn")] + [CombinatorialData] + public async Task RegressionFor9513(TestHost testHost) + { + await TestAsync( + """ + enum E + { + A, + B + } + + class C + { + void M() { - static void Main() + switch (new E()) { - var x; + case E.A: + goto case E.B; + case E.B: + goto default; + default: + goto case E.A; } } - """, - testHost, - Keyword("var")); - } + } + """, + testHost, + Enum("E"), + Enum("E"), + EnumMember("A"), + Enum("E"), + EnumMember("B"), + Enum("E"), + EnumMember("B"), + Enum("E"), + EnumMember("A")); + } - [Theory, WorkItem(9513, "DevDiv_Projects/Roslyn")] - [CombinatorialData] - public async Task RegressionFor9513(TestHost testHost) - { - await TestAsync( - """ - enum E + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542368")] + [CombinatorialData] + public async Task RegressionFor9572(TestHost testHost) + { + await TestAsync( + """ + class A where T : A.I, A.I + { + public interface I { - A, - B } + } + """, + testHost, + TypeParameter("T"), + Class("A"), + TypeParameter("T"), + TypeParameter("S"), + Interface("I"), + Class("A"), + TypeParameter("T"), + TypeParameter("T"), + Interface("I")); + } - class C + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542368")] + [CombinatorialData] + public async Task RegressionFor9831(TestHost testHost) + { + await TestAsync(@"F : A", + """ + public class B + { + public class A { - void M() - { - switch (new E()) - { - case E.A: - goto case E.B; - case E.B: - goto default; - default: - goto case E.A; - } - } } - """, - testHost, - Enum("E"), - Enum("E"), - EnumMember("A"), - Enum("E"), - EnumMember("B"), - Enum("E"), - EnumMember("B"), - Enum("E"), - EnumMember("A")); - } + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542368")] - [CombinatorialData] - public async Task RegressionFor9572(TestHost testHost) - { - await TestAsync( - """ - class A where T : A.I, A.I + public class X : B + { + public class F : A { - public interface I - { - } } - """, - testHost, - TypeParameter("T"), - Class("A"), - TypeParameter("T"), - TypeParameter("S"), - Interface("I"), - Class("A"), - TypeParameter("T"), - TypeParameter("T"), - Interface("I")); - } + } + """, + testHost, + Class("A")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542368")] - [CombinatorialData] - public async Task RegressionFor9831(TestHost testHost) - { - await TestAsync(@"F : A", - """ - public class B + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542432")] + [CombinatorialData] + public async Task TestVar(TestHost testHost) + { + await TestAsync( + """ + class Program + { + class var { - public class A - { - } } - public class X : B + static var GetVarT() { - public class F : A - { - } + return null; } - """, - testHost, - Class("A")); - } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542432")] - [CombinatorialData] - public async Task TestVar(TestHost testHost) - { - await TestAsync( - """ - class Program + static void Main() { - class var - { - } - - static var GetVarT() - { - return null; - } - - static void Main() - { - var x = GetVarT(); - var y = new var(); - } + var x = GetVarT(); + var y = new var(); } - """, - testHost, - Class("var"), - Keyword("var"), - Method("GetVarT"), - Static("GetVarT"), - Keyword("var"), - Class("var")); - } + } + """, + testHost, + Class("var"), + Keyword("var"), + Method("GetVarT"), + Static("GetVarT"), + Keyword("var"), + Class("var")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543123")] - [CombinatorialData] - public async Task TestVar2(TestHost testHost) - { - await TestAsync( - """ - class Program + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543123")] + [CombinatorialData] + public async Task TestVar2(TestHost testHost) + { + await TestAsync( + """ + class Program + { + void Main(string[] args) { - void Main(string[] args) + foreach (var v in args) { - foreach (var v in args) - { - } } } - """, - testHost, - Keyword("var"), - Parameter("args")); - } + } + """, + testHost, + Keyword("var"), + Parameter("args")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542778")] - [CombinatorialData] - public async Task TestDuplicateTypeParamWithConstraint(TestHost testHost) - { - await TestAsync(@"where U : IEnumerable", - """ - using System.Collections.Generic; + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542778")] + [CombinatorialData] + public async Task TestDuplicateTypeParamWithConstraint(TestHost testHost) + { + await TestAsync(@"where U : IEnumerable", + """ + using System.Collections.Generic; - class C + class C + { + public void Goo(U arg) + where S : T + where U : IEnumerable { - public void Goo(U arg) - where S : T - where U : IEnumerable - { - } } - """, - testHost, - TypeParameter("U"), - Interface("IEnumerable")); - } + } + """, + testHost, + TypeParameter("U"), + Interface("IEnumerable")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] - [CombinatorialData] - public async Task OptimisticallyColorFromInDeclaration(TestHost testHost) - { - await TestInExpressionAsync("from ", - testHost, - Keyword("from")); - } + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] + [CombinatorialData] + public async Task OptimisticallyColorFromInDeclaration(TestHost testHost) + { + await TestInExpressionAsync("from ", + testHost, + Keyword("from")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] - [CombinatorialData] - public async Task OptimisticallyColorFromInAssignment(TestHost testHost) - { - await TestInMethodAsync( - """ - var q = 3; - - q = from - """, - testHost, - Keyword("var"), - Local("q"), - Keyword("from")); - } + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] + [CombinatorialData] + public async Task OptimisticallyColorFromInAssignment(TestHost testHost) + { + await TestInMethodAsync( + """ + var q = 3; + + q = from + """, + testHost, + Keyword("var"), + Local("q"), + Keyword("from")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] - [CombinatorialData] - public async Task DoNotColorThingsOtherThanFromInDeclaration(TestHost testHost) - => await TestInExpressionAsync("fro ", testHost); + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] + [CombinatorialData] + public async Task DoNotColorThingsOtherThanFromInDeclaration(TestHost testHost) + => await TestInExpressionAsync("fro ", testHost); - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] - [CombinatorialData] - public async Task DoNotColorThingsOtherThanFromInAssignment(TestHost testHost) - { - await TestInMethodAsync( - """ - var q = 3; - - q = fro - """, - testHost, - Keyword("var"), - Local("q")); - } + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] + [CombinatorialData] + public async Task DoNotColorThingsOtherThanFromInAssignment(TestHost testHost) + { + await TestInMethodAsync( + """ + var q = 3; + + q = fro + """, + testHost, + Keyword("var"), + Local("q")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] - [CombinatorialData] - public async Task DoNotColorFromWhenBoundInDeclaration(TestHost testHost) - { - await TestInMethodAsync( - """ - var from = 3; - var q = from - """, - testHost, - Keyword("var"), - Keyword("var"), - Local("from")); - } + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] + [CombinatorialData] + public async Task DoNotColorFromWhenBoundInDeclaration(TestHost testHost) + { + await TestInMethodAsync( + """ + var from = 3; + var q = from + """, + testHost, + Keyword("var"), + Keyword("var"), + Local("from")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] - [CombinatorialData] - public async Task DoNotColorFromWhenBoundInAssignment(TestHost testHost) - { - await TestInMethodAsync( - """ - var q = 3; - var from = 3; - - q = from - """, - testHost, - Keyword("var"), - Keyword("var"), - Local("q"), - Local("from")); - } + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542685")] + [CombinatorialData] + public async Task DoNotColorFromWhenBoundInAssignment(TestHost testHost) + { + await TestInMethodAsync( + """ + var q = 3; + var from = 3; + + q = from + """, + testHost, + Keyword("var"), + Keyword("var"), + Local("q"), + Local("from")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543404")] - [CombinatorialData] - public async Task NewOfClassWithOnlyPrivateConstructor(TestHost testHost) - { - await TestAsync( - """ - class X + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543404")] + [CombinatorialData] + public async Task NewOfClassWithOnlyPrivateConstructor(TestHost testHost) + { + await TestAsync( + """ + class X + { + private X() { - private X() - { - } } + } - class Program + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - new X(); - } + new X(); } - """, - testHost, - Class("X")); - } + } + """, + testHost, + Class("X")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544179")] - [CombinatorialData] - public async Task TestNullableVersusConditionalAmbiguity1(TestHost testHost) - { - await TestAsync( - """ - class Program + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544179")] + [CombinatorialData] + public async Task TestNullableVersusConditionalAmbiguity1(TestHost testHost) + { + await TestAsync( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - C1 ? - } + C1 ? } + } - public class C1 - { - } - """, - testHost, - Class("C1")); - } + public class C1 + { + } + """, + testHost, + Class("C1")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544179")] - [CombinatorialData] - public async Task TestPointerVersusMultiplyAmbiguity1(TestHost testHost) - { - await TestAsync( - """ - class Program + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544179")] + [CombinatorialData] + public async Task TestPointerVersusMultiplyAmbiguity1(TestHost testHost) + { + await TestAsync( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) - { - C1 * - } + C1 * } + } - public class C1 - { - } - """, - testHost, - Class("C1")); - } + public class C1 + { + } + """, + testHost, + Class("C1")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544302")] - [CombinatorialData] - public async Task EnumTypeAssignedToNamedPropertyOfSameNameInAttributeCtor(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Runtime.InteropServices; + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544302")] + [CombinatorialData] + public async Task EnumTypeAssignedToNamedPropertyOfSameNameInAttributeCtor(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Runtime.InteropServices; - class C - { - [DllImport("abc", CallingConvention = CallingConvention)] - static extern void M(); - } - """, - testHost, - Namespace("System"), - Namespace("System"), - Namespace("Runtime"), - Namespace("InteropServices"), - Class("DllImport"), - Field("CallingConvention"), - Enum("CallingConvention")); - } + class C + { + [DllImport("abc", CallingConvention = CallingConvention)] + static extern void M(); + } + """, + testHost, + Namespace("System"), + Namespace("System"), + Namespace("Runtime"), + Namespace("InteropServices"), + Class("DllImport"), + Field("CallingConvention"), + Enum("CallingConvention")); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531119")] - [CombinatorialData] - public async Task OnlyClassifyGenericNameOnce(TestHost testHost) - { - await TestAsync( - """ - enum Type + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531119")] + [CombinatorialData] + public async Task OnlyClassifyGenericNameOnce(TestHost testHost) + { + await TestAsync( + """ + enum Type + { + } + + struct Type + { + Type f; + } + """, + testHost, + Struct("Type")); + } + + [Theory, CombinatorialData] + public async Task NameOf1(TestHost testHost) + { + await TestAsync( + """ + class C + { + void goo() { + var x = nameof } + } + """, + testHost, + Keyword("var"), + Keyword("nameof")); + } - struct Type + [Theory, CombinatorialData] + public async Task NameOf2(TestHost testHost) + { + await TestAsync( + """ + class C + { + void goo() { - Type f; + var x = nameof(C); } - """, - testHost, - Struct("Type")); - } + } + """, + testHost, + Keyword("var"), + Keyword("nameof"), + Class("C")); + } - [Theory, CombinatorialData] - public async Task NameOf1(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task NameOfLocalMethod(TestHost testHost) + { + await TestAsync( + """ + class C + { + void goo() { - void goo() + var x = nameof(M); + + void M() { - var x = nameof } - } - """, - testHost, - Keyword("var"), - Keyword("nameof")); - } - [Theory, CombinatorialData] - public async Task NameOf2(TestHost testHost) - { - await TestAsync( - """ - class C - { - void goo() + void M(int a) { - var x = nameof(C); } - } - """, - testHost, - Keyword("var"), - Keyword("nameof"), - Class("C")); - } - [Theory, CombinatorialData] - public async Task NameOfLocalMethod(TestHost testHost) - { - await TestAsync( - """ - class C - { - void goo() + void M(string s) { - var x = nameof(M); - - void M() - { - } - - void M(int a) - { - } - - void M(string s) - { - } } } - """, - testHost, - Keyword("var"), - Keyword("nameof"), - Method("M")); - } + } + """, + testHost, + Keyword("var"), + Keyword("nameof"), + Method("M")); + } - [Theory, CombinatorialData] - public async Task MethodCalledNameOfInScope(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task MethodCalledNameOfInScope(TestHost testHost) + { + await TestAsync( + """ + class C + { + void nameof(int i) { - void nameof(int i) - { - } - - void goo() - { - int y = 3; - var x = nameof(); - } } - """, - testHost, - Keyword("var"), - Method("nameof")); - } - [Theory, CombinatorialData] - public async Task Tuples(TestHost testHost) - { - await TestAsync( - """ - class C + void goo() { - (int a, int b) x; + int y = 3; + var x = nameof(); } - """, - testHost, - ParseOptions(TestOptions.Regular, Options.Script)); - } + } + """, + testHost, + Keyword("var"), + Method("nameof")); + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/261049")] - public async Task DevDiv261049RegressionTest(TestHost testHost) - { - var source = """ - var (a,b) = Get(out int x, out int y); - Console.WriteLine($"({a.first}, {a.second})"); - """; - - await TestInMethodAsync( - source, - testHost, - Keyword("var"), Local("a"), Local("a")); - } + [Theory, CombinatorialData] + public async Task Tuples(TestHost testHost) + { + await TestAsync( + """ + class C + { + (int a, int b) x; + } + """, + testHost, + ParseOptions(TestOptions.Regular, Options.Script)); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/633")] - public async Task InXmlDocCref_WhenTypeOnlyIsSpecified_ItIsClassified(TestHost testHost) - { - await TestAsync( - """ - /// - /// - /// - class MyClass - { - public MyClass(int x) - { - } + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/261049")] + public async Task DevDiv261049RegressionTest(TestHost testHost) + { + var source = """ + var (a,b) = Get(out int x, out int y); + Console.WriteLine($"({a.first}, {a.second})"); + """; + + await TestInMethodAsync( + source, + testHost, + Keyword("var"), Local("a"), Local("a")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/633")] + public async Task InXmlDocCref_WhenTypeOnlyIsSpecified_ItIsClassified(TestHost testHost) + { + await TestAsync( + """ + /// + /// + /// + class MyClass + { + public MyClass(int x) + { } - """, - testHost, - Class("MyClass")); - } + } + """, + testHost, + Class("MyClass")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/633")] - public async Task InXmlDocCref_WhenConstructorOnlyIsSpecified_NothingIsClassified(TestHost testHost) - { - await TestAsync( - """ - /// - /// - /// - class MyClass - { - public MyClass(int x) - { - } + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/633")] + public async Task InXmlDocCref_WhenConstructorOnlyIsSpecified_NothingIsClassified(TestHost testHost) + { + await TestAsync( + """ + /// + /// + /// + class MyClass + { + public MyClass(int x) + { } - """, testHost, - Class("MyClass")); - } + } + """, testHost, + Class("MyClass")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/633")] - public async Task InXmlDocCref_WhenTypeAndConstructorSpecified_OnlyTypeIsClassified(TestHost testHost) - { - await TestAsync( - """ - /// - /// - /// - class MyClass - { - public MyClass(int x) - { - } + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/633")] + public async Task InXmlDocCref_WhenTypeAndConstructorSpecified_OnlyTypeIsClassified(TestHost testHost) + { + await TestAsync( + """ + /// + /// + /// + class MyClass + { + public MyClass(int x) + { } - """, - testHost, - Class("MyClass"), - Class("MyClass")); - } + } + """, + testHost, + Class("MyClass"), + Class("MyClass")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/13174")] - public async Task TestMemberBindingThatLooksGeneric(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics; - using System.Threading.Tasks; + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/13174")] + public async Task TestMemberBindingThatLooksGeneric(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics; + using System.Threading.Tasks; - namespace ConsoleApplication1 + namespace ConsoleApplication1 + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - Debug.Assert(args?.Length < 2); - } + Debug.Assert(args?.Length < 2); } } - """, - testHost, - Namespace("System"), - Namespace("Diagnostics"), - Namespace("System"), - Namespace("Threading"), - Namespace("Tasks"), - Namespace("ConsoleApplication1"), - Class("Debug"), - Static("Debug"), - Method("Assert"), - Static("Assert"), - Parameter("args"), - Property("Length")); - } + } + """, + testHost, + Namespace("System"), + Namespace("Diagnostics"), + Namespace("System"), + Namespace("Threading"), + Namespace("Tasks"), + Namespace("ConsoleApplication1"), + Class("Debug"), + Static("Debug"), + Method("Assert"), + Static("Assert"), + Parameter("args"), + Property("Length")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/23940")] - public async Task TestAliasQualifiedClass(TestHost testHost) - { - await TestAsync( - """ - using System; - using Col = System.Collections.Generic; + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/23940")] + public async Task TestAliasQualifiedClass(TestHost testHost) + { + await TestAsync( + """ + using System; + using Col = System.Collections.Generic; - namespace AliasTest + namespace AliasTest + { + class Program { - class Program + static void Main(string[] args) { - static void Main(string[] args) - { - var list1 = new Col::List - } + var list1 = new Col::List } } - """, - testHost, - Namespace("System"), - Namespace("Col"), - Namespace("System"), - Namespace("Collections"), - Namespace("Generic"), - Namespace("AliasTest"), - Keyword("var"), - Namespace("Col"), - Class("List")); - } + } + """, + testHost, + Namespace("System"), + Namespace("Col"), + Namespace("System"), + Namespace("Collections"), + Namespace("Generic"), + Namespace("AliasTest"), + Keyword("var"), + Namespace("Col"), + Class("List")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_InsideMethod(TestHost testHost) - { - // Asserts no Keyword("unmanaged") because it is an identifier. - await TestInMethodAsync(""" - var unmanaged = 0; - unmanaged++; - """, - testHost, - Keyword("var"), - Local("unmanaged")); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_InsideMethod(TestHost testHost) + { + // Asserts no Keyword("unmanaged") because it is an identifier. + await TestInMethodAsync(""" + var unmanaged = 0; + unmanaged++; + """, + testHost, + Keyword("var"), + Local("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_Keyword(TestHost testHost) - { - await TestAsync( - "class X where T : unmanaged { }", - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_Keyword(TestHost testHost) + { + await TestAsync( + "class X where T : unmanaged { }", + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + class X where T : unmanaged { } + """, + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface unmanaged {} - class X where T : unmanaged { } - """, - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + } + class X where T : unmanaged { } + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - class X where T : unmanaged { } - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("unmanaged")); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void M() where T : unmanaged { } + } + """, + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void M() where T : unmanaged { } - } - """, - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + class X + { + void M() where T : unmanaged { } + } + """, + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface unmanaged {} - class X - { - void M() where T : unmanaged { } - } - """, - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + } + class X + { + void M() where T : unmanaged { } + } + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - class X - { - void M() where T : unmanaged { } - } - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("unmanaged")); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_Keyword(TestHost testHost) + { + await TestAsync( + "delegate void D() where T : unmanaged;", + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_Keyword(TestHost testHost) - { - await TestAsync( - "delegate void D() where T : unmanaged;", - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + delegate void D() where T : unmanaged; + """, + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface unmanaged {} - delegate void D() where T : unmanaged; - """, - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + } + delegate void D() where T : unmanaged; + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - interface unmanaged {} + void M() where T : unmanaged { } } - delegate void D() where T : unmanaged; - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("unmanaged")); - } + } + """, + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_Keyword(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + class X + { + void N() { - void N() - { - void M() where T : unmanaged { } - } + void M() where T : unmanaged { } } - """, - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } + } + """, + testHost, + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface unmanaged {} - class X - { - void N() - { - void M() where T : unmanaged { } - } - } - """, - testHost, - TypeParameter("T"), - Keyword("unmanaged")); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - class X + } + class X + { + void N() { - void N() - { - void M() where T : unmanaged { } - } + void M() where T : unmanaged { } } - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("unmanaged")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29451")] - [CombinatorialData] - public async Task TestDirectiveStringLiteral(TestHost testHost) - => await TestInMethodAsync(""" - #line 1 "a\b" - """, testHost); + } + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("unmanaged")); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/30378")] - [CombinatorialData] - public async Task TestFormatSpecifierInInterpolation(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo{{1:0000}}bar"";", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29451")] + [CombinatorialData] + public async Task TestDirectiveStringLiteral(TestHost testHost) + => await TestInMethodAsync(""" + #line 1 "a\b" + """, testHost); - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] - [CombinatorialData] - public async Task TestOverloadedOperator_BinaryExpression(TestHost testHost) - { - await TestAsync(""" - class C - { - void M() - { - var a = 1 + 1; - var b = new True() + new True(); - } - } - class True - { - public static True operator +(True a, True b) - { - return new True(); - } - } - """, - testHost, - Keyword("var"), - Keyword("var"), - Class("True"), - OverloadedOperators.Plus, - Class("True"), - Class("True"), - Class("True"), - Class("True"), - Class("True")); - } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/30378")] + [CombinatorialData] + public async Task TestFormatSpecifierInInterpolation(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo{{1:0000}}bar"";", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] - [CombinatorialData] - public async Task TestOverloadedOperator_PrefixUnaryExpression(TestHost testHost) - { - await TestAsync(""" - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] + [CombinatorialData] + public async Task TestOverloadedOperator_BinaryExpression(TestHost testHost) + { + await TestAsync(""" + class C + { + void M() { - void M() - { - var a = !false; - var b = !new True(); - } + var a = 1 + 1; + var b = new True() + new True(); } - class True + } + class True + { + public static True operator +(True a, True b) { - public static bool operator !(True a) - { - return false; - } + return new True(); } - """, - testHost, - Keyword("var"), - Keyword("var"), - OverloadedOperators.Exclamation, - Class("True"), - Class("True")); - } + } + """, + testHost, + Keyword("var"), + Keyword("var"), + Class("True"), + OverloadedOperators.Plus, + Class("True"), + Class("True"), + Class("True"), + Class("True"), + Class("True")); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] - [CombinatorialData] - public async Task TestOverloadedOperator_PostfixUnaryExpression(TestHost testHost) - { - await TestAsync(""" - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] + [CombinatorialData] + public async Task TestOverloadedOperator_PrefixUnaryExpression(TestHost testHost) + { + await TestAsync(""" + class C + { + void M() { - void M() - { - var a = 1; - a++; - var b = new True(); - b++; - } + var a = !false; + var b = !new True(); } - class True + } + class True + { + public static bool operator !(True a) { - public static True operator ++(True a) - { - return new True(); - } + return false; } - """, - testHost, - Keyword("var"), - Local("a"), - Keyword("var"), - Class("True"), - Local("b"), - OverloadedOperators.PlusPlus, - Class("True"), - Class("True"), - Class("True")); - } + } + """, + testHost, + Keyword("var"), + Keyword("var"), + OverloadedOperators.Exclamation, + Class("True"), + Class("True")); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] - [CombinatorialData] - public async Task TestOverloadedOperator_ConditionalExpression(TestHost testHost) - { - await TestAsync(""" - class C + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] + [CombinatorialData] + public async Task TestOverloadedOperator_PostfixUnaryExpression(TestHost testHost) + { + await TestAsync(""" + class C + { + void M() { - void M() - { - var a = 1 == 1; - var b = new True() == new True(); - } + var a = 1; + a++; + var b = new True(); + b++; } - class True + } + class True + { + public static True operator ++(True a) { - public static bool operator ==(True a, True b) - { - return true; - } + return new True(); } - """, - testHost, - Keyword("var"), - Keyword("var"), - Class("True"), - OverloadedOperators.EqualsEquals, - Class("True"), - Class("True"), - Class("True")); - } + } + """, + testHost, + Keyword("var"), + Local("a"), + Keyword("var"), + Class("True"), + Local("b"), + OverloadedOperators.PlusPlus, + Class("True"), + Class("True"), + Class("True")); + } - [Theory, CombinatorialData] - public async Task TestCatchDeclarationVariable(TestHost testHost) - { - await TestInMethodAsync(""" - try + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] + [CombinatorialData] + public async Task TestOverloadedOperator_ConditionalExpression(TestHost testHost) + { + await TestAsync(""" + class C + { + void M() { + var a = 1 == 1; + var b = new True() == new True(); } - catch (Exception ex) + } + class True + { + public static bool operator ==(True a, True b) { - throw ex; + return true; } - """, - testHost, - Local("ex")); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_InsideMethod(TestHost testHost) - { - // Asserts no Keyword("notnull") because it is an identifier. - await TestInMethodAsync(""" - var notnull = 0; - notnull++; - """, - testHost, - Keyword("var"), - Local("notnull")); - } + } + """, + testHost, + Keyword("var"), + Keyword("var"), + Class("True"), + OverloadedOperators.EqualsEquals, + Class("True"), + Class("True"), + Class("True")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_Keyword(TestHost testHost) - { - await TestAsync( - "class X where T : notnull { }", - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestCatchDeclarationVariable(TestHost testHost) + { + await TestInMethodAsync(""" + try + { + } + catch (Exception ex) + { + throw ex; + } + """, + testHost, + Local("ex")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_ExistingInterface(TestHost testHost) - { - await TestAsync(""" - interface notnull {} - class X where T : notnull { } - """, - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_InsideMethod(TestHost testHost) + { + // Asserts no Keyword("notnull") because it is an identifier. + await TestInMethodAsync(""" + var notnull = 0; + notnull++; + """, + testHost, + Keyword("var"), + Local("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - class X where T : notnull { } - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_Keyword(TestHost testHost) + { + await TestAsync( + "class X where T : notnull { }", + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void M() where T : notnull { } - } - """, - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + class X where T : notnull { } + """, + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface notnull {} - class X - { - void M() where T : notnull { } - } - """, - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + } + class X where T : notnull { } + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - class X - { - void M() where T : notnull { } - } - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void M() where T : notnull { } + } + """, + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_Keyword(TestHost testHost) - { - await TestAsync( - "delegate void D() where T : notnull;", - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + class X + { + void M() where T : notnull { } + } + """, + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface notnull {} - delegate void D() where T : notnull; - """, - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + } + class X + { + void M() where T : notnull { } + } + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - delegate void D() where T : notnull; - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_Keyword(TestHost testHost) + { + await TestAsync( + "delegate void D() where T : notnull;", + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void N() - { - void M() where T : notnull { } - } - } - """, - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + delegate void D() where T : notnull; + """, + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface notnull {} - class X + } + delegate void D() where T : notnull; + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("notnull")); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - void M() where T : notnull { } - } + void M() where T : notnull { } } - """, - testHost, - TypeParameter("T"), - Keyword("notnull")); - } + } + """, + testHost, + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + class X + { + void N() { - interface notnull {} + void M() where T : notnull { } } - class X + } + """, + testHost, + TypeParameter("T"), + Keyword("notnull")); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { + interface notnull {} + } + class X + { + void N() { - void N() - { - void M() where T : notnull { } - } + void M() where T : notnull { } } - """, - testHost, - Namespace("OtherScope"), - TypeParameter("T"), - Keyword("notnull")); - } + } + """, + testHost, + Namespace("OtherScope"), + TypeParameter("T"), + Keyword("notnull")); + } - [Theory, CombinatorialData] - public async Task NonDiscardVariableDeclaration(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task NonDiscardVariableDeclaration(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - var _ = int.Parse(""); - } + var _ = int.Parse(""); } - """, - testHost, - Keyword("var"), - Method("Parse"), - Static("Parse")); - } + } + """, + testHost, + Keyword("var"), + Method("Parse"), + Static("Parse")); + } - [Theory, CombinatorialData] - public async Task NonDiscardVariableDeclarationMultipleDeclarators(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task NonDiscardVariableDeclarationMultipleDeclarators(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - int i = 1, _ = 1; - int _ = 2, j = 1; - } + int i = 1, _ = 1; + int _ = 2, j = 1; } - """, testHost); - } + } + """, testHost); + } - [Theory, CombinatorialData] - public async Task DiscardAssignment(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardAssignment(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - _ = int.Parse(""); - } + _ = int.Parse(""); } - """, - testHost, - Keyword("_"), - Method("Parse"), - Static("Parse")); - } + } + """, + testHost, + Keyword("_"), + Method("Parse"), + Static("Parse")); + } - [Theory, CombinatorialData] - public async Task DiscardInOutDeclaration(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInOutDeclaration(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - int.TryParse("", out var _); - } + int.TryParse("", out var _); } - """, - testHost, - Method("TryParse"), - Static("TryParse"), - Keyword("var"), - Keyword("_")); - } + } + """, + testHost, + Method("TryParse"), + Static("TryParse"), + Keyword("var"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardInOutAssignment(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInOutAssignment(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - int.TryParse("", out _); - } + int.TryParse("", out _); } - """, - testHost, - Method("TryParse"), - Static("TryParse"), - Keyword("_")); - } + } + """, + testHost, + Method("TryParse"), + Static("TryParse"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardInDeconstructionAssignment(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInDeconstructionAssignment(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - (x, _) = (0, 0); - } + (x, _) = (0, 0); } - """, - testHost, - Keyword("_")); - } + } + """, + testHost, + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardInDeconstructionDeclaration(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInDeconstructionDeclaration(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - (int x, int _) = (0, 0); - } + (int x, int _) = (0, 0); } - """, - testHost, - Keyword("_")); - } + } + """, + testHost, + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardInPatternMatch(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInPatternMatch(TestHost testHost) + { + await TestAsync(""" + class X + { + bool N(object x) { - bool N(object x) - { - return x is int _; - } + return x is int _; } - """, - testHost, - Parameter("x"), - Keyword("_")); - } + } + """, + testHost, + Parameter("x"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardInSwitch(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInSwitch(TestHost testHost) + { + await TestAsync(""" + class X + { + bool N(object x) { - bool N(object x) + switch(x) { - switch(x) - { - case int _: - return true; - default: - return false; - } + case int _: + return true; + default: + return false; } } - """, - testHost, - Parameter("x"), - Keyword("_")); - } + } + """, + testHost, + Parameter("x"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardInSwitchPatternMatch(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardInSwitchPatternMatch(TestHost testHost) + { + await TestAsync(""" + class X + { + bool N(object x) { - bool N(object x) + return x switch { - return x switch - { - _ => return true; - }; - } + _ => return true; + }; } - """, - testHost, - Parameter("x"), - Keyword("_")); - } + } + """, + testHost, + Parameter("x"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task UnusedUnderscoreParameterInLambda(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task UnusedUnderscoreParameterInLambda(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - System.Func a = (int _) => 0; - } + System.Func a = (int _) => 0; } - """, - testHost, - Namespace("System"), - Delegate("Func")); - } + } + """, + testHost, + Namespace("System"), + Delegate("Func")); + } - [Theory, CombinatorialData] - public async Task UsedUnderscoreParameterInLambda(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task UsedUnderscoreParameterInLambda(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - System.Func a = (int _) => _; - } + System.Func a = (int _) => _; } - """, - testHost, - Namespace("System"), - Delegate("Func"), - Parameter("_")); - } + } + """, + testHost, + Namespace("System"), + Delegate("Func"), + Parameter("_")); + } - [Theory, CombinatorialData] - public async Task DiscardsInLambda(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardsInLambda(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - System.Func a = (int _, int _) => 0; - } + System.Func a = (int _, int _) => 0; } - """, - testHost, - Namespace("System"), - Delegate("Func"), - Keyword("_"), - Keyword("_")); - } + } + """, + testHost, + Namespace("System"), + Delegate("Func"), + Keyword("_"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task DiscardsInLambdaWithInferredType(TestHost testHost) - { - await TestAsync(""" - class X + [Theory, CombinatorialData] + public async Task DiscardsInLambdaWithInferredType(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { - void N() - { - System.Func a = (_, _) => 0; - } + System.Func a = (_, _) => 0; } - """, - testHost, - Namespace("System"), - Delegate("Func"), - Keyword("_"), - Keyword("_")); - } + } + """, + testHost, + Namespace("System"), + Delegate("Func"), + Keyword("_"), + Keyword("_")); + } - [Theory, CombinatorialData] - public async Task NativeInteger(TestHost testHost) - { - await TestInMethodAsync( - @"nint i = 0; nuint i2 = 0;", - testHost, - Classifications(Keyword("nint"), Keyword("nuint"))); - } + [Theory, CombinatorialData] + public async Task NativeInteger(TestHost testHost) + { + await TestInMethodAsync( + @"nint i = 0; nuint i2 = 0;", + testHost, + Classifications(Keyword("nint"), Keyword("nuint"))); + } - [Theory, CombinatorialData] - public async Task NotNativeInteger(TestHost testHost) - { - await TestInMethodAsync( - "nint", - "M", - "nint i = 0;", - testHost, - Classifications(Class("nint"))); - } + [Theory, CombinatorialData] + public async Task NotNativeInteger(TestHost testHost) + { + await TestInMethodAsync( + "nint", + "M", + "nint i = 0;", + testHost, + Classifications(Class("nint"))); + } - [Theory, CombinatorialData] - public async Task NotNativeUnsignedInteger(TestHost testHost) - { - await TestInMethodAsync( - "nuint", - "M", - "nuint i = 0;", - testHost, - Classifications(Class("nuint"))); - } + [Theory, CombinatorialData] + public async Task NotNativeUnsignedInteger(TestHost testHost) + { + await TestInMethodAsync( + "nuint", + "M", + "nuint i = 0;", + testHost, + Classifications(Class("nuint"))); + } - [Theory, CombinatorialData] - public async Task StaticBoldingMethodName(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task StaticBoldingMethodName(TestHost testHost) + { + await TestAsync( + """ + class C + { + public static void Method() { - public static void Method() - { - System.Action action = Method; - } + System.Action action = Method; } - """, - testHost, - Namespace("System"), - Delegate("Action"), - Method("Method"), - Static("Method")); - } + } + """, + testHost, + Namespace("System"), + Delegate("Action"), + Method("Method"), + Static("Method")); + } - [Theory, CombinatorialData] - public async Task StaticBoldingMethodNameNestedInNameof(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task StaticBoldingMethodNameNestedInNameof(TestHost testHost) + { + await TestAsync( + """ + class C + { + public static void Method() { - public static void Method() - { - _ = nameof(Method); - } + _ = nameof(Method); } - """, - testHost, - Keyword("_"), - Keyword("nameof"), - Static("Method"), - Method("Method")); - } + } + """, + testHost, + Keyword("_"), + Keyword("nameof"), + Static("Method"), + Method("Method")); + } - [Theory, CombinatorialData] - public async Task BoldingMethodNameStaticAndNot(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task BoldingMethodNameStaticAndNot(TestHost testHost) + { + await TestAsync( + """ + class C + { + public static void Method() { - public static void Method() - { - } + } - public void Method(int x) - { + public void Method(int x) + { - } + } - public void Test() { - _ = nameof(Method); - } + public void Test() { + _ = nameof(Method); } - """, - testHost, - Keyword("_"), - Keyword("nameof"), - Static("Method"), - Method("Method")); - } + } + """, + testHost, + Keyword("_"), + Keyword("nameof"), + Static("Method"), + Method("Method")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/46985")] - public async Task BasicRecordClassification(TestHost testHost) - { - await TestAsync( - """ - record R - { - R r; + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/46985")] + public async Task BasicRecordClassification(TestHost testHost) + { + await TestAsync( + """ + record R + { + R r; - R() { } - } - """, - testHost, - RecordClass("R")); - } + R() { } + } + """, + testHost, + RecordClass("R")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/46985")] - public async Task ParameterizedRecordClassification(TestHost testHost) - { - await TestAsync( - """ - record R(int X, int Y); + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/46985")] + public async Task ParameterizedRecordClassification(TestHost testHost) + { + await TestAsync( + """ + record R(int X, int Y); - class C - { - R r; - } - """, - testHost, - RecordClass("R")); - } + class C + { + R r; + } + """, + testHost, + RecordClass("R")); + } - [Theory, CombinatorialData] - public async Task BasicRecordClassClassification(TestHost testHost) - { - await TestAsync( - """ - record class R - { - R r; + [Theory, CombinatorialData] + public async Task BasicRecordClassClassification(TestHost testHost) + { + await TestAsync( + """ + record class R + { + R r; - R() { } - } - """, - testHost, - RecordClass("R")); - } + R() { } + } + """, + testHost, + RecordClass("R")); + } - [Theory, CombinatorialData] - public async Task BasicRecordStructClassification(TestHost testHost) - { - await TestAsync( - """ - record struct R - { - R property { get; set; } - } - """, - testHost, - RecordStruct("R")); - } + [Theory, CombinatorialData] + public async Task BasicRecordStructClassification(TestHost testHost) + { + await TestAsync( + """ + record struct R + { + R property { get; set; } + } + """, + testHost, + RecordStruct("R")); + } - [Theory, CombinatorialData] - public async Task BasicFileScopedNamespaceClassification(TestHost testHost) - { - await TestAsync( - """ - namespace NS; - - class C { } - """, - testHost, - Namespace("NS")); - } + [Theory, CombinatorialData] + public async Task BasicFileScopedNamespaceClassification(TestHost testHost) + { + await TestAsync( + """ + namespace NS; + + class C { } + """, + testHost, + Namespace("NS")); + } - [Theory, CombinatorialData] - public async Task NullCheckedParameterClassification(TestHost testHost) - { - await TestAsync( - """ - class C - { - void M(string s!!) { } - } - """, - testHost); - } + [Theory, CombinatorialData] + public async Task NullCheckedParameterClassification(TestHost testHost) + { + await TestAsync( + """ + class C + { + void M(string s!!) { } + } + """, + testHost); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/57184")] - public async Task MethodGroupClassifications(TestHost testHost) - { - await TestAsync( - """ - var f = m; - Delegate d = m; - MulticastDelegate md = m; - ICloneable c = m; - object obj = m; - m(m); - - int m(Delegate d) { } - """, - testHost, - Keyword("var"), - Method("m"), - Method("m"), - Method("m"), - Method("m"), - Method("m"), - Method("m"), - Method("m")); - } + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/57184")] + public async Task MethodGroupClassifications(TestHost testHost) + { + await TestAsync( + """ + var f = m; + Delegate d = m; + MulticastDelegate md = m; + ICloneable c = m; + object obj = m; + m(m); + + int m(Delegate d) { } + """, + testHost, + Keyword("var"), + Method("m"), + Method("m"), + Method("m"), + Method("m"), + Method("m"), + Method("m"), + Method("m")); + } - /// - /// - [Theory, CombinatorialData] - public async Task LocalFunctionUse(TestHost testHost) - { - await TestAsync( - """ - using System; + /// + /// + [Theory, CombinatorialData] + public async Task LocalFunctionUse(TestHost testHost) + { + await TestAsync( + """ + using System; - class C + class C + { + void M(Action action) { - void M(Action action) - { - [|localFunction(); - staticLocalFunction(); + [|localFunction(); + staticLocalFunction(); - M(localFunction); - M(staticLocalFunction); + M(localFunction); + M(staticLocalFunction); - void localFunction() { } - static void staticLocalFunction() { }|] - } + void localFunction() { } + static void staticLocalFunction() { }|] } + } - """, - testHost, - Method("localFunction"), - Method("staticLocalFunction"), - Static("staticLocalFunction"), - Method("M"), - Method("localFunction"), - Method("M"), - Method("staticLocalFunction"), - Static("staticLocalFunction")); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/744813")] - public async Task TestCreateWithBufferNotInWorkspace() - { - // don't crash - using var workspace = EditorTestWorkspace.CreateCSharp(""); - var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id); + """, + testHost, + Method("localFunction"), + Method("staticLocalFunction"), + Static("staticLocalFunction"), + Method("M"), + Method("localFunction"), + Method("M"), + Method("staticLocalFunction"), + Static("staticLocalFunction")); + } - var contentTypeService = document.GetRequiredLanguageService(); - var contentType = contentTypeService.GetDefaultContentType(); - var extraBuffer = workspace.ExportProvider.GetExportedValue().CreateTextBuffer("", contentType); + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/744813")] + public async Task TestCreateWithBufferNotInWorkspace() + { + // don't crash + using var workspace = EditorTestWorkspace.CreateCSharp(""); + var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id); - WpfTestRunner.RequireWpfFact($"Creates an {nameof(IWpfTextView)} explicitly with an unrelated buffer"); - using var disposableView = workspace.ExportProvider.GetExportedValue().CreateDisposableTextView(extraBuffer); - var listenerProvider = workspace.ExportProvider.GetExportedValue(); - var globalOptions = workspace.ExportProvider.GetExportedValue(); + var contentTypeService = document.GetRequiredLanguageService(); + var contentType = contentTypeService.GetDefaultContentType(); + var extraBuffer = workspace.ExportProvider.GetExportedValue().CreateTextBuffer("", contentType); - var provider = new SemanticClassificationViewTaggerProvider( - workspace.GetService(), - workspace.GetService(), - globalOptions, - visibilityTracker: null, - listenerProvider); + WpfTestRunner.RequireWpfFact($"Creates an {nameof(IWpfTextView)} explicitly with an unrelated buffer"); + using var disposableView = workspace.ExportProvider.GetExportedValue().CreateDisposableTextView(extraBuffer); + var listenerProvider = workspace.ExportProvider.GetExportedValue(); + var globalOptions = workspace.ExportProvider.GetExportedValue(); - using var tagger = provider.CreateTagger(disposableView.TextView, extraBuffer); - using (var edit = extraBuffer.CreateEdit()) - { - edit.Insert(0, "class A { }"); - edit.Apply(); - } + var provider = new SemanticClassificationViewTaggerProvider( + workspace.GetService(), + workspace.GetService(), + globalOptions, + visibilityTracker: null, + listenerProvider); - var waiter = listenerProvider.GetWaiter(FeatureAttribute.Classification); - await waiter.ExpeditedWaitAsync(); + using var tagger = provider.CreateTagger(disposableView.TextView, extraBuffer); + using (var edit = extraBuffer.CreateEdit()) + { + edit.Insert(0, "class A { }"); + edit.Apply(); } + + var waiter = listenerProvider.GetWaiter(FeatureAttribute.Classification); + await waiter.ExpeditedWaitAsync(); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Json.cs b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Json.cs index 51aaed31e3993..a2cd0d8506acb 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Json.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Json.cs @@ -9,342 +9,341 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +public partial class SemanticClassifierTests { - public partial class SemanticClassifierTests + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/68534")] + public async Task TestJson1(TestHost testHost) { - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/68534")] - public async Task TestJson1(TestHost testHost) - { - await TestAsync( - """ - class Program + await TestAsync( + """ + class Program + { + void Goo() { - void Goo() - { - // lang=json - var r = @"[/*comment*/{ 'goo': 0, bar: -Infinity, ""baz"": true }, new Date(), text, 'str'] // comment"; - } + // lang=json + var r = @"[/*comment*/{ 'goo': 0, bar: -Infinity, ""baz"": true }, new Date(), text, 'str'] // comment"; } - """, - testHost, - Keyword("var"), - Json.Array("["), - Json.Comment("/*comment*/"), - Json.Object("{"), - Json.PropertyName("'goo'"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Punctuation(","), - Json.PropertyName("bar"), - Json.Punctuation(":"), - Json.Operator("-"), - Json.Keyword("Infinity"), - Json.Punctuation(","), - Json.PropertyName(""" - ""baz"" - """), - Json.Punctuation(":"), - Json.Keyword("true"), - Json.Object("}"), - Json.Punctuation(","), - Json.Keyword("new"), - Json.ConstructorName("Date"), - Json.Punctuation("("), - Json.Punctuation(")"), - Json.Punctuation(","), - Json.Text("text"), - Json.Punctuation(","), - Json.String("'str'"), - Json.Array("]"), - Json.Comment("// comment")); - } + } + """, + testHost, + Keyword("var"), + Json.Array("["), + Json.Comment("/*comment*/"), + Json.Object("{"), + Json.PropertyName("'goo'"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Punctuation(","), + Json.PropertyName("bar"), + Json.Punctuation(":"), + Json.Operator("-"), + Json.Keyword("Infinity"), + Json.Punctuation(","), + Json.PropertyName(""" + ""baz"" + """), + Json.Punctuation(":"), + Json.Keyword("true"), + Json.Object("}"), + Json.Punctuation(","), + Json.Keyword("new"), + Json.ConstructorName("Date"), + Json.Punctuation("("), + Json.Punctuation(")"), + Json.Punctuation(","), + Json.Text("text"), + Json.Punctuation(","), + Json.String("'str'"), + Json.Array("]"), + Json.Comment("// comment")); + } - [Theory, CombinatorialData] - public async Task TestJson_RawString(TestHost testHost) - { - await TestAsync( - """" - class Program + [Theory, CombinatorialData] + public async Task TestJson_RawString(TestHost testHost) + { + await TestAsync( + """" + class Program + { + void Goo() { - void Goo() - { - // lang=json - var r = """[/*comment*/{ 'goo': 0 }]"""; - } + // lang=json + var r = """[/*comment*/{ 'goo': 0 }]"""; } - """", - testHost, - Keyword("var"), - Json.Array("["), - Json.Comment("/*comment*/"), - Json.Object("{"), - Json.PropertyName("'goo'"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Object("}"), - Json.Array("]")); - } + } + """", + testHost, + Keyword("var"), + Json.Array("["), + Json.Comment("/*comment*/"), + Json.Object("{"), + Json.PropertyName("'goo'"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Object("}"), + Json.Array("]")); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/68534")] - public async Task TestMultiLineJson1(TestHost testHost) - { - await TestAsync( - """ - class Program + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/68534")] + public async Task TestMultiLineJson1(TestHost testHost) + { + await TestAsync( + """ + class Program + { + void Goo() { - void Goo() - { - // lang=json - var r = @"[ - /*comment*/ - { - 'goo': 0, - bar: -Infinity, - ""baz"": true, - 0: null - }, - new Date(), - text, - 'str'] // comment"; - } + // lang=json + var r = @"[ + /*comment*/ + { + 'goo': 0, + bar: -Infinity, + ""baz"": true, + 0: null + }, + new Date(), + text, + 'str'] // comment"; } - """, - testHost, - Keyword("var"), - Json.Array("["), - Json.Comment("/*comment*/"), - Json.Object("{"), - Json.PropertyName("'goo'"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Punctuation(","), - Json.PropertyName("bar"), - Json.Punctuation(":"), - Json.Operator("-"), - Json.Keyword("Infinity"), - Json.Punctuation(","), - Json.PropertyName(""" - ""baz"" - """), - Json.Punctuation(":"), - Json.Keyword("true"), - Json.Punctuation(","), - Json.PropertyName("0"), - Json.Punctuation(":"), - Json.Keyword("null"), - Json.Object("}"), - Json.Punctuation(","), - Json.Keyword("new"), - Json.ConstructorName("Date"), - Json.Punctuation("("), - Json.Punctuation(")"), - Json.Punctuation(","), - Json.Text("text"), - Json.Punctuation(","), - Json.String("'str'"), - Json.Array("]"), - Json.Comment("// comment")); - } + } + """, + testHost, + Keyword("var"), + Json.Array("["), + Json.Comment("/*comment*/"), + Json.Object("{"), + Json.PropertyName("'goo'"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Punctuation(","), + Json.PropertyName("bar"), + Json.Punctuation(":"), + Json.Operator("-"), + Json.Keyword("Infinity"), + Json.Punctuation(","), + Json.PropertyName(""" + ""baz"" + """), + Json.Punctuation(":"), + Json.Keyword("true"), + Json.Punctuation(","), + Json.PropertyName("0"), + Json.Punctuation(":"), + Json.Keyword("null"), + Json.Object("}"), + Json.Punctuation(","), + Json.Keyword("new"), + Json.ConstructorName("Date"), + Json.Punctuation("("), + Json.Punctuation(")"), + Json.Punctuation(","), + Json.Text("text"), + Json.Punctuation(","), + Json.String("'str'"), + Json.Array("]"), + Json.Comment("// comment")); + } - [Theory, CombinatorialData] - public async Task TestJson_NoComment_NotLikelyJson(TestHost testHost) - { - var input = """ - class C + [Theory, CombinatorialData] + public async Task TestJson_NoComment_NotLikelyJson(TestHost testHost) + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = @"[1, 2, 3]"; - } + var r = @"[1, 2, 3]"; } - """; - await TestAsync(input, - testHost, - Keyword("var")); - } + } + """; + await TestAsync(input, + testHost, + Keyword("var")); + } - [Theory, CombinatorialData] - public async Task TestJson_NoComment_LikelyJson(TestHost testHost) - { - var input = """ - class C + [Theory, CombinatorialData] + public async Task TestJson_NoComment_LikelyJson(TestHost testHost) + { + var input = """ + class C + { + void Goo() { - void Goo() - { - var r = @"[1, { prop: 0 }, 3]"; - } + var r = @"[1, { prop: 0 }, 3]"; } - """; - await TestAsync(input, - testHost, - Keyword("var"), - Json.Array("["), - Json.Number("1"), - Json.Punctuation(","), - Json.Object("{"), - Json.PropertyName("prop"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Object("}"), - Json.Punctuation(","), - Json.Number("3"), - Json.Array("]")); - } + } + """; + await TestAsync(input, + testHost, + Keyword("var"), + Json.Array("["), + Json.Number("1"), + Json.Punctuation(","), + Json.Object("{"), + Json.PropertyName("prop"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Object("}"), + Json.Punctuation(","), + Json.Number("3"), + Json.Array("]")); + } - [Theory, CombinatorialData] - public async Task TestJsonOnApiWithStringSyntaxAttribute_Field(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; + [Theory, CombinatorialData] + public async Task TestJsonOnApiWithStringSyntaxAttribute_Field(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; - class Program + class Program + { + [StringSyntax(StringSyntaxAttribute.Json)] + private string field; + void Goo() { - [StringSyntax(StringSyntaxAttribute.Json)] - private string field; - void Goo() - { - [|this.field = @"[{ 'goo': 0}]";|] - } + [|this.field = @"[{ 'goo': 0}]";|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Field("field"), - Json.Array("["), - Json.Object("{"), - Json.PropertyName("'goo'"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Object("}"), - Json.Array("]")); - } + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Field("field"), + Json.Array("["), + Json.Object("{"), + Json.PropertyName("'goo'"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Object("}"), + Json.Array("]")); + } - [Theory, CombinatorialData] - public async Task TestJsonOnApiWithStringSyntaxAttribute_Property(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; + [Theory, CombinatorialData] + public async Task TestJsonOnApiWithStringSyntaxAttribute_Property(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; - class Program + class Program + { + [StringSyntax(StringSyntaxAttribute.Json)] + private string Prop { get; set; } + void Goo() { - [StringSyntax(StringSyntaxAttribute.Json)] - private string Prop { get; set; } - void Goo() - { - [|this.Prop = @"[{ 'goo': 0}]";|] - } + [|this.Prop = @"[{ 'goo': 0}]";|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Property("Prop"), - Json.Array("["), - Json.Object("{"), - Json.PropertyName("'goo'"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Object("}"), - Json.Array("]")); - } + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Property("Prop"), + Json.Array("["), + Json.Object("{"), + Json.PropertyName("'goo'"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Object("}"), + Json.Array("]")); + } - [Theory, CombinatorialData] - public async Task TestJsonOnApiWithStringSyntaxAttribute_Argument(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; + [Theory, CombinatorialData] + public async Task TestJsonOnApiWithStringSyntaxAttribute_Argument(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; - class Program + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Json)] string p) { - private void M([StringSyntax(StringSyntaxAttribute.Json)] string p) - { - } - - void Goo() - { - [|M(@"[{ 'goo': 0}]");|] - } } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Json.Array("["), - Json.Object("{"), - Json.PropertyName("'goo'"), - Json.Punctuation(":"), - Json.Number("0"), - Json.Object("}"), - Json.Array("]")); - } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/69237")] - public async Task TestJsonOnApiWithStringSyntaxAttribute_PropertyInitializer(TestHost testHost) - { - await TestAsync( - """" - using System.Diagnostics.CodeAnalysis; - - public sealed record Foo + void Goo() { - [StringSyntax(StringSyntaxAttribute.Json)] - public required string Bar { get; set; } + [|M(@"[{ 'goo': 0}]");|] } + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Json.Array("["), + Json.Object("{"), + Json.PropertyName("'goo'"), + Json.Punctuation(":"), + Json.Number("0"), + Json.Object("}"), + Json.Array("]")); + } - class Program - { - void Goo() - { - var f = new Foo { [|Bar = """[1, 2, 3]"""|] }; - } - } - """" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Property("Bar"), - Json.Array("["), - Json.Number("1"), - Json.Punctuation(","), - Json.Number("2"), - Json.Punctuation(","), - Json.Number("3"), - Json.Array("]")); - } + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/69237")] + public async Task TestJsonOnApiWithStringSyntaxAttribute_PropertyInitializer(TestHost testHost) + { + await TestAsync( + """" + using System.Diagnostics.CodeAnalysis; - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/69237")] - public async Task TestJsonOnApiWithStringSyntaxAttribute_WithExpression(TestHost testHost) - { - await TestAsync( - """" - using System.Diagnostics.CodeAnalysis; + public sealed record Foo + { + [StringSyntax(StringSyntaxAttribute.Json)] + public required string Bar { get; set; } + } - public sealed record Foo + class Program + { + void Goo() { - [StringSyntax(StringSyntaxAttribute.Json)] - public required string Bar { get; set; } + var f = new Foo { [|Bar = """[1, 2, 3]"""|] }; } + } + """" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Property("Bar"), + Json.Array("["), + Json.Number("1"), + Json.Punctuation(","), + Json.Number("2"), + Json.Punctuation(","), + Json.Number("3"), + Json.Array("]")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/69237")] + public async Task TestJsonOnApiWithStringSyntaxAttribute_WithExpression(TestHost testHost) + { + await TestAsync( + """" + using System.Diagnostics.CodeAnalysis; + + public sealed record Foo + { + [StringSyntax(StringSyntaxAttribute.Json)] + public required string Bar { get; set; } + } - class Program + class Program + { + void Goo() { - void Goo() - { - var f = new Foo { Bar = "" }; - f = f with { [|Bar = """[1, 2, 3]"""|] }; - } + var f = new Foo { Bar = "" }; + f = f with { [|Bar = """[1, 2, 3]"""|] }; } - """" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Property("Bar"), - Json.Array("["), - Json.Number("1"), - Json.Punctuation(","), - Json.Number("2"), - Json.Punctuation(","), - Json.Number("3"), - Json.Array("]")); - } + } + """" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Property("Bar"), + Json.Array("["), + Json.Number("1"), + Json.Punctuation(","), + Json.Number("2"), + Json.Punctuation(","), + Json.Number("3"), + Json.Array("]")); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Regex.cs b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Regex.cs index 395eed27a1de5..c1a4348299cd1 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Regex.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_Regex.cs @@ -9,1308 +9,1307 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +public partial class SemanticClassifierTests { - public partial class SemanticClassifierTests + [Theory, CombinatorialData] + public async Task TestRegex1(TestHost testHost) { - [Theory, CombinatorialData] - public async Task TestRegex1(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - var r = new Regex(@"$(\a\t\u0020)|[^\p{Lu}-a\w\sa-z-[m-p]]+?(?#comment)|(\b\G\z)|(?sub){0,5}?^"); - } - } - """, - testHost, - Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Class("Regex"), - Regex.Anchor("$"), - Regex.Grouping("("), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("t"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("u"), - Regex.OtherEscape("0020"), - Regex.Grouping(")"), - Regex.Alternation("|"), - Regex.CharacterClass("["), - Regex.CharacterClass("^"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("p"), - Regex.CharacterClass("{"), - Regex.CharacterClass("Lu"), - Regex.CharacterClass("}"), - Regex.Text("-a"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("w"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("s"), - Regex.Text("a"), - Regex.CharacterClass("-"), - Regex.Text("z"), - Regex.CharacterClass("-"), - Regex.CharacterClass("["), - Regex.Text("m"), - Regex.CharacterClass("-"), - Regex.Text("p"), - Regex.CharacterClass("]"), - Regex.CharacterClass("]"), - Regex.Quantifier("+"), - Regex.Quantifier("?"), - Regex.Comment("(?#comment)"), - Regex.Alternation("|"), - Regex.Grouping("("), - Regex.Anchor("\\"), - Regex.Anchor("b"), - Regex.Anchor("\\"), - Regex.Anchor("G"), - Regex.Anchor("\\"), - Regex.Anchor("z"), - Regex.Grouping(")"), - Regex.Alternation("|"), - Regex.Grouping("("), - Regex.Grouping("?"), - Regex.Grouping("<"), - Regex.Grouping("name"), - Regex.Grouping(">"), - Regex.Text("sub"), - Regex.Grouping(")"), - Regex.Quantifier("{"), - Regex.Quantifier("0"), - Regex.Quantifier(","), - Regex.Quantifier("5"), - Regex.Quantifier("}"), - Regex.Quantifier("?"), - Regex.Anchor("^")); - } - - [Theory, CombinatorialData] - public async Task TestRegex2(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - // language=regex - var r = @"$(\a\t\u0020)|[^\p{Lu}-a\w\sa-z-[m-p]]+?(?#comment)|(\b\G\z)|(?sub){0,5}?^"; - } - } - """, - testHost, - Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.Grouping("("), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("t"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("u"), - Regex.OtherEscape("0020"), - Regex.Grouping(")"), - Regex.Alternation("|"), - Regex.CharacterClass("["), - Regex.CharacterClass("^"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("p"), - Regex.CharacterClass("{"), - Regex.CharacterClass("Lu"), - Regex.CharacterClass("}"), - Regex.Text("-a"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("w"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("s"), - Regex.Text("a"), - Regex.CharacterClass("-"), - Regex.Text("z"), - Regex.CharacterClass("-"), - Regex.CharacterClass("["), - Regex.Text("m"), - Regex.CharacterClass("-"), - Regex.Text("p"), - Regex.CharacterClass("]"), - Regex.CharacterClass("]"), - Regex.Quantifier("+"), - Regex.Quantifier("?"), - Regex.Comment("(?#comment)"), - Regex.Alternation("|"), - Regex.Grouping("("), - Regex.Anchor("\\"), - Regex.Anchor("b"), - Regex.Anchor("\\"), - Regex.Anchor("G"), - Regex.Anchor("\\"), - Regex.Anchor("z"), - Regex.Grouping(")"), - Regex.Alternation("|"), - Regex.Grouping("("), - Regex.Grouping("?"), - Regex.Grouping("<"), - Regex.Grouping("name"), - Regex.Grouping(">"), - Regex.Text("sub"), - Regex.Grouping(")"), - Regex.Quantifier("{"), - Regex.Quantifier("0"), - Regex.Quantifier(","), - Regex.Quantifier("5"), - Regex.Quantifier("}"), - Regex.Quantifier("?"), - Regex.Anchor("^")); - } - - [Theory, CombinatorialData] - public async Task TestRegex3(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - var r = /* language=regex */@"$(\a\t\u0020\\)|[^\p{Lu}-a\w\sa-z-[m-p]]+?(?#comment)|(\b\G\z)|(?sub){0,5}?^"; - } - } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.Grouping("("), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("t"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("u"), - Regex.OtherEscape("0020"), - Regex.SelfEscapedCharacter("\\"), - Regex.SelfEscapedCharacter("\\"), - Regex.Grouping(")"), - Regex.Alternation("|"), - Regex.CharacterClass("["), - Regex.CharacterClass("^"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("p"), - Regex.CharacterClass("{"), - Regex.CharacterClass("Lu"), - Regex.CharacterClass("}"), - Regex.Text("-a"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("w"), - Regex.CharacterClass("\\"), - Regex.CharacterClass("s"), - Regex.Text("a"), - Regex.CharacterClass("-"), - Regex.Text("z"), - Regex.CharacterClass("-"), - Regex.CharacterClass("["), - Regex.Text("m"), - Regex.CharacterClass("-"), - Regex.Text("p"), - Regex.CharacterClass("]"), - Regex.CharacterClass("]"), - Regex.Quantifier("+"), - Regex.Quantifier("?"), - Regex.Comment("(?#comment)"), - Regex.Alternation("|"), - Regex.Grouping("("), - Regex.Anchor("\\"), - Regex.Anchor("b"), - Regex.Anchor("\\"), - Regex.Anchor("G"), - Regex.Anchor("\\"), - Regex.Anchor("z"), - Regex.Grouping(")"), - Regex.Alternation("|"), - Regex.Grouping("("), - Regex.Grouping("?"), - Regex.Grouping("<"), - Regex.Grouping("name"), - Regex.Grouping(">"), - Regex.Text("sub"), - Regex.Grouping(")"), - Regex.Quantifier("{"), - Regex.Quantifier("0"), - Regex.Quantifier(","), - Regex.Quantifier("5"), - Regex.Quantifier("}"), - Regex.Quantifier("?"), - Regex.Anchor("^")); - } - - [Theory, CombinatorialData] - public async Task TestRegex4(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - var r = /* lang=regex */@"$\a(?#comment)"; - } - } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegex4_utf8_1(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - var r = /* lang=regex */"$\\a(?#comment)"; - } - } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape(@"\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegex4_utf8_2(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - var r = /* lang=regex */@"$\a(?#comment)"u8; - } - } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegex5(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program - { - void Goo() - { - var r = /* lang=regexp */@"$\a(?#comment)"; - } - } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegex6(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang=regexp */@"$\a(?#comment) # not end of line comment"; - } + var r = new Regex(@"$(\a\t\u0020)|[^\p{Lu}-a\w\sa-z-[m-p]]+?(?#comment)|(\b\G\z)|(?sub){0,5}?^"); } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Text(" # not end of line comment")); - } - - [Theory, CombinatorialData] - public async Task TestRegex7(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, + Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Class("Regex"), + Regex.Anchor("$"), + Regex.Grouping("("), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("t"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("u"), + Regex.OtherEscape("0020"), + Regex.Grouping(")"), + Regex.Alternation("|"), + Regex.CharacterClass("["), + Regex.CharacterClass("^"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("p"), + Regex.CharacterClass("{"), + Regex.CharacterClass("Lu"), + Regex.CharacterClass("}"), + Regex.Text("-a"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("w"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("s"), + Regex.Text("a"), + Regex.CharacterClass("-"), + Regex.Text("z"), + Regex.CharacterClass("-"), + Regex.CharacterClass("["), + Regex.Text("m"), + Regex.CharacterClass("-"), + Regex.Text("p"), + Regex.CharacterClass("]"), + Regex.CharacterClass("]"), + Regex.Quantifier("+"), + Regex.Quantifier("?"), + Regex.Comment("(?#comment)"), + Regex.Alternation("|"), + Regex.Grouping("("), + Regex.Anchor("\\"), + Regex.Anchor("b"), + Regex.Anchor("\\"), + Regex.Anchor("G"), + Regex.Anchor("\\"), + Regex.Anchor("z"), + Regex.Grouping(")"), + Regex.Alternation("|"), + Regex.Grouping("("), + Regex.Grouping("?"), + Regex.Grouping("<"), + Regex.Grouping("name"), + Regex.Grouping(">"), + Regex.Text("sub"), + Regex.Grouping(")"), + Regex.Quantifier("{"), + Regex.Quantifier("0"), + Regex.Quantifier(","), + Regex.Quantifier("5"), + Regex.Quantifier("}"), + Regex.Quantifier("?"), + Regex.Anchor("^")); + } + + [Theory, CombinatorialData] + public async Task TestRegex2(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang=regexp,ignorepatternwhitespace */@"$\a(?#comment) # is end of line comment"; - } + // language=regex + var r = @"$(\a\t\u0020)|[^\p{Lu}-a\w\sa-z-[m-p]]+?(?#comment)|(\b\G\z)|(?sub){0,5}?^"; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Comment("# is end of line comment")); - } - - [Theory, CombinatorialData] - public async Task TestRegex8(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, + Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.Grouping("("), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("t"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("u"), + Regex.OtherEscape("0020"), + Regex.Grouping(")"), + Regex.Alternation("|"), + Regex.CharacterClass("["), + Regex.CharacterClass("^"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("p"), + Regex.CharacterClass("{"), + Regex.CharacterClass("Lu"), + Regex.CharacterClass("}"), + Regex.Text("-a"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("w"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("s"), + Regex.Text("a"), + Regex.CharacterClass("-"), + Regex.Text("z"), + Regex.CharacterClass("-"), + Regex.CharacterClass("["), + Regex.Text("m"), + Regex.CharacterClass("-"), + Regex.Text("p"), + Regex.CharacterClass("]"), + Regex.CharacterClass("]"), + Regex.Quantifier("+"), + Regex.Quantifier("?"), + Regex.Comment("(?#comment)"), + Regex.Alternation("|"), + Regex.Grouping("("), + Regex.Anchor("\\"), + Regex.Anchor("b"), + Regex.Anchor("\\"), + Regex.Anchor("G"), + Regex.Anchor("\\"), + Regex.Anchor("z"), + Regex.Grouping(")"), + Regex.Alternation("|"), + Regex.Grouping("("), + Regex.Grouping("?"), + Regex.Grouping("<"), + Regex.Grouping("name"), + Regex.Grouping(">"), + Regex.Text("sub"), + Regex.Grouping(")"), + Regex.Quantifier("{"), + Regex.Quantifier("0"), + Regex.Quantifier(","), + Regex.Quantifier("5"), + Regex.Quantifier("}"), + Regex.Quantifier("?"), + Regex.Anchor("^")); + } + + [Theory, CombinatorialData] + public async Task TestRegex3(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang = regexp , ignorepatternwhitespace */@"$\a(?#comment) # is end of line comment"; - } + var r = /* language=regex */@"$(\a\t\u0020\\)|[^\p{Lu}-a\w\sa-z-[m-p]]+?(?#comment)|(\b\G\z)|(?sub){0,5}?^"; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Comment("# is end of line comment")); - } - - [Theory, CombinatorialData] - public async Task TestRegex9(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.Grouping("("), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("t"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("u"), + Regex.OtherEscape("0020"), + Regex.SelfEscapedCharacter("\\"), + Regex.SelfEscapedCharacter("\\"), + Regex.Grouping(")"), + Regex.Alternation("|"), + Regex.CharacterClass("["), + Regex.CharacterClass("^"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("p"), + Regex.CharacterClass("{"), + Regex.CharacterClass("Lu"), + Regex.CharacterClass("}"), + Regex.Text("-a"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("w"), + Regex.CharacterClass("\\"), + Regex.CharacterClass("s"), + Regex.Text("a"), + Regex.CharacterClass("-"), + Regex.Text("z"), + Regex.CharacterClass("-"), + Regex.CharacterClass("["), + Regex.Text("m"), + Regex.CharacterClass("-"), + Regex.Text("p"), + Regex.CharacterClass("]"), + Regex.CharacterClass("]"), + Regex.Quantifier("+"), + Regex.Quantifier("?"), + Regex.Comment("(?#comment)"), + Regex.Alternation("|"), + Regex.Grouping("("), + Regex.Anchor("\\"), + Regex.Anchor("b"), + Regex.Anchor("\\"), + Regex.Anchor("G"), + Regex.Anchor("\\"), + Regex.Anchor("z"), + Regex.Grouping(")"), + Regex.Alternation("|"), + Regex.Grouping("("), + Regex.Grouping("?"), + Regex.Grouping("<"), + Regex.Grouping("name"), + Regex.Grouping(">"), + Regex.Text("sub"), + Regex.Grouping(")"), + Regex.Quantifier("{"), + Regex.Quantifier("0"), + Regex.Quantifier(","), + Regex.Quantifier("5"), + Regex.Quantifier("}"), + Regex.Quantifier("?"), + Regex.Anchor("^")); + } + + [Theory, CombinatorialData] + public async Task TestRegex4(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = new Regex(@"$\a(?#comment) # is end of line comment", RegexOptions.IgnorePatternWhitespace); - } + var r = /* lang=regex */@"$\a(?#comment)"; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Class("Regex"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Comment("# is end of line comment"), - Enum("RegexOptions"), - EnumMember("IgnorePatternWhitespace")); - } - - [Theory, CombinatorialData] - public async Task TestRegex10(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegex4_utf8_1(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = new Regex(@"$\a(?#comment) # is not end of line comment"); - } + var r = /* lang=regex */"$\\a(?#comment)"; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Class("Regex"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Text(" # is not end of line comment")); - } - - [Theory, CombinatorialData] - public async Task TestRegex10_utf8(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape(@"\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegex4_utf8_2(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - // lang=regex - var r = @"$\a(?#comment) # is not end of line comment"u8; - } + var r = /* lang=regex */@"$\a(?#comment)"u8; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Text(" # is not end of line comment")); - } - - [Theory, CombinatorialData] - public async Task TestRegex11(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegex5(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - // language=regex - private static string myRegex = @"$(\a\t\u0020)"; + var r = /* lang=regexp */@"$\a(?#comment)"; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Regex.Anchor("$"), - Regex.Grouping("("), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("t"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("u"), - Regex.OtherEscape("0020"), - Regex.Grouping(")")); - } - - [Theory, CombinatorialData] - public async Task TestRegexSingleLineRawStringLiteral(TestHost testHost) - { - await TestAsync( - """" - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegex6(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang=regex */ """$\a(?#comment)"""; - } + var r = /* lang=regexp */@"$\a(?#comment) # not end of line comment"; } - """", - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexSingleLineRawStringLiteral_utf8(TestHost testHost) - { - await TestAsync( - """" - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Text(" # not end of line comment")); + } + + [Theory, CombinatorialData] + public async Task TestRegex7(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang=regex */ """$\a(?#comment)"""u8; - } + var r = /* lang=regexp,ignorepatternwhitespace */@"$\a(?#comment) # is end of line comment"; } - """", - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexMultiLineRawStringLiteral(TestHost testHost) - { - await TestAsync( - """" - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Comment("# is end of line comment")); + } + + [Theory, CombinatorialData] + public async Task TestRegex8(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang=regex */ """ - $\a(?#comment) - """; - } + var r = /* lang = regexp , ignorepatternwhitespace */@"$\a(?#comment) # is end of line comment"; } - """", - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexMultiLineRawStringLiteral_utf8(TestHost testHost) - { - await TestAsync( - """" - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Comment("# is end of line comment")); + } + + [Theory, CombinatorialData] + public async Task TestRegex9(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = /* lang=regex */ """ - $\a(?#comment) - """u8; - } + var r = new Regex(@"$\a(?#comment) # is end of line comment", RegexOptions.IgnorePatternWhitespace); } - """", - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/47079")] - [CombinatorialData] - public async Task TestRegexWithSpecialCSharpCharLiterals(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Class("Regex"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Comment("# is end of line comment"), + Enum("RegexOptions"), + EnumMember("IgnorePatternWhitespace")); + } + + [Theory, CombinatorialData] + public async Task TestRegex10(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - // the double-quote inside the string should not affect this being classified as a regex. - private Regex myRegex = new Regex(@"^ "" $"; + var r = new Regex(@"$\a(?#comment) # is not end of line comment"); } - """, - testHost, - Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Class("Regex"), - Class("Regex"), - Regex.Anchor("^"), - Regex.Text(@" """" "), - Regex.Anchor("$")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/47079")] - [CombinatorialData] - public async Task TestRegexWithSpecialCSharpCharLiterals_utf8(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Class("Regex"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Text(" # is not end of line comment")); + } + + [Theory, CombinatorialData] + public async Task TestRegex10_utf8(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { // lang=regex - private string myRegex = @"^ "" $"u8; + var r = @"$\a(?#comment) # is not end of line comment"u8; } - """, - testHost, - Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Regex.Anchor("^"), - Regex.Text(@" """" "), - Regex.Anchor("$")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Field(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program - { - [StringSyntax(StringSyntaxAttribute.Regex)] - private string field; + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Text(" # is not end of line comment")); + } - void Goo() - { - [|this.field = @"$\a(?#comment)";|] - } - } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Field("field"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Field2(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + [Theory, CombinatorialData] + public async Task TestRegex11(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + // language=regex + private static string myRegex = @"$(\a\t\u0020)"; + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Regex.Anchor("$"), + Regex.Grouping("("), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("t"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("u"), + Regex.OtherEscape("0020"), + Regex.Grouping(")")); + } + + [Theory, CombinatorialData] + public async Task TestRegexSingleLineRawStringLiteral(TestHost testHost) + { + await TestAsync( + """" + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - [StringSyntax(StringSyntaxAttribute.Regex)] - [|private string field = @"$\a(?#comment)";|] + var r = /* lang=regex */ """$\a(?#comment)"""; } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Property(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program - { - [StringSyntax(StringSyntaxAttribute.Regex)] - private string Prop { get; set; } + } + """", + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } - void Goo() - { - [|this.Prop = @"$\a(?#comment)";|] - } - } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Property("Prop"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Property2(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + [Theory, CombinatorialData] + public async Task TestRegexSingleLineRawStringLiteral_utf8(TestHost testHost) + { + await TestAsync( + """" + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - [StringSyntax(StringSyntaxAttribute.Regex)] - [|private string Prop { get; set; } = @"$\a(?#comment)";|] + var r = /* lang=regex */ """$\a(?#comment)"""u8; } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Argument(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + } + """", + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexMultiLineRawStringLiteral(TestHost testHost) + { + await TestAsync( + """" + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] string p) - { - } - - void Goo() - { - [|M(@"$\a(?#comment)");|] - } + var r = /* lang=regex */ """ + $\a(?#comment) + """; } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsArgument(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + } + """", + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexMultiLineRawStringLiteral_utf8(TestHost testHost) + { + await TestAsync( + """" + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] params string[] p) - { - } - - void Goo() - { - [|M(@"$\a(?#comment)");|] - } + var r = /* lang=regex */ """ + $\a(?#comment) + """u8; } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/64549")] - [CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsArgument2(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + } + """", + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/47079")] + [CombinatorialData] + public async Task TestRegexWithSpecialCSharpCharLiterals(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + // the double-quote inside the string should not affect this being classified as a regex. + private Regex myRegex = new Regex(@"^ "" $"; + } + """, + testHost, + Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Class("Regex"), + Class("Regex"), + Regex.Anchor("^"), + Regex.Text(@" """" "), + Regex.Anchor("$")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/47079")] + [CombinatorialData] + public async Task TestRegexWithSpecialCSharpCharLiterals_utf8(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + // lang=regex + private string myRegex = @"^ "" $"u8; + } + """, + testHost, + Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Regex.Anchor("^"), + Regex.Text(@" """" "), + Regex.Anchor("$")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Field(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + [StringSyntax(StringSyntaxAttribute.Regex)] + private string field; + + void Goo() { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] params string[] p) - { - } - - void Goo() - { - [|M(@"$\a(?#comment)", @"$\a(?#comment)");|] - } + [|this.field = @"$\a(?#comment)";|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ArrayArgument(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Field("field"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Field2(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + [StringSyntax(StringSyntaxAttribute.Regex)] + [|private string field = @"$\a(?#comment)";|] + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Property(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + [StringSyntax(StringSyntaxAttribute.Regex)] + private string Prop { get; set; } + + void Goo() { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] string[] p) - { - } - - void Goo() - { - [|M(new string[] { @"$\a(?#comment)" });|] - } + [|this.Prop = @"$\a(?#comment)";|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitArrayArgument(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Property("Prop"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Property2(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + [StringSyntax(StringSyntaxAttribute.Regex)] + [|private string Prop { get; set; } = @"$\a(?#comment)";|] + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Argument(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] string p) { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] string[] p) - { - } - - void Goo() - { - [|M(new[] { @"$\a(?#comment)" });|] - } } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_CollectionArgument(TestHost testHost) - { - await TestAsync( - """ - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + + void Goo() { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] List p) - { - } - - void Goo() - { - [|M(new List { @"$\a(?#comment)" });|] - } + [|M(@"$\a(?#comment)");|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Class("List"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitCollectionArgument(TestHost testHost) - { - await TestAsync( - """ - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsArgument(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] params string[] p) { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] List p) - { - } - - void Goo() - { - [|M(new() { @"$\a(?#comment)" });|] - } } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Argument_Options(TestHost testHost) - { - await TestAsync( - """ - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - class Program + + void Goo() { - private void M([StringSyntax(StringSyntaxAttribute.Regex)] string p, RegexOptions options) - { - } - - void Goo() - { - [|M(@"$\a(?#comment) # is end of line comment", RegexOptions.IgnorePatternWhitespace);|] - } + [|M(@"$\a(?#comment)");|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Method("M"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)"), - Regex.Comment("# is end of line comment"), - Enum("RegexOptions"), - EnumMember("IgnorePatternWhitespace")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_Attribute(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - [AttributeUsage(AttributeTargets.Field)] - class RegexTestAttribute : Attribute + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/64549")] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsArgument2(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] params string[] p) { - public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string value) { } } - class Program + void Goo() { - [|[RegexTest(@"$\a(?#comment)")]|] - private string field; + [|M(@"$\a(?#comment)", @"$\a(?#comment)");|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Class("RegexTest"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/61947")] - public async Task TestRegexOnApiWithStringSyntaxAttribute_AttributeField(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - [AttributeUsage(AttributeTargets.Field)] - class RegexTestAttribute : Attribute - { - public RegexTestAttribute() { } + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } - [StringSyntax(StringSyntaxAttribute.Regex)] - public string value; + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ArrayArgument(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] string[] p) + { } - class Program + void Goo() { - [|[RegexTest(value = @"$\a(?#comment)")]|] - private string field; + [|M(new string[] { @"$\a(?#comment)" });|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Class("RegexTest"), - Field("value"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/61947")] - public async Task TestRegexOnApiWithStringSyntaxAttribute_AttributeProperty(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - [AttributeUsage(AttributeTargets.Field)] - class RegexTestAttribute : Attribute - { - public RegexTestAttribute() { } + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } - [StringSyntax(StringSyntaxAttribute.Regex)] - public string value { get; set; } + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitArrayArgument(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] string[] p) + { } - class Program + void Goo() { - [|[RegexTest(value = @"$\a(?#comment)")]|] - private string field; + [|M(new[] { @"$\a(?#comment)" });|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Class("RegexTest"), - Property("value"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsAttribute(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - [AttributeUsage(AttributeTargets.Field)] - class RegexTestAttribute : Attribute + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_CollectionArgument(TestHost testHost) + { + await TestAsync( + """ + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] List p) { - public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] params string[] value) { } } - class Program + void Goo() { - [|[RegexTest(@"$\a(?#comment)")]|] - private string field; + [|M(new List { @"$\a(?#comment)" });|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Class("RegexTest"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ArrayAttribute(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - [AttributeUsage(AttributeTargets.Field)] - class RegexTestAttribute : Attribute + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Class("List"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitCollectionArgument(TestHost testHost) + { + await TestAsync( + """ + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] List p) { - public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string[] value) { } } - class Program + void Goo() { - [|[RegexTest(new string[] { @"$\a(?#comment)" })]|] - private string field; + [|M(new() { @"$\a(?#comment)" });|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Class("RegexTest"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitArrayAttribute(TestHost testHost) - { - await TestAsync( - """ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Text.RegularExpressions; - - [AttributeUsage(AttributeTargets.Field)] - class RegexTestAttribute : Attribute + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Argument_Options(TestHost testHost) + { + await TestAsync( + """ + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + class Program + { + private void M([StringSyntax(StringSyntaxAttribute.Regex)] string p, RegexOptions options) { - public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string[] value) { } } - class Program + void Goo() { - [|[RegexTest(new[] { @"$\a(?#comment)" })]|] - private string field; + [|M(@"$\a(?#comment) # is end of line comment", RegexOptions.IgnorePatternWhitespace);|] } - """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, - testHost, - Class("RegexTest"), - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestIncompleteRegexLeadingToStringInsideSkippedTokensInsideADirective(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Method("M"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)"), + Regex.Comment("# is end of line comment"), + Enum("RegexOptions"), + EnumMember("IgnorePatternWhitespace")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_Attribute(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Field)] + class RegexTestAttribute : Attribute + { + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string value) { } + } + + class Program + { + [|[RegexTest(@"$\a(?#comment)")]|] + private string field; + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Class("RegexTest"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/61947")] + public async Task TestRegexOnApiWithStringSyntaxAttribute_AttributeField(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Field)] + class RegexTestAttribute : Attribute + { + public RegexTestAttribute() { } + + [StringSyntax(StringSyntaxAttribute.Regex)] + public string value; + } + + class Program + { + [|[RegexTest(value = @"$\a(?#comment)")]|] + private string field; + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Class("RegexTest"), + Field("value"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/61947")] + public async Task TestRegexOnApiWithStringSyntaxAttribute_AttributeProperty(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Field)] + class RegexTestAttribute : Attribute + { + public RegexTestAttribute() { } + + [StringSyntax(StringSyntaxAttribute.Regex)] + public string value { get; set; } + } + + class Program + { + [|[RegexTest(value = @"$\a(?#comment)")]|] + private string field; + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Class("RegexTest"), + Property("value"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsAttribute(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Field)] + class RegexTestAttribute : Attribute + { + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] params string[] value) { } + } + + class Program + { + [|[RegexTest(@"$\a(?#comment)")]|] + private string field; + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Class("RegexTest"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ArrayAttribute(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Field)] + class RegexTestAttribute : Attribute + { + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string[] value) { } + } + + class Program + { + [|[RegexTest(new string[] { @"$\a(?#comment)" })]|] + private string field; + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Class("RegexTest"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitArrayAttribute(TestHost testHost) + { + await TestAsync( + """ + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Field)] + class RegexTestAttribute : Attribute + { + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string[] value) { } + } + + class Program + { + [|[RegexTest(new[] { @"$\a(?#comment)" })]|] + private string field; + } + """ + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, + testHost, + Class("RegexTest"), + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestIncompleteRegexLeadingToStringInsideSkippedTokensInsideADirective(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void M() { - void M() - { - // not terminating this string caused us to eat up to the quote on the next line. - // we then treated #comment as a directive with a lot of skipped tokens on it, including - // a skipped token for "; - // - // Because it's a comment on a directive, special lexing rules apply (i.e. no escape - // characters are supposed, and we want our system to bail there and not try to validate - // it. - var r = new Regex(@"$; - var s = /* language=regex */ @"(?#comment)|(\b\G\z)|(?sub){0,5}?^"; - } + // not terminating this string caused us to eat up to the quote on the next line. + // we then treated #comment as a directive with a lot of skipped tokens on it, including + // a skipped token for "; + // + // Because it's a comment on a directive, special lexing rules apply (i.e. no escape + // characters are supposed, and we want our system to bail there and not try to validate + // it. + var r = new Regex(@"$; + var s = /* language=regex */ @"(?#comment)|(\b\G\z)|(?sub){0,5}?^"; } - """, - testHost, Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var"), - Class("Regex")); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/61982")] - public async Task TestRegexAmbiguity1(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + } + """, + testHost, Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var"), + Class("Regex")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/61982")] + public async Task TestRegexAmbiguity1(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = Regex.Match("", [|@"$\a(?#comment)"|] - """, - testHost, - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/61982")] - public async Task TestRegexAmbiguity2(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + var r = Regex.Match("", [|@"$\a(?#comment)"|] + """, + testHost, + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/61982")] + public async Task TestRegexAmbiguity2(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - var r = Regex.Match("", [|@"$\a(?#comment)"|], - """, - testHost, - Regex.Anchor("$"), - Regex.OtherEscape("\\"), - Regex.OtherEscape("a"), - Regex.Comment("(?#comment)")); - } - - [Theory, CombinatorialData] - public async Task TestRegexNotOnBinaryExpression(TestHost testHost) - { - await TestAsync( - """ - using System.Text.RegularExpressions; - - class Program + var r = Regex.Match("", [|@"$\a(?#comment)"|], + """, + testHost, + Regex.Anchor("$"), + Regex.OtherEscape("\\"), + Regex.OtherEscape("a"), + Regex.Comment("(?#comment)")); + } + + [Theory, CombinatorialData] + public async Task TestRegexNotOnBinaryExpression(TestHost testHost) + { + await TestAsync( + """ + using System.Text.RegularExpressions; + + class Program + { + void Goo() { - void Goo() - { - // language=regex - var r = @"[a-" + @"z]"; - } + // language=regex + var r = @"[a-" + @"z]"; } - """, - testHost, - Namespace("System"), - Namespace("Text"), - Namespace("RegularExpressions"), - Keyword("var")); - } + } + """, + testHost, + Namespace("System"), + Namespace("Text"), + Namespace("RegularExpressions"), + Keyword("var")); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_StringEscapes.cs b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_StringEscapes.cs index 3ffcabb7cec40..2be1b8bfd6319 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_StringEscapes.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests_StringEscapes.cs @@ -8,424 +8,423 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +public partial class SemanticClassifierTests : AbstractCSharpClassifierTests { - public partial class SemanticClassifierTests : AbstractCSharpClassifierTests - { - [Theory, CombinatorialData] - public async Task TestStringEscape1(TestHost testHost) - { - await TestInMethodAsync(@"var goo = ""goo\r\nbar"";", - testHost, - Keyword("var"), - Escape(@"\r"), - Escape(@"\n")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape1_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = ""goo\r\nbar""u8;", - testHost, - Keyword("var"), - Escape(@"\r"), - Escape(@"\n")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape2(TestHost testHost) - { - await TestInMethodAsync(@"var goo = @""goo\r\nbar"";", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape2_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = @""goo\r\nbar""u8;", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape3(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo{{1}}bar"";", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape3_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo{{1}}bar""u8;", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape4(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""goo{{1}}bar"";", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape4_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""goo{{1}}bar""u8;", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape5(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo\r{{1}}\nbar"";", - testHost, - Keyword("var"), - Escape(@"\r"), - Escape(@"{{"), - Escape(@"}}"), - Escape(@"\n")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape5_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo\r{{1}}\nbar""u8;", - testHost, - Keyword("var"), - Escape(@"\r"), - Escape(@"{{"), - Escape(@"}}"), - Escape(@"\n")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape6(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""goo\r{{1}}\nbar"";", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape6_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""goo\r{{1}}\nbar""u8;", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape7(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo\r{1}\nbar"";", - testHost, - Keyword("var"), - Escape(@"\r"), - Escape(@"\n")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape7_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $""goo\r{1}\nbar""u8;", - testHost, - Keyword("var"), - Escape(@"\r"), - Escape(@"\n")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""{{goo{1}bar}}"";", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape8_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""{{goo{1}bar}}""u8;", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape9(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""{{{12:X}}}"";", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape9_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""{{{12:X}}}""u8;", - testHost, - Keyword("var"), - Escape(@"{{"), - Escape(@"}}")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral1(TestHost testHost) - { - await TestInMethodAsync(@"var goo = """"""goo\r\nbar"""""";", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral1_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = """"""goo\r\nbar""""""u8;", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral2(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = """ - goo\r\nbar - """; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral2_utf8(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = """ - goo\r\nbar - """u8; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral3(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = $""" - goo\r\nbar - """; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral3_utf8(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = $""" - goo\r\nbar - """u8; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral4(TestHost testHost) - { - await TestInMethodAsync(@"var goo = """"""\"""""";", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral4_utf8(TestHost testHost) - { - await TestInMethodAsync(@"var goo = """"""\""""""u8;", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral5(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = """ - \ - """; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral5_utf8(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = """ - \ - """u8; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral6(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = $""" - \ - """; - """", - testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestNotStringEscapeInRawLiteral6_utf8(TestHost testHost) - { - await TestInMethodAsync("""" - var goo = $""" - \ - """u8; - """", - testHost, - Keyword("var")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] - [CombinatorialData] - public async Task TestCharEscape1(TestHost testHost) - { - await TestInMethodAsync(@"var goo = '\n';", - testHost, - Keyword("var"), - Escape(@"\n")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] - [CombinatorialData] - public async Task TestCharEscape2(TestHost testHost) - { - await TestInMethodAsync(@"var goo = '\\';", - testHost, - Keyword("var"), - Escape(@"\\")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] - [CombinatorialData] - public async Task TestCharEscape3(TestHost testHost) - { - await TestInMethodAsync(@"var goo = '\'';", - testHost, - Keyword("var"), - Escape(@"\'")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] - [CombinatorialData] - public async Task TestCharEscape5(TestHost testHost) - { - await TestInMethodAsync(@"var goo = '""';", - testHost, - Keyword("var")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] - [CombinatorialData] - public async Task TestCharEscape4(TestHost testHost) - { - await TestInMethodAsync(@"var goo = '\u000a';", - testHost, - Keyword("var"), - Escape(@"\u000a")); - } - - [Theory, CombinatorialData] - public async Task TestEscapeFourBytesCharacter(TestHost testHost) - { - await TestAsync(""" - class C - { - void M() - { - var x = "𠀀𠀁𠣶𤆐𥽠𪛕"; - } - } - """, testHost, - Keyword("var")); - } - - [Theory, CombinatorialData] - public async Task TestEscapeCharacter(TestHost testHost) - { - await TestAsync(""""" - class C - { - string x1 = "\xabcd"; - string x2 = "\uabcd"; - string x3 = "\U00009F99"; - string x4 = "\'"; - string x5 = "\""; - string x6 = "\\"; - string x7 = "\0"; - string x8 = "\a"; - string x9 = "\b"; - string x10 = "\f"; - string x11 = "\n"; - string x12 = "\r"; - string x13 = "\t"; - string x14 = "\v"; - string x15 = @""""; - } - """"", testHost, - Escape("\\xabcd"), - Escape("\\uabcd"), - Escape("\\U00009F99"), - Escape("\\\'"), - Escape(""" - \" - """), - Escape("\\\\"), - Escape("\\0"), - Escape("\\a"), - Escape("\\b"), - Escape("\\f"), - Escape("\\n"), - Escape("\\r"), - Escape("\\t"), - Escape("\\v"), - Escape(""" - "" - """)); - } + [Theory, CombinatorialData] + public async Task TestStringEscape1(TestHost testHost) + { + await TestInMethodAsync(@"var goo = ""goo\r\nbar"";", + testHost, + Keyword("var"), + Escape(@"\r"), + Escape(@"\n")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape1_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = ""goo\r\nbar""u8;", + testHost, + Keyword("var"), + Escape(@"\r"), + Escape(@"\n")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape2(TestHost testHost) + { + await TestInMethodAsync(@"var goo = @""goo\r\nbar"";", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape2_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = @""goo\r\nbar""u8;", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape3(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo{{1}}bar"";", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape3_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo{{1}}bar""u8;", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape4(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""goo{{1}}bar"";", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape4_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""goo{{1}}bar""u8;", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape5(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo\r{{1}}\nbar"";", + testHost, + Keyword("var"), + Escape(@"\r"), + Escape(@"{{"), + Escape(@"}}"), + Escape(@"\n")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape5_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo\r{{1}}\nbar""u8;", + testHost, + Keyword("var"), + Escape(@"\r"), + Escape(@"{{"), + Escape(@"}}"), + Escape(@"\n")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape6(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""goo\r{{1}}\nbar"";", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape6_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""goo\r{{1}}\nbar""u8;", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape7(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo\r{1}\nbar"";", + testHost, + Keyword("var"), + Escape(@"\r"), + Escape(@"\n")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape7_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $""goo\r{1}\nbar""u8;", + testHost, + Keyword("var"), + Escape(@"\r"), + Escape(@"\n")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""{{goo{1}bar}}"";", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape8_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""{{goo{1}bar}}""u8;", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape9(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""{{{12:X}}}"";", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape9_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""{{{12:X}}}""u8;", + testHost, + Keyword("var"), + Escape(@"{{"), + Escape(@"}}")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral1(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """"""goo\r\nbar"""""";", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral1_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """"""goo\r\nbar""""""u8;", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral2(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = """ + goo\r\nbar + """; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral2_utf8(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = """ + goo\r\nbar + """u8; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral3(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = $""" + goo\r\nbar + """; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral3_utf8(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = $""" + goo\r\nbar + """u8; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral4(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """"""\"""""";", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral4_utf8(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """"""\""""""u8;", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral5(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = """ + \ + """; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral5_utf8(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = """ + \ + """u8; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral6(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = $""" + \ + """; + """", + testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral6_utf8(TestHost testHost) + { + await TestInMethodAsync("""" + var goo = $""" + \ + """u8; + """", + testHost, + Keyword("var")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] + [CombinatorialData] + public async Task TestCharEscape1(TestHost testHost) + { + await TestInMethodAsync(@"var goo = '\n';", + testHost, + Keyword("var"), + Escape(@"\n")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] + [CombinatorialData] + public async Task TestCharEscape2(TestHost testHost) + { + await TestInMethodAsync(@"var goo = '\\';", + testHost, + Keyword("var"), + Escape(@"\\")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] + [CombinatorialData] + public async Task TestCharEscape3(TestHost testHost) + { + await TestInMethodAsync(@"var goo = '\'';", + testHost, + Keyword("var"), + Escape(@"\'")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] + [CombinatorialData] + public async Task TestCharEscape5(TestHost testHost) + { + await TestInMethodAsync(@"var goo = '""';", + testHost, + Keyword("var")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/31200")] + [CombinatorialData] + public async Task TestCharEscape4(TestHost testHost) + { + await TestInMethodAsync(@"var goo = '\u000a';", + testHost, + Keyword("var"), + Escape(@"\u000a")); + } + + [Theory, CombinatorialData] + public async Task TestEscapeFourBytesCharacter(TestHost testHost) + { + await TestAsync(""" + class C + { + void M() + { + var x = "𠀀𠀁𠣶𤆐𥽠𪛕"; + } + } + """, testHost, + Keyword("var")); + } + + [Theory, CombinatorialData] + public async Task TestEscapeCharacter(TestHost testHost) + { + await TestAsync(""""" + class C + { + string x1 = "\xabcd"; + string x2 = "\uabcd"; + string x3 = "\U00009F99"; + string x4 = "\'"; + string x5 = "\""; + string x6 = "\\"; + string x7 = "\0"; + string x8 = "\a"; + string x9 = "\b"; + string x10 = "\f"; + string x11 = "\n"; + string x12 = "\r"; + string x13 = "\t"; + string x14 = "\v"; + string x15 = @""""; + } + """"", testHost, + Escape("\\xabcd"), + Escape("\\uabcd"), + Escape("\\U00009F99"), + Escape("\\\'"), + Escape(""" + \" + """), + Escape("\\\\"), + Escape("\\0"), + Escape("\\a"), + Escape("\\b"), + Escape("\\f"), + Escape("\\n"), + Escape("\\r"), + Escape("\\t"), + Escape("\\v"), + Escape(""" + "" + """)); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs index 6d9aa6c32b773..9176c5048ea32 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests.cs @@ -14,134 +14,134 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +public partial class SyntacticClassifierTests : AbstractCSharpClassifierTests { - public partial class SyntacticClassifierTests : AbstractCSharpClassifierTests + protected override async Task> GetClassificationSpansAsync(string code, ImmutableArray spans, ParseOptions? options, TestHost testHost) { - protected override async Task> GetClassificationSpansAsync(string code, ImmutableArray spans, ParseOptions? options, TestHost testHost) - { - using var workspace = CreateWorkspace(code, options, testHost); - var document = workspace.CurrentSolution.Projects.First().Documents.First(); + using var workspace = CreateWorkspace(code, options, testHost); + var document = workspace.CurrentSolution.Projects.First().Documents.First(); - return await GetSyntacticClassificationsAsync(document, spans); - } + return await GetSyntacticClassificationsAsync(document, spans); + } - [Theory, CombinatorialData] - public async Task VarAtTypeMemberLevel(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task VarAtTypeMemberLevel(TestHost testHost) + { + await TestAsync( @"class C { var goo }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Identifier("var"), - Field("goo"), - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Identifier("var"), + Field("goo"), + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestNamespace(TestHost testHost) + { + await TestAsync( @"namespace N { }", - testHost, - Keyword("namespace"), - Namespace("N"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("N"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestFileScopedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestFileScopedNamespace(TestHost testHost) + { + await TestAsync( @"namespace N; ", - testHost, - Keyword("namespace"), - Namespace("N"), - Punctuation.Semicolon); - } + testHost, + Keyword("namespace"), + Namespace("N"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task VarAsLocalVariableType(TestHost testHost) - { - await TestInMethodAsync("var goo = 42", - testHost, - Keyword("var"), - Local("goo"), - Operators.Equals, - Number("42")); - } + [Theory, CombinatorialData] + public async Task VarAsLocalVariableType(TestHost testHost) + { + await TestInMethodAsync("var goo = 42", + testHost, + Keyword("var"), + Local("goo"), + Operators.Equals, + Number("42")); + } - [Theory, CombinatorialData] - public async Task VarOptimisticallyColored(TestHost testHost) - { - await TestInMethodAsync("var", - testHost, - Keyword("var")); - } + [Theory, CombinatorialData] + public async Task VarOptimisticallyColored(TestHost testHost) + { + await TestInMethodAsync("var", + testHost, + Keyword("var")); + } - [Theory, CombinatorialData] - public async Task VarNotColoredInClass(TestHost testHost) - { - await TestInClassAsync("var", - testHost, - Identifier("var")); - } + [Theory, CombinatorialData] + public async Task VarNotColoredInClass(TestHost testHost) + { + await TestInClassAsync("var", + testHost, + Identifier("var")); + } - [Theory, CombinatorialData] - public async Task VarInsideLocalAndExpressions(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task VarInsideLocalAndExpressions(TestHost testHost) + { + await TestInMethodAsync( @"var var = (var)var as var;", - testHost, - Keyword("var"), - Local("var"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("var"), - Punctuation.CloseParen, - Identifier("var"), - Keyword("as"), - Identifier("var"), - Punctuation.Semicolon); - } + testHost, + Keyword("var"), + Local("var"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("var"), + Punctuation.CloseParen, + Identifier("var"), + Keyword("as"), + Identifier("var"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task VarAsMethodParameter(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task VarAsMethodParameter(TestHost testHost) + { + await TestAsync( @"class C { void M(var v) { } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Identifier("var"), - Parameter("v"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Identifier("var"), + Parameter("v"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task YieldYield(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task YieldYield(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class yield @@ -152,45 +152,45 @@ IEnumerable M() yield return yield; } }", - testHost, - Keyword("using"), - Identifier("System"), - Operators.Dot, - Identifier("Collections"), - Operators.Dot, - Identifier("Generic"), - Punctuation.Semicolon, - Keyword("class"), - Class("yield"), - Punctuation.OpenCurly, - Identifier("IEnumerable"), - Punctuation.OpenAngle, - Identifier("yield"), - Punctuation.CloseAngle, - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Identifier("yield"), - Local("yield"), - Operators.Equals, - Keyword("new"), - Identifier("yield"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - ControlKeyword("yield"), - ControlKeyword("return"), - Identifier("yield"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("using"), + Identifier("System"), + Operators.Dot, + Identifier("Collections"), + Operators.Dot, + Identifier("Generic"), + Punctuation.Semicolon, + Keyword("class"), + Class("yield"), + Punctuation.OpenCurly, + Identifier("IEnumerable"), + Punctuation.OpenAngle, + Identifier("yield"), + Punctuation.CloseAngle, + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Identifier("yield"), + Local("yield"), + Operators.Equals, + Keyword("new"), + Identifier("yield"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + ControlKeyword("yield"), + ControlKeyword("return"), + Identifier("yield"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task YieldYieldAsSpans(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task YieldYieldAsSpans(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class yield @@ -201,112 +201,112 @@ IEnumerable M() [|yield return yield;|] } }", - testHost, - Identifier("yield"), - Local("yield"), - Operators.Equals, - Keyword("new"), - Identifier("yield"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - ControlKeyword("yield"), - ControlKeyword("return"), - Identifier("yield"), - Punctuation.Semicolon); - } + testHost, + Identifier("yield"), + Local("yield"), + Operators.Equals, + Keyword("new"), + Identifier("yield"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + ControlKeyword("yield"), + ControlKeyword("return"), + Identifier("yield"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task YieldReturn(TestHost testHost) - { - await TestInMethodAsync("yield return 42", - testHost, - ControlKeyword("yield"), - ControlKeyword("return"), - Number("42")); - } + [Theory, CombinatorialData] + public async Task YieldReturn(TestHost testHost) + { + await TestInMethodAsync("yield return 42", + testHost, + ControlKeyword("yield"), + ControlKeyword("return"), + Number("42")); + } - [Theory, CombinatorialData] - public async Task YieldFixed(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task YieldFixed(TestHost testHost) + { + await TestInMethodAsync( @"yield return this.items[0]; yield break; fixed (int* i = 0) { }", - testHost, - ControlKeyword("yield"), - ControlKeyword("return"), - Keyword("this"), - Operators.Dot, - Identifier("items"), - Punctuation.OpenBracket, - Number("0"), - Punctuation.CloseBracket, - Punctuation.Semicolon, - ControlKeyword("yield"), - ControlKeyword("break"), - Punctuation.Semicolon, - Keyword("fixed"), - Punctuation.OpenParen, - Keyword("int"), - Operators.Asterisk, - Local("i"), - Operators.Equals, - Number("0"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + ControlKeyword("yield"), + ControlKeyword("return"), + Keyword("this"), + Operators.Dot, + Identifier("items"), + Punctuation.OpenBracket, + Number("0"), + Punctuation.CloseBracket, + Punctuation.Semicolon, + ControlKeyword("yield"), + ControlKeyword("break"), + Punctuation.Semicolon, + Keyword("fixed"), + Punctuation.OpenParen, + Keyword("int"), + Operators.Asterisk, + Local("i"), + Operators.Equals, + Number("0"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task PartialClass(TestHost testHost) - { - await TestAsync("public partial class Goo", - testHost, - Keyword("public"), - Keyword("partial"), - Keyword("class"), - Class("Goo")); - } + [Theory, CombinatorialData] + public async Task PartialClass(TestHost testHost) + { + await TestAsync("public partial class Goo", + testHost, + Keyword("public"), + Keyword("partial"), + Keyword("class"), + Class("Goo")); + } - [Theory, CombinatorialData] - public async Task PartialMethod(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task PartialMethod(TestHost testHost) + { + await TestInClassAsync( @"public partial void M() { }", - testHost, - Keyword("public"), - Keyword("partial"), - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("public"), + Keyword("partial"), + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - /// - /// Partial is only valid in a type declaration - /// - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536313")] - public async Task PartialAsLocalVariableType(TestHost testHost) - { - await TestInMethodAsync( + /// + /// Partial is only valid in a type declaration + /// + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536313")] + public async Task PartialAsLocalVariableType(TestHost testHost) + { + await TestInMethodAsync( @"partial p1 = 42;", - testHost, - Identifier("partial"), - Local("p1"), - Operators.Equals, - Number("42"), - Punctuation.Semicolon); - } + testHost, + Identifier("partial"), + Local("p1"), + Operators.Equals, + Number("42"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task PartialClassStructInterface(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task PartialClassStructInterface(TestHost testHost) + { + await TestAsync( @"partial class T1 { } @@ -318,393 +318,393 @@ partial struct T2 partial interface T3 { }", - testHost, - Keyword("partial"), - Keyword("class"), - Class("T1"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("partial"), - Keyword("struct"), - Struct("T2"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("partial"), - Keyword("interface"), - Interface("T3"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - private static readonly string[] s_contextualKeywordsOnlyValidInMethods = ["where", "from", "group", "join", "select", "into", "let", "by", "orderby", "on", "equals", "ascending", "descending"]; + testHost, + Keyword("partial"), + Keyword("class"), + Class("T1"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("partial"), + Keyword("struct"), + Struct("T2"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("partial"), + Keyword("interface"), + Interface("T3"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - /// - /// Check for items only valid within a method declaration - /// - [Theory, CombinatorialData] - public async Task ContextualKeywordsOnlyValidInMethods(TestHost testHost) - { - foreach (var kw in s_contextualKeywordsOnlyValidInMethods) - { - await TestInNamespaceAsync(kw + " goo", - testHost, - Identifier(kw), - Field("goo")); - } - } + private static readonly string[] s_contextualKeywordsOnlyValidInMethods = ["where", "from", "group", "join", "select", "into", "let", "by", "orderby", "on", "equals", "ascending", "descending"]; - [Theory, CombinatorialData] - public async Task VerbatimStringLiterals1(TestHost testHost) + /// + /// Check for items only valid within a method declaration + /// + [Theory, CombinatorialData] + public async Task ContextualKeywordsOnlyValidInMethods(TestHost testHost) + { + foreach (var kw in s_contextualKeywordsOnlyValidInMethods) { - await TestInMethodAsync(@"@""goo""", + await TestInNamespaceAsync(kw + " goo", testHost, - Verbatim(@"@""goo""")); + Identifier(kw), + Field("goo")); } + } - [Theory, CombinatorialData] - public async Task VerbatimStringLiteralsUtf8_01(TestHost testHost) - { - await TestInMethodAsync(@"@""goo""u8", - testHost, - Verbatim(@"@""goo"""), - Keyword("u8")); - } + [Theory, CombinatorialData] + public async Task VerbatimStringLiterals1(TestHost testHost) + { + await TestInMethodAsync(@"@""goo""", + testHost, + Verbatim(@"@""goo""")); + } - [Theory, CombinatorialData] - public async Task VerbatimStringLiteralsUtf8_02(TestHost testHost) - { - await TestInMethodAsync(@"@""goo""U8", - testHost, - Verbatim(@"@""goo"""), - Keyword("U8")); - } + [Theory, CombinatorialData] + public async Task VerbatimStringLiteralsUtf8_01(TestHost testHost) + { + await TestInMethodAsync(@"@""goo""u8", + testHost, + Verbatim(@"@""goo"""), + Keyword("u8")); + } - /// - /// Should show up as soon as we get the @\" typed out - /// - [Theory, CombinatorialData] - public async Task VerbatimStringLiterals2(TestHost testHost) - { - await TestAsync(@"@""", - testHost, - Verbatim(@"@""")); - } + [Theory, CombinatorialData] + public async Task VerbatimStringLiteralsUtf8_02(TestHost testHost) + { + await TestInMethodAsync(@"@""goo""U8", + testHost, + Verbatim(@"@""goo"""), + Keyword("U8")); + } - /// - /// Parser does not currently support strings of this type - /// - [Theory, CombinatorialData] - public async Task VerbatimStringLiterals3(TestHost testHost) - { - await TestAsync(@"goo @""", - testHost, - Identifier("goo"), - Verbatim(@"@""")); - } + /// + /// Should show up as soon as we get the @\" typed out + /// + [Theory, CombinatorialData] + public async Task VerbatimStringLiterals2(TestHost testHost) + { + await TestAsync(@"@""", + testHost, + Verbatim(@"@""")); + } - /// - /// Uncompleted ones should span new lines - /// - [Theory, CombinatorialData] - public async Task VerbatimStringLiterals4(TestHost testHost) - { - var code = @" + /// + /// Parser does not currently support strings of this type + /// + [Theory, CombinatorialData] + public async Task VerbatimStringLiterals3(TestHost testHost) + { + await TestAsync(@"goo @""", + testHost, + Identifier("goo"), + Verbatim(@"@""")); + } + + /// + /// Uncompleted ones should span new lines + /// + [Theory, CombinatorialData] + public async Task VerbatimStringLiterals4(TestHost testHost) + { + var code = @" @"" goo bar "; - await TestAsync(code, - testHost, - Verbatim(@"@"" goo bar + await TestAsync(code, + testHost, + Verbatim(@"@"" goo bar ")); - } + } - [Theory, CombinatorialData] - public async Task VerbatimStringLiterals5(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task VerbatimStringLiterals5(TestHost testHost) + { + var code = @" @"" goo bar and on a new line "" more stuff"; - await TestInMethodAsync(code, - testHost, - Verbatim(@"@"" goo bar + await TestInMethodAsync(code, + testHost, + Verbatim(@"@"" goo bar and on a new line """), - Identifier("more"), - Local("stuff")); - } + Identifier("more"), + Local("stuff")); + } - [Theory, CombinatorialData] - public async Task VerbatimStringLiteralsUtf8_03(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task VerbatimStringLiteralsUtf8_03(TestHost testHost) + { + var code = @" @"" goo bar and on a new line ""u8 more stuff"; - await TestInMethodAsync(code, - testHost, - Verbatim(@"@"" goo bar + await TestInMethodAsync(code, + testHost, + Verbatim(@"@"" goo bar and on a new line """), - Keyword("u8"), - Identifier("more"), - Local("stuff")); - } + Keyword("u8"), + Identifier("more"), + Local("stuff")); + } - [Theory, CombinatorialData] - public async Task VerbatimStringLiteralsUtf8_04(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task VerbatimStringLiteralsUtf8_04(TestHost testHost) + { + var code = @" @"" goo bar and on a new line ""U8 more stuff"; - await TestInMethodAsync(code, - testHost, - Verbatim(@"@"" goo bar + await TestInMethodAsync(code, + testHost, + Verbatim(@"@"" goo bar and on a new line """), - Keyword("U8"), - Identifier("more"), - Local("stuff")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - [CombinatorialData] - public async Task VerbatimStringLiterals6(bool script, TestHost testHost) - { - var code = @"string s = @""""""/*"";"; + Keyword("U8"), + Identifier("more"), + Local("stuff")); + } - var parseOptions = script ? Options.Script : null; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + [CombinatorialData] + public async Task VerbatimStringLiterals6(bool script, TestHost testHost) + { + var code = @"string s = @""""""/*"";"; - await TestAsync( - code, - code, - testHost, - parseOptions, - Keyword("string"), - script ? Field("s") : Local("s"), - Operators.Equals, - Verbatim(@"@""""""/*"""), - Punctuation.Semicolon); - } + var parseOptions = script ? Options.Script : null; - [Theory, CombinatorialData] - public async Task VerbatimStringLiteralsUtf8_05(bool script, TestHost testHost) - { - var code = @"string s = @""""""/*""u8;"; + await TestAsync( + code, + code, + testHost, + parseOptions, + Keyword("string"), + script ? Field("s") : Local("s"), + Operators.Equals, + Verbatim(@"@""""""/*"""), + Punctuation.Semicolon); + } - var parseOptions = script ? Options.Script : null; + [Theory, CombinatorialData] + public async Task VerbatimStringLiteralsUtf8_05(bool script, TestHost testHost) + { + var code = @"string s = @""""""/*""u8;"; - await TestAsync( - code, - code, - testHost, - parseOptions, - Keyword("string"), - script ? Field("s") : Local("s"), - Operators.Equals, - Verbatim(@"@""""""/*"""), - Keyword("u8"), - Punctuation.Semicolon); - } + var parseOptions = script ? Options.Script : null; - [Theory, CombinatorialData] - public async Task VerbatimStringLiteralsUtf8_06(bool script, TestHost testHost) - { - var code = @"string s = @""""""/*""u8;"; + await TestAsync( + code, + code, + testHost, + parseOptions, + Keyword("string"), + script ? Field("s") : Local("s"), + Operators.Equals, + Verbatim(@"@""""""/*"""), + Keyword("u8"), + Punctuation.Semicolon); + } - var parseOptions = script ? Options.Script : null; + [Theory, CombinatorialData] + public async Task VerbatimStringLiteralsUtf8_06(bool script, TestHost testHost) + { + var code = @"string s = @""""""/*""u8;"; - await TestAsync( - code, - code, - testHost, - parseOptions, - Keyword("string"), - script ? Field("s") : Local("s"), - Operators.Equals, - Verbatim(@"@""""""/*"""), - Keyword("u8"), - Punctuation.Semicolon); - } + var parseOptions = script ? Options.Script : null; - [Theory, CombinatorialData] - public async Task StringLiteral1(TestHost testHost) - { - await TestAsync(@"""goo""", - testHost, - String(@"""goo""")); - } + await TestAsync( + code, + code, + testHost, + parseOptions, + Keyword("string"), + script ? Field("s") : Local("s"), + Operators.Equals, + Verbatim(@"@""""""/*"""), + Keyword("u8"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task StringLiteralUtf8_01(TestHost testHost) - { - await TestAsync(@"""goo""u8", - testHost, - String(@"""goo"""), - Keyword("u8")); - } + [Theory, CombinatorialData] + public async Task StringLiteral1(TestHost testHost) + { + await TestAsync(@"""goo""", + testHost, + String(@"""goo""")); + } - [Theory, CombinatorialData] - public async Task StringLiteralUtf8_02(TestHost testHost) - { - await TestAsync(@"""goo""U8", - testHost, - String(@"""goo"""), - Keyword("U8")); - } + [Theory, CombinatorialData] + public async Task StringLiteralUtf8_01(TestHost testHost) + { + await TestAsync(@"""goo""u8", + testHost, + String(@"""goo"""), + Keyword("u8")); + } - [Theory, CombinatorialData] - public async Task StringLiteral2(TestHost testHost) - { - await TestAsync(@"""""", - testHost, - String(@"""""")); - } + [Theory, CombinatorialData] + public async Task StringLiteralUtf8_02(TestHost testHost) + { + await TestAsync(@"""goo""U8", + testHost, + String(@"""goo"""), + Keyword("U8")); + } - [Theory, CombinatorialData] - public async Task StringLiteralUtf8_03(TestHost testHost) - { - await TestAsync(@"""""u8", - testHost, - String(@""""""), - Keyword("u8")); - } + [Theory, CombinatorialData] + public async Task StringLiteral2(TestHost testHost) + { + await TestAsync(@"""""", + testHost, + String(@"""""")); + } - [Theory, CombinatorialData] - public async Task StringLiteralUtf8_04(TestHost testHost) - { - await TestAsync(@"""""U8", - testHost, - String(@""""""), - Keyword("U8")); - } + [Theory, CombinatorialData] + public async Task StringLiteralUtf8_03(TestHost testHost) + { + await TestAsync(@"""""u8", + testHost, + String(@""""""), + Keyword("u8")); + } - [Theory, CombinatorialData] - public async Task CharacterLiteral1(TestHost testHost) - { - var code = @"'f'"; - await TestInMethodAsync(code, - testHost, - String("'f'")); - } + [Theory, CombinatorialData] + public async Task StringLiteralUtf8_04(TestHost testHost) + { + await TestAsync(@"""""U8", + testHost, + String(@""""""), + Keyword("U8")); + } - [Theory, CombinatorialData] - public async Task LinqFrom1(TestHost testHost) - { - var code = @"from it in goo"; - await TestInExpressionAsync(code, - testHost, - Keyword("from"), - Identifier("it"), - Keyword("in"), - Identifier("goo")); - } + [Theory, CombinatorialData] + public async Task CharacterLiteral1(TestHost testHost) + { + var code = @"'f'"; + await TestInMethodAsync(code, + testHost, + String("'f'")); + } - [Theory, CombinatorialData] - public async Task LinqFrom2(TestHost testHost) - { - var code = @"from it in goo.Bar()"; - await TestInExpressionAsync(code, - testHost, - Keyword("from"), - Identifier("it"), - Keyword("in"), - Identifier("goo"), - Operators.Dot, - Identifier("Bar"), - Punctuation.OpenParen, - Punctuation.CloseParen); - } + [Theory, CombinatorialData] + public async Task LinqFrom1(TestHost testHost) + { + var code = @"from it in goo"; + await TestInExpressionAsync(code, + testHost, + Keyword("from"), + Identifier("it"), + Keyword("in"), + Identifier("goo")); + } - [Theory, CombinatorialData] - public async Task LinqFrom3(TestHost testHost) - { - // query expression are not statement expressions, but the parser parses them anyways to give better errors - var code = @"from it in "; - await TestInMethodAsync(code, - testHost, - Keyword("from"), - Identifier("it"), - Keyword("in")); - } + [Theory, CombinatorialData] + public async Task LinqFrom2(TestHost testHost) + { + var code = @"from it in goo.Bar()"; + await TestInExpressionAsync(code, + testHost, + Keyword("from"), + Identifier("it"), + Keyword("in"), + Identifier("goo"), + Operators.Dot, + Identifier("Bar"), + Punctuation.OpenParen, + Punctuation.CloseParen); + } - [Theory, CombinatorialData] - public async Task LinqFrom4(TestHost testHost) - { - var code = @"from it in "; - await TestInExpressionAsync(code, - testHost, - Keyword("from"), - Identifier("it"), - Keyword("in")); - } + [Theory, CombinatorialData] + public async Task LinqFrom3(TestHost testHost) + { + // query expression are not statement expressions, but the parser parses them anyways to give better errors + var code = @"from it in "; + await TestInMethodAsync(code, + testHost, + Keyword("from"), + Identifier("it"), + Keyword("in")); + } - [Theory, CombinatorialData] - public async Task LinqWhere1(TestHost testHost) - { - var code = "from it in goo where it > 42"; - await TestInExpressionAsync(code, - testHost, - Keyword("from"), - Identifier("it"), - Keyword("in"), - Identifier("goo"), - Keyword("where"), - Identifier("it"), - Operators.GreaterThan, - Number("42")); - } + [Theory, CombinatorialData] + public async Task LinqFrom4(TestHost testHost) + { + var code = @"from it in "; + await TestInExpressionAsync(code, + testHost, + Keyword("from"), + Identifier("it"), + Keyword("in")); + } - [Theory, CombinatorialData] - public async Task LinqWhere2(TestHost testHost) - { - var code = @"from it in goo where it > ""bar"""; - await TestInExpressionAsync(code, - testHost, - Keyword("from"), - Identifier("it"), - Keyword("in"), - Identifier("goo"), - Keyword("where"), - Identifier("it"), - Operators.GreaterThan, - String(@"""bar""")); - } + [Theory, CombinatorialData] + public async Task LinqWhere1(TestHost testHost) + { + var code = "from it in goo where it > 42"; + await TestInExpressionAsync(code, + testHost, + Keyword("from"), + Identifier("it"), + Keyword("in"), + Identifier("goo"), + Keyword("where"), + Identifier("it"), + Operators.GreaterThan, + Number("42")); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - [CombinatorialData] - public async Task VarContextualKeywordAtNamespaceLevel(bool script, TestHost testHost) - { - var code = @"var goo = 2;"; + [Theory, CombinatorialData] + public async Task LinqWhere2(TestHost testHost) + { + var code = @"from it in goo where it > ""bar"""; + await TestInExpressionAsync(code, + testHost, + Keyword("from"), + Identifier("it"), + Keyword("in"), + Identifier("goo"), + Keyword("where"), + Identifier("it"), + Operators.GreaterThan, + String(@"""bar""")); + } - var parseOptions = script ? Options.Script : null; + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + [CombinatorialData] + public async Task VarContextualKeywordAtNamespaceLevel(bool script, TestHost testHost) + { + var code = @"var goo = 2;"; - await TestAsync(code, - code, - testHost, - parseOptions, - script ? Identifier("var") : Keyword("var"), - script ? Field("goo") : Local("goo"), - Operators.Equals, - Number("2"), - Punctuation.Semicolon); - } + var parseOptions = script ? Options.Script : null; - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - [CombinatorialData] - public async Task LinqKeywordsAtNamespaceLevel(bool script, TestHost testHost) - { - // the contextual keywords are actual keywords since we parse top level field declaration and only give a semantic error - var code = @"object goo = from goo in goo + await TestAsync(code, + code, + testHost, + parseOptions, + script ? Identifier("var") : Keyword("var"), + script ? Field("goo") : Local("goo"), + Operators.Equals, + Number("2"), + Punctuation.Semicolon); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + [CombinatorialData] + public async Task LinqKeywordsAtNamespaceLevel(bool script, TestHost testHost) + { + // the contextual keywords are actual keywords since we parse top level field declaration and only give a semantic error + var code = @"object goo = from goo in goo join goo in goo on goo equals goo group goo by goo into goo let goo = goo @@ -712,91 +712,91 @@ where goo orderby goo ascending, goo descending select goo;"; - var parseOptions = script ? Options.Script : null; + var parseOptions = script ? Options.Script : null; - await TestAsync( - code, - code, - testHost, - parseOptions, - Keyword("object"), - script ? Field("goo") : Local("goo"), - Operators.Equals, - Keyword("from"), - Identifier("goo"), - Keyword("in"), - Identifier("goo"), - Keyword("join"), - Identifier("goo"), - Keyword("in"), - Identifier("goo"), - Keyword("on"), - Identifier("goo"), - Keyword("equals"), - Identifier("goo"), - Keyword("group"), - Identifier("goo"), - Keyword("by"), - Identifier("goo"), - Keyword("into"), - Identifier("goo"), - Keyword("let"), - Identifier("goo"), - Operators.Equals, - Identifier("goo"), - Keyword("where"), - Identifier("goo"), - Keyword("orderby"), - Identifier("goo"), - Keyword("ascending"), - Punctuation.Comma, - Identifier("goo"), - Keyword("descending"), - Keyword("select"), - Identifier("goo"), - Punctuation.Semicolon); - } + await TestAsync( + code, + code, + testHost, + parseOptions, + Keyword("object"), + script ? Field("goo") : Local("goo"), + Operators.Equals, + Keyword("from"), + Identifier("goo"), + Keyword("in"), + Identifier("goo"), + Keyword("join"), + Identifier("goo"), + Keyword("in"), + Identifier("goo"), + Keyword("on"), + Identifier("goo"), + Keyword("equals"), + Identifier("goo"), + Keyword("group"), + Identifier("goo"), + Keyword("by"), + Identifier("goo"), + Keyword("into"), + Identifier("goo"), + Keyword("let"), + Identifier("goo"), + Operators.Equals, + Identifier("goo"), + Keyword("where"), + Identifier("goo"), + Keyword("orderby"), + Identifier("goo"), + Keyword("ascending"), + Punctuation.Comma, + Identifier("goo"), + Keyword("descending"), + Keyword("select"), + Identifier("goo"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task ContextualKeywordsAsFieldName(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task ContextualKeywordsAsFieldName(TestHost testHost) + { + await TestAsync( @"class C { int yield, get, set, value, add, remove, global, partial, where, alias; }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("int"), - Field("yield"), - Punctuation.Comma, - Field("get"), - Punctuation.Comma, - Field("set"), - Punctuation.Comma, - Field("value"), - Punctuation.Comma, - Field("add"), - Punctuation.Comma, - Field("remove"), - Punctuation.Comma, - Field("global"), - Punctuation.Comma, - Field("partial"), - Punctuation.Comma, - Field("where"), - Punctuation.Comma, - Field("alias"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("int"), + Field("yield"), + Punctuation.Comma, + Field("get"), + Punctuation.Comma, + Field("set"), + Punctuation.Comma, + Field("value"), + Punctuation.Comma, + Field("add"), + Punctuation.Comma, + Field("remove"), + Punctuation.Comma, + Field("global"), + Punctuation.Comma, + Field("partial"), + Punctuation.Comma, + Field("where"), + Punctuation.Comma, + Field("alias"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LinqKeywordsInFieldInitializer(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task LinqKeywordsInFieldInitializer(TestHost testHost) + { + await TestAsync( @"class C { int a = from a in a @@ -807,53 +807,53 @@ where a orderby a ascending, a descending select a; }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("int"), - Field("a"), - Operators.Equals, - Keyword("from"), - Identifier("a"), - Keyword("in"), - Identifier("a"), - Keyword("join"), - Identifier("a"), - Keyword("in"), - Identifier("a"), - Keyword("on"), - Identifier("a"), - Keyword("equals"), - Identifier("a"), - Keyword("group"), - Identifier("a"), - Keyword("by"), - Identifier("a"), - Keyword("into"), - Identifier("a"), - Keyword("let"), - Identifier("a"), - Operators.Equals, - Identifier("a"), - Keyword("where"), - Identifier("a"), - Keyword("orderby"), - Identifier("a"), - Keyword("ascending"), - Punctuation.Comma, - Identifier("a"), - Keyword("descending"), - Keyword("select"), - Identifier("a"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("int"), + Field("a"), + Operators.Equals, + Keyword("from"), + Identifier("a"), + Keyword("in"), + Identifier("a"), + Keyword("join"), + Identifier("a"), + Keyword("in"), + Identifier("a"), + Keyword("on"), + Identifier("a"), + Keyword("equals"), + Identifier("a"), + Keyword("group"), + Identifier("a"), + Keyword("by"), + Identifier("a"), + Keyword("into"), + Identifier("a"), + Keyword("let"), + Identifier("a"), + Operators.Equals, + Identifier("a"), + Keyword("where"), + Identifier("a"), + Keyword("orderby"), + Identifier("a"), + Keyword("ascending"), + Punctuation.Comma, + Identifier("a"), + Keyword("descending"), + Keyword("select"), + Identifier("a"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LinqKeywordsAsTypeName(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task LinqKeywordsAsTypeName(TestHost testHost) + { + await TestAsync( @"class var { } @@ -906,133 +906,133 @@ class descending class select { }", - testHost, - Keyword("class"), - Class("var"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("struct"), - Struct("from"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("interface"), - Interface("join"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("enum"), - Enum("on"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Identifier("equals"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("group"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("by"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("into"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("let"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("where"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("orderby"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("ascending"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("descending"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("select"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("var"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("struct"), + Struct("from"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("interface"), + Interface("join"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("enum"), + Enum("on"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Identifier("equals"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("group"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("by"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("into"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("let"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("where"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("orderby"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("ascending"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("descending"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("select"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LinqKeywordsAsMethodParameters(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task LinqKeywordsAsMethodParameters(TestHost testHost) + { + await TestAsync( @"class C { orderby M(var goo, from goo, join goo, on goo, equals goo, group goo, by goo, into goo, let goo, where goo, orderby goo, ascending goo, descending goo, select goo) { } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Identifier("orderby"), - Method("M"), - Punctuation.OpenParen, - Identifier("var"), - Parameter("goo"), - Punctuation.Comma, - Identifier("from"), - Parameter("goo"), - Punctuation.Comma, - Identifier("join"), - Parameter("goo"), - Punctuation.Comma, - Identifier("on"), - Parameter("goo"), - Punctuation.Comma, - Identifier("equals"), - Parameter("goo"), - Punctuation.Comma, - Identifier("group"), - Parameter("goo"), - Punctuation.Comma, - Identifier("by"), - Parameter("goo"), - Punctuation.Comma, - Identifier("into"), - Parameter("goo"), - Punctuation.Comma, - Identifier("let"), - Parameter("goo"), - Punctuation.Comma, - Identifier("where"), - Parameter("goo"), - Punctuation.Comma, - Identifier("orderby"), - Parameter("goo"), - Punctuation.Comma, - Identifier("ascending"), - Parameter("goo"), - Punctuation.Comma, - Identifier("descending"), - Parameter("goo"), - Punctuation.Comma, - Identifier("select"), - Parameter("goo"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Identifier("orderby"), + Method("M"), + Punctuation.OpenParen, + Identifier("var"), + Parameter("goo"), + Punctuation.Comma, + Identifier("from"), + Parameter("goo"), + Punctuation.Comma, + Identifier("join"), + Parameter("goo"), + Punctuation.Comma, + Identifier("on"), + Parameter("goo"), + Punctuation.Comma, + Identifier("equals"), + Parameter("goo"), + Punctuation.Comma, + Identifier("group"), + Parameter("goo"), + Punctuation.Comma, + Identifier("by"), + Parameter("goo"), + Punctuation.Comma, + Identifier("into"), + Parameter("goo"), + Punctuation.Comma, + Identifier("let"), + Parameter("goo"), + Punctuation.Comma, + Identifier("where"), + Parameter("goo"), + Punctuation.Comma, + Identifier("orderby"), + Parameter("goo"), + Punctuation.Comma, + Identifier("ascending"), + Parameter("goo"), + Punctuation.Comma, + Identifier("descending"), + Parameter("goo"), + Punctuation.Comma, + Identifier("select"), + Parameter("goo"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LinqKeywordsInLocalVariableDeclarations(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task LinqKeywordsInLocalVariableDeclarations(TestHost testHost) + { + await TestAsync( @"class C { void M() @@ -1051,835 +1051,835 @@ void M() select goo = (select)goo as select; } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("var"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("var"), - Punctuation.Semicolon, - Identifier("from"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("from"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("from"), - Punctuation.Semicolon, - Identifier("join"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("join"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("join"), - Punctuation.Semicolon, - Identifier("on"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("on"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("on"), - Punctuation.Semicolon, - Identifier("equals"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("equals"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("equals"), - Punctuation.Semicolon, - Identifier("group"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("group"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("group"), - Punctuation.Semicolon, - Identifier("by"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("by"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("by"), - Punctuation.Semicolon, - Identifier("into"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("into"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("into"), - Punctuation.Semicolon, - Identifier("orderby"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("orderby"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("orderby"), - Punctuation.Semicolon, - Identifier("ascending"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("ascending"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("ascending"), - Punctuation.Semicolon, - Identifier("descending"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("descending"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("descending"), - Punctuation.Semicolon, - Identifier("select"), - Local("goo"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("select"), - Punctuation.CloseParen, - Identifier("goo"), - Keyword("as"), - Identifier("select"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("var"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("var"), + Punctuation.Semicolon, + Identifier("from"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("from"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("from"), + Punctuation.Semicolon, + Identifier("join"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("join"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("join"), + Punctuation.Semicolon, + Identifier("on"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("on"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("on"), + Punctuation.Semicolon, + Identifier("equals"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("equals"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("equals"), + Punctuation.Semicolon, + Identifier("group"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("group"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("group"), + Punctuation.Semicolon, + Identifier("by"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("by"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("by"), + Punctuation.Semicolon, + Identifier("into"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("into"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("into"), + Punctuation.Semicolon, + Identifier("orderby"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("orderby"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("orderby"), + Punctuation.Semicolon, + Identifier("ascending"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("ascending"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("ascending"), + Punctuation.Semicolon, + Identifier("descending"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("descending"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("descending"), + Punctuation.Semicolon, + Identifier("select"), + Local("goo"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("select"), + Punctuation.CloseParen, + Identifier("goo"), + Keyword("as"), + Identifier("select"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LinqKeywordsAsFieldNames(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task LinqKeywordsAsFieldNames(TestHost testHost) + { + await TestAsync( @"class C { int var, from, join, on, into, equals, let, orderby, ascending, descending, select, group, by, partial; }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("int"), - Field("var"), - Punctuation.Comma, - Field("from"), - Punctuation.Comma, - Field("join"), - Punctuation.Comma, - Field("on"), - Punctuation.Comma, - Field("into"), - Punctuation.Comma, - Field("equals"), - Punctuation.Comma, - Field("let"), - Punctuation.Comma, - Field("orderby"), - Punctuation.Comma, - Field("ascending"), - Punctuation.Comma, - Field("descending"), - Punctuation.Comma, - Field("select"), - Punctuation.Comma, - Field("group"), - Punctuation.Comma, - Field("by"), - Punctuation.Comma, - Field("partial"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("int"), + Field("var"), + Punctuation.Comma, + Field("from"), + Punctuation.Comma, + Field("join"), + Punctuation.Comma, + Field("on"), + Punctuation.Comma, + Field("into"), + Punctuation.Comma, + Field("equals"), + Punctuation.Comma, + Field("let"), + Punctuation.Comma, + Field("orderby"), + Punctuation.Comma, + Field("ascending"), + Punctuation.Comma, + Field("descending"), + Punctuation.Comma, + Field("select"), + Punctuation.Comma, + Field("group"), + Punctuation.Comma, + Field("by"), + Punctuation.Comma, + Field("partial"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LinqKeywordsAtFieldLevelInvalid(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task LinqKeywordsAtFieldLevelInvalid(TestHost testHost) + { + await TestAsync( @"class C { string Property { from a in a join a in a on a equals a group a by a into a let a = a where a orderby a ascending, a descending select a; } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("string"), - Property("Property"), - Punctuation.OpenCurly, - Identifier("from"), - Identifier("a"), - Keyword("in"), - Identifier("a"), - Identifier("join"), - Identifier("a"), - Keyword("in"), - Identifier("a"), - Identifier("on"), - Identifier("a"), - Identifier("equals"), - Identifier("a"), - Identifier("group"), - Identifier("a"), - Identifier("by"), - Identifier("a"), - Identifier("into"), - Identifier("a"), - Identifier("let"), - Identifier("a"), - Operators.Equals, - Identifier("a"), - Identifier("where"), - Identifier("a"), - Identifier("orderby"), - Identifier("a"), - Identifier("ascending"), - Punctuation.Comma, - Identifier("a"), - Identifier("descending"), - Identifier("select"), - Identifier("a"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("string"), + Property("Property"), + Punctuation.OpenCurly, + Identifier("from"), + Identifier("a"), + Keyword("in"), + Identifier("a"), + Identifier("join"), + Identifier("a"), + Keyword("in"), + Identifier("a"), + Identifier("on"), + Identifier("a"), + Identifier("equals"), + Identifier("a"), + Identifier("group"), + Identifier("a"), + Identifier("by"), + Identifier("a"), + Identifier("into"), + Identifier("a"), + Identifier("let"), + Identifier("a"), + Operators.Equals, + Identifier("a"), + Identifier("where"), + Identifier("a"), + Identifier("orderby"), + Identifier("a"), + Identifier("ascending"), + Punctuation.Comma, + Identifier("a"), + Identifier("descending"), + Identifier("select"), + Identifier("a"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CommentSingle(TestHost testHost) - { - var code = "// goo"; + [Theory, CombinatorialData] + public async Task CommentSingle(TestHost testHost) + { + var code = "// goo"; - await TestAsync(code, - testHost, - Comment("// goo")); - } + await TestAsync(code, + testHost, + Comment("// goo")); + } - [Theory, CombinatorialData] - public async Task CommentAsTrailingTrivia1(TestHost testHost) - { - var code = "class Bar { // goo"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Comment("// goo")); - } + [Theory, CombinatorialData] + public async Task CommentAsTrailingTrivia1(TestHost testHost) + { + var code = "class Bar { // goo"; + await TestAsync(code, + testHost, + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Comment("// goo")); + } - [Theory, CombinatorialData] - public async Task CommentAsLeadingTrivia1(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task CommentAsLeadingTrivia1(TestHost testHost) + { + var code = @" class Bar { // goo void Method1() { } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Comment("// goo"), - Keyword("void"), - Method("Method1"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Comment("// goo"), + Keyword("void"), + Method("Method1"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task ShebangAsFirstCommentInScript(TestHost testHost) - { - var code = @"#!/usr/bin/env scriptcs + [Theory, CombinatorialData] + public async Task ShebangAsFirstCommentInScript(TestHost testHost) + { + var code = @"#!/usr/bin/env scriptcs System.Console.WriteLine();"; - var expected = new[] - { - Comment("#!/usr/bin/env scriptcs"), - Identifier("System"), - Operators.Dot, - Identifier("Console"), - Operators.Dot, - Identifier("WriteLine"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon - }; - - await TestAsync(code, code, testHost, Options.Script, expected); - } - - [Theory, CombinatorialData] - public async Task ShebangAsFirstCommentInNonScript(TestHost testHost) + var expected = new[] { - var code = @"#!/usr/bin/env scriptcs -System.Console.WriteLine();"; + Comment("#!/usr/bin/env scriptcs"), + Identifier("System"), + Operators.Dot, + Identifier("Console"), + Operators.Dot, + Identifier("WriteLine"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon + }; - var expected = new[] - { - PPKeyword("#"), - PPText("!/usr/bin/env scriptcs"), - Identifier("System"), - Operators.Dot, - Identifier("Console"), - Operators.Dot, - Identifier("WriteLine"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon - }; - - await TestAsync(code, code, testHost, Options.Regular, expected); - } + await TestAsync(code, code, testHost, Options.Script, expected); + } - [Theory, CombinatorialData] - public async Task ShebangNotAsFirstCommentInScript(TestHost testHost) - { - var code = @" #!/usr/bin/env scriptcs + [Theory, CombinatorialData] + public async Task ShebangAsFirstCommentInNonScript(TestHost testHost) + { + var code = @"#!/usr/bin/env scriptcs System.Console.WriteLine();"; - var expected = new[] - { - PPKeyword("#"), - PPText("!/usr/bin/env scriptcs"), - Identifier("System"), - Operators.Dot, - Identifier("Console"), - Operators.Dot, - Identifier("WriteLine"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon - }; - - await TestAsync(code, code, testHost, Options.Script, expected); - } + var expected = new[] + { + PPKeyword("#"), + PPText("!/usr/bin/env scriptcs"), + Identifier("System"), + Operators.Dot, + Identifier("Console"), + Operators.Dot, + Identifier("WriteLine"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon + }; + + await TestAsync(code, code, testHost, Options.Regular, expected); + } + + [Theory, CombinatorialData] + public async Task ShebangNotAsFirstCommentInScript(TestHost testHost) + { + var code = @" #!/usr/bin/env scriptcs +System.Console.WriteLine();"; - [Theory, CombinatorialData] - public async Task CommentAsMethodBodyContent(TestHost testHost) + var expected = new[] { - var code = @" + PPKeyword("#"), + PPText("!/usr/bin/env scriptcs"), + Identifier("System"), + Operators.Dot, + Identifier("Console"), + Operators.Dot, + Identifier("WriteLine"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon + }; + + await TestAsync(code, code, testHost, Options.Script, expected); + } + + [Theory, CombinatorialData] + public async Task CommentAsMethodBodyContent(TestHost testHost) + { + var code = @" class Bar { void Method1() { // goo } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Method1"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Comment("// goo"), - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Method1"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Comment("// goo"), + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CommentMix1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task CommentMix1(TestHost testHost) + { + await TestAsync( @"// comment1 /* class cl { } //comment2 */", - testHost, - Comment("// comment1 /*"), - Keyword("class"), - Class("cl"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Comment("//comment2 */")); - } + testHost, + Comment("// comment1 /*"), + Keyword("class"), + Class("cl"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Comment("//comment2 */")); + } - [Theory, CombinatorialData] - public async Task CommentMix2(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task CommentMix2(TestHost testHost) + { + await TestInMethodAsync( @"/**/int /**/i = 0;", - testHost, - Comment("/**/"), - Keyword("int"), - Comment("/**/"), - Local("i"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon); - } + testHost, + Comment("/**/"), + Keyword("int"), + Comment("/**/"), + Local("i"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task XmlDocCommentOnClass(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocCommentOnClass(TestHost testHost) + { + var code = @" /// something class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Text("something"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Text("something"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocCommentOnClassWithIndent(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocCommentOnClassWithIndent(TestHost testHost) + { + var code = @" /// /// something /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter("///"), - XmlDoc.Text(" something"), - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter("///"), + XmlDoc.Text(" something"), + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_EntityReference(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_EntityReference(TestHost testHost) + { + var code = @" /// A class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.EntityReference("A"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.EntityReference("A"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_ExteriorTriviaInsideCloseTag(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_ExteriorTriviaInsideCloseTag(TestHost testHost) + { + var code = @" /// something class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Text("something"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Text("something"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531155")] - [CombinatorialData] - public async Task XmlDocComment_ExteriorTriviaInsideCRef(TestHost testHost) - { - var code = @" + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531155")] + [CombinatorialData] + public async Task XmlDocComment_ExteriorTriviaInsideCRef(TestHost testHost) + { + var code = @" /// class C { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("see"), - XmlDoc.AttributeName("cref"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes("\""), - Identifier("System"), - Operators.Dot, - XmlDoc.Delimiter("///"), - Identifier("Int32"), - XmlDoc.AttributeQuotes("\""), - XmlDoc.Delimiter("/>"), - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("see"), + XmlDoc.AttributeName("cref"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes("\""), + Identifier("System"), + Operators.Dot, + XmlDoc.Delimiter("///"), + Identifier("Int32"), + XmlDoc.AttributeQuotes("\""), + XmlDoc.Delimiter("/>"), + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocCommentOnClassWithExteriorTrivia(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocCommentOnClassWithExteriorTrivia(TestHost testHost) + { + var code = @" /// /// something /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter("///"), - XmlDoc.Text(" something"), - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter("///"), + XmlDoc.Text(" something"), + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_ExteriorTriviaNoText(TestHost testHost) - { - var code = + [Theory, CombinatorialData] + public async Task XmlDocComment_ExteriorTriviaNoText(TestHost testHost) + { + var code = @"/// ///something /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter("///"), - XmlDoc.Text("something"), - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter("///"), + XmlDoc.Text("something"), + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_EmptyElement(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_EmptyElement(TestHost testHost) + { + var code = @" /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter("/>"), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter("/>"), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_Attribute(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_Attribute(TestHost testHost) + { + var code = @" /// something class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.AttributeName("attribute"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(@""""), - XmlDoc.AttributeValue(@"value"), - XmlDoc.AttributeQuotes(@""""), - XmlDoc.Delimiter(">"), - XmlDoc.Text("something"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.AttributeName("attribute"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(@""""), + XmlDoc.AttributeValue(@"value"), + XmlDoc.AttributeQuotes(@""""), + XmlDoc.Delimiter(">"), + XmlDoc.Text("something"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_AttributeInEmptyElement(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_AttributeInEmptyElement(TestHost testHost) + { + var code = @" /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.AttributeName("attribute"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(@""""), - XmlDoc.AttributeValue(@"value"), - XmlDoc.AttributeQuotes(@""""), - XmlDoc.Delimiter("/>"), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.AttributeName("attribute"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(@""""), + XmlDoc.AttributeValue(@"value"), + XmlDoc.AttributeQuotes(@""""), + XmlDoc.Delimiter("/>"), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_ExtraSpaces(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_ExtraSpaces(TestHost testHost) + { + var code = @" /// < summary attribute = ""value"" /> class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.AttributeName("attribute"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(@""""), - XmlDoc.AttributeValue(@"value"), - XmlDoc.AttributeQuotes(@""""), - XmlDoc.Delimiter("/>"), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.AttributeName("attribute"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(@""""), + XmlDoc.AttributeValue(@"value"), + XmlDoc.AttributeQuotes(@""""), + XmlDoc.Delimiter("/>"), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_XmlComment(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_XmlComment(TestHost testHost) + { + var code = @" /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_XmlCommentWithExteriorTrivia(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_XmlCommentWithExteriorTrivia(TestHost testHost) + { + var code = @" /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_XmlCommentInElement(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_XmlCommentInElement(TestHost testHost) + { + var code = @" /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter(""), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter(""), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/pull/31410")] - public async Task XmlDocComment_MalformedXmlDocComment(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/pull/31410")] + public async Task XmlDocComment_MalformedXmlDocComment(TestHost testHost) + { + var code = @" /// ///. /// class C { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter("<"), - XmlDoc.Name("a"), - XmlDoc.Name(":"), - XmlDoc.Name("b"), - XmlDoc.Text(","), - XmlDoc.Text("c"), - XmlDoc.Delimiter("/>"), - XmlDoc.Text("."), - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter("<"), + XmlDoc.Name("a"), + XmlDoc.Name(":"), + XmlDoc.Name("b"), + XmlDoc.Text(","), + XmlDoc.Text("c"), + XmlDoc.Delimiter("/>"), + XmlDoc.Text("."), + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task MultilineXmlDocComment_ExteriorTrivia(TestHost testHost) - { - var code = + [Theory, CombinatorialData] + public async Task MultilineXmlDocComment_ExteriorTrivia(TestHost testHost) + { + var code = @"/** *comment **/ class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("/**"), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter("*"), - XmlDoc.Text("comment"), - XmlDoc.Delimiter("*"), - XmlDoc.Delimiter(""), - XmlDoc.Delimiter("*/"), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("/**"), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter("*"), + XmlDoc.Text("comment"), + XmlDoc.Delimiter("*"), + XmlDoc.Delimiter(""), + XmlDoc.Delimiter("*/"), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_CDataWithExteriorTrivia(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task XmlDocComment_CDataWithExteriorTrivia(TestHost testHost) + { + var code = @" /// class Bar { }"; - await TestAsync(code, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task XmlDocComment_ProcessingDirective(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task XmlDocComment_ProcessingDirective(TestHost testHost) + { + await TestAsync( @"/// public class Program @@ -1888,488 +1888,488 @@ static void Main() { } }", - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.ProcessingInstruction(""), - XmlDoc.Delimiter(""), - Keyword("public"), - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("static"), - Keyword("void"), - Method("Main"), - Static("Main"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536321")] - public async Task KeywordTypeParameters(TestHost testHost) - { - var code = @"class C { }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.ProcessingInstruction(""), + XmlDoc.Delimiter(""), + Keyword("public"), + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("static"), + Keyword("void"), + Method("Main"), + Static("Main"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536853")] - public async Task TypeParametersWithAttribute(TestHost testHost) - { - var code = @"class C<[Attr] T> { }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenAngle, - Punctuation.OpenBracket, - Identifier("Attr"), - Punctuation.CloseBracket, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536321")] + public async Task KeywordTypeParameters(TestHost testHost) + { + var code = @"class C { }"; + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task ClassTypeDeclaration1(TestHost testHost) - { - var code = "class C1 { } "; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C1"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/536853")] + public async Task TypeParametersWithAttribute(TestHost testHost) + { + var code = @"class C<[Attr] T> { }"; + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenAngle, + Punctuation.OpenBracket, + Identifier("Attr"), + Punctuation.CloseBracket, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task ClassTypeDeclaration2(TestHost testHost) - { - var code = "class ClassName1 { } "; - await TestAsync(code, - testHost, - Keyword("class"), - Class("ClassName1"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task ClassTypeDeclaration1(TestHost testHost) + { + var code = "class C1 { } "; + await TestAsync(code, + testHost, + Keyword("class"), + Class("C1"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task StructTypeDeclaration1(TestHost testHost) - { - var code = "struct Struct1 { }"; - await TestAsync(code, - testHost, - Keyword("struct"), - Struct("Struct1"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task ClassTypeDeclaration2(TestHost testHost) + { + var code = "class ClassName1 { } "; + await TestAsync(code, + testHost, + Keyword("class"), + Class("ClassName1"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task InterfaceDeclaration1(TestHost testHost) - { - var code = "interface I1 { }"; - await TestAsync(code, - testHost, - Keyword("interface"), - Interface("I1"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task StructTypeDeclaration1(TestHost testHost) + { + var code = "struct Struct1 { }"; + await TestAsync(code, + testHost, + Keyword("struct"), + Struct("Struct1"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task EnumDeclaration1(TestHost testHost) - { - var code = "enum Weekday { }"; - await TestAsync(code, - testHost, - Keyword("enum"), - Enum("Weekday"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task InterfaceDeclaration1(TestHost testHost) + { + var code = "interface I1 { }"; + await TestAsync(code, + testHost, + Keyword("interface"), + Interface("I1"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem(4302, "DevDiv_Projects/Roslyn")] - [CombinatorialData] - public async Task ClassInEnum(TestHost testHost) - { - var code = "enum E { Min = System.Int32.MinValue }"; - await TestAsync(code, - testHost, - Keyword("enum"), - Enum("E"), - Punctuation.OpenCurly, - EnumMember("Min"), - Operators.Equals, - Identifier("System"), - Operators.Dot, - Identifier("Int32"), - Operators.Dot, - Identifier("MinValue"), - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task EnumDeclaration1(TestHost testHost) + { + var code = "enum Weekday { }"; + await TestAsync(code, + testHost, + Keyword("enum"), + Enum("Weekday"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task DelegateDeclaration1(TestHost testHost) - { - var code = "delegate void Action();"; - await TestAsync(code, - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("Action"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon); - } + [Theory, WorkItem(4302, "DevDiv_Projects/Roslyn")] + [CombinatorialData] + public async Task ClassInEnum(TestHost testHost) + { + var code = "enum E { Min = System.Int32.MinValue }"; + await TestAsync(code, + testHost, + Keyword("enum"), + Enum("E"), + Punctuation.OpenCurly, + EnumMember("Min"), + Operators.Equals, + Identifier("System"), + Operators.Dot, + Identifier("Int32"), + Operators.Dot, + Identifier("MinValue"), + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task GenericTypeArgument(TestHost testHost) - { - await TestInMethodAsync( - "C", - "M", - "default(T)", - testHost, - Keyword("default"), - Punctuation.OpenParen, - Identifier("T"), - Punctuation.CloseParen); - } + [Theory, CombinatorialData] + public async Task DelegateDeclaration1(TestHost testHost) + { + var code = "delegate void Action();"; + await TestAsync(code, + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("Action"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task GenericParameter(TestHost testHost) - { - var code = "class C1 {}"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C1"), - Punctuation.OpenAngle, - TypeParameter("P1"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task GenericTypeArgument(TestHost testHost) + { + await TestInMethodAsync( + "C", + "M", + "default(T)", + testHost, + Keyword("default"), + Punctuation.OpenParen, + Identifier("T"), + Punctuation.CloseParen); + } - [Theory, CombinatorialData] - public async Task GenericParameters(TestHost testHost) - { - var code = "class C1 {}"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C1"), - Punctuation.OpenAngle, - TypeParameter("P1"), - Punctuation.Comma, - TypeParameter("P2"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task GenericParameter(TestHost testHost) + { + var code = "class C1 {}"; + await TestAsync(code, + testHost, + Keyword("class"), + Class("C1"), + Punctuation.OpenAngle, + TypeParameter("P1"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task GenericParameter_Interface(TestHost testHost) - { - var code = "interface I1 {}"; - await TestAsync(code, - testHost, - Keyword("interface"), - Interface("I1"), - Punctuation.OpenAngle, - TypeParameter("P1"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task GenericParameters(TestHost testHost) + { + var code = "class C1 {}"; + await TestAsync(code, + testHost, + Keyword("class"), + Class("C1"), + Punctuation.OpenAngle, + TypeParameter("P1"), + Punctuation.Comma, + TypeParameter("P2"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task GenericParameter_Struct(TestHost testHost) - { - var code = "struct S1 {}"; - await TestAsync(code, - testHost, - Keyword("struct"), - Struct("S1"), - Punctuation.OpenAngle, - TypeParameter("P1"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task GenericParameter_Interface(TestHost testHost) + { + var code = "interface I1 {}"; + await TestAsync(code, + testHost, + Keyword("interface"), + Interface("I1"), + Punctuation.OpenAngle, + TypeParameter("P1"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task GenericParameter_Delegate(TestHost testHost) - { - var code = "delegate void D1 {}"; - await TestAsync(code, - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("D1"), - Punctuation.OpenAngle, - TypeParameter("P1"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task GenericParameter_Struct(TestHost testHost) + { + var code = "struct S1 {}"; + await TestAsync(code, + testHost, + Keyword("struct"), + Struct("S1"), + Punctuation.OpenAngle, + TypeParameter("P1"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task GenericParameter_Method(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task GenericParameter_Delegate(TestHost testHost) + { + var code = "delegate void D1 {}"; + await TestAsync(code, + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("D1"), + Punctuation.OpenAngle, + TypeParameter("P1"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task GenericParameter_Method(TestHost testHost) + { + await TestInClassAsync( @"T M(T t) { return default(T); }", - testHost, - Identifier("T"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Identifier("T"), - Parameter("t"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Keyword("default"), - Punctuation.OpenParen, - Identifier("T"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + testHost, + Identifier("T"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Identifier("T"), + Parameter("t"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("return"), + Keyword("default"), + Punctuation.OpenParen, + Identifier("T"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TernaryExpression(TestHost testHost) - { - await TestInExpressionAsync("true ? 1 : 0", - testHost, - Keyword("true"), - Operators.QuestionMark, - Number("1"), - Operators.Colon, - Number("0")); - } + [Theory, CombinatorialData] + public async Task TernaryExpression(TestHost testHost) + { + await TestInExpressionAsync("true ? 1 : 0", + testHost, + Keyword("true"), + Operators.QuestionMark, + Number("1"), + Operators.Colon, + Number("0")); + } - [Theory, CombinatorialData] - public async Task BaseClass(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task BaseClass(TestHost testHost) + { + await TestAsync( @"class C : B { }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.Colon, - Identifier("B"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.Colon, + Identifier("B"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestLabel(TestHost testHost) - { - await TestInMethodAsync("goo:", - testHost, - Label("goo"), - Punctuation.Colon); - } + [Theory, CombinatorialData] + public async Task TestLabel(TestHost testHost) + { + await TestInMethodAsync("goo:", + testHost, + Label("goo"), + Punctuation.Colon); + } - [Theory, CombinatorialData] - public async Task Attribute(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task Attribute(TestHost testHost) + { + await TestAsync( @"[assembly: Goo]", - testHost, - Punctuation.OpenBracket, - Keyword("assembly"), - Punctuation.Colon, - Identifier("Goo"), - Punctuation.CloseBracket); - } + testHost, + Punctuation.OpenBracket, + Keyword("assembly"), + Punctuation.Colon, + Identifier("Goo"), + Punctuation.CloseBracket); + } - [Theory, CombinatorialData] - public async Task TestAngleBracketsOnGenericConstraints_Bug932262(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAngleBracketsOnGenericConstraints_Bug932262(TestHost testHost) + { + await TestAsync( @"class C where T : A { }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Identifier("A"), - Punctuation.OpenAngle, - Identifier("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Identifier("A"), + Punctuation.OpenAngle, + Identifier("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestYieldPositive(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task TestYieldPositive(TestHost testHost) + { + await TestInMethodAsync( @"yield return goo;", - testHost, - ControlKeyword("yield"), - ControlKeyword("return"), - Identifier("goo"), - Punctuation.Semicolon); - } + testHost, + ControlKeyword("yield"), + ControlKeyword("return"), + Identifier("goo"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestYieldNegative(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task TestYieldNegative(TestHost testHost) + { + await TestInMethodAsync( @"int yield;", - testHost, - Keyword("int"), - Local("yield"), - Punctuation.Semicolon); - } + testHost, + Keyword("int"), + Local("yield"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestFromPositive(TestHost testHost) - { - await TestInExpressionAsync( + [Theory, CombinatorialData] + public async Task TestFromPositive(TestHost testHost) + { + await TestInExpressionAsync( @"from x in y", - testHost, - Keyword("from"), - Identifier("x"), - Keyword("in"), - Identifier("y")); - } + testHost, + Keyword("from"), + Identifier("x"), + Keyword("in"), + Identifier("y")); + } - [Theory, CombinatorialData] - public async Task TestFromNegative(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task TestFromNegative(TestHost testHost) + { + await TestInMethodAsync( @"int from;", - testHost, - Keyword("int"), - Local("from"), - Punctuation.Semicolon); - } + testHost, + Keyword("int"), + Local("from"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersModule(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersModule(TestHost testHost) + { + await TestAsync( @"[module: Obsolete]", - testHost, - Punctuation.OpenBracket, - Keyword("module"), - Punctuation.Colon, - Identifier("Obsolete"), - Punctuation.CloseBracket); - } + testHost, + Punctuation.OpenBracket, + Keyword("module"), + Punctuation.Colon, + Identifier("Obsolete"), + Punctuation.CloseBracket); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersAssembly(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersAssembly(TestHost testHost) + { + await TestAsync( @"[assembly: Obsolete]", - testHost, - Punctuation.OpenBracket, - Keyword("assembly"), - Punctuation.Colon, - Identifier("Obsolete"), - Punctuation.CloseBracket); - } + testHost, + Punctuation.OpenBracket, + Keyword("assembly"), + Punctuation.Colon, + Identifier("Obsolete"), + Punctuation.CloseBracket); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnDelegate(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnDelegate(TestHost testHost) + { + await TestInClassAsync( @"[type: A] [return: A] delegate void M();", - testHost, - Punctuation.OpenBracket, - Keyword("type"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("return"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Keyword("delegate"), - Keyword("void"), - Delegate("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon); - } + testHost, + Punctuation.OpenBracket, + Keyword("type"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("return"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Keyword("delegate"), + Keyword("void"), + Delegate("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnMethod(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnMethod(TestHost testHost) + { + await TestInClassAsync( @"[return: A] [method: A] void M() { }", - testHost, - Punctuation.OpenBracket, - Keyword("return"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Punctuation.OpenBracket, + Keyword("return"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnCtor(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnCtor(TestHost testHost) + { + await TestAsync( @"class C { [method: A] @@ -2377,27 +2377,27 @@ await TestAsync( { } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Class("C"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Class("C"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnDtor(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnDtor(TestHost testHost) + { + await TestAsync( @"class C { [method: A] @@ -2405,63 +2405,63 @@ await TestAsync( { } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Operators.Tilde, - Class("C"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Operators.Tilde, + Class("C"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnOperator(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnOperator(TestHost testHost) + { + await TestInClassAsync( @"[method: A] [return: A] static T operator +(T a, T b) { }", - testHost, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("return"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Keyword("static"), - Identifier("T"), - Keyword("operator"), - Operators.Plus, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.Comma, - Identifier("T"), - Parameter("b"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("return"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Keyword("static"), + Identifier("T"), + Keyword("operator"), + Operators.Plus, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.Comma, + Identifier("T"), + Parameter("b"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnEventDeclaration(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnEventDeclaration(TestHost testHost) + { + await TestInClassAsync( @"[event: A] event A E { @@ -2477,49 +2477,49 @@ event A E { } }", - testHost, - Punctuation.OpenBracket, - Keyword("event"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Keyword("event"), - Identifier("A"), - Event("E"), - Punctuation.OpenCurly, - Punctuation.OpenBracket, - Keyword("param"), - Punctuation.Colon, - Identifier("Test"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("Test"), - Punctuation.CloseBracket, - Keyword("add"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.OpenBracket, - Keyword("param"), - Punctuation.Colon, - Identifier("Test"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("Test"), - Punctuation.CloseBracket, - Keyword("remove"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Punctuation.OpenBracket, + Keyword("event"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Keyword("event"), + Identifier("A"), + Event("E"), + Punctuation.OpenCurly, + Punctuation.OpenBracket, + Keyword("param"), + Punctuation.Colon, + Identifier("Test"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("Test"), + Punctuation.CloseBracket, + Keyword("add"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.OpenBracket, + Keyword("param"), + Punctuation.Colon, + Identifier("Test"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("Test"), + Punctuation.CloseBracket, + Keyword("remove"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnPropertyAccessors(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnPropertyAccessors(TestHost testHost) + { + await TestInClassAsync( @"int P { [return: T] @@ -2534,69 +2534,69 @@ await TestInClassAsync( { } }", - testHost, - Keyword("int"), - Property("P"), - Punctuation.OpenCurly, - Punctuation.OpenBracket, - Keyword("return"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Keyword("get"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.OpenBracket, - Keyword("param"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Keyword("set"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("int"), + Property("P"), + Punctuation.OpenCurly, + Punctuation.OpenBracket, + Keyword("return"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Keyword("get"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.OpenBracket, + Keyword("param"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Keyword("set"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnIndexers(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnIndexers(TestHost testHost) + { + await TestInClassAsync( @"[property: A] int this[int i] { get; set; }", - testHost, - Punctuation.OpenBracket, - Keyword("property"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Keyword("int"), - Keyword("this"), - Punctuation.OpenBracket, - Keyword("int"), - Parameter("i"), - Punctuation.CloseBracket, - Punctuation.OpenCurly, - Keyword("get"), - Punctuation.Semicolon, - Keyword("set"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + testHost, + Punctuation.OpenBracket, + Keyword("property"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Keyword("int"), + Keyword("this"), + Punctuation.OpenBracket, + Keyword("int"), + Parameter("i"), + Punctuation.CloseBracket, + Punctuation.OpenCurly, + Keyword("get"), + Punctuation.Semicolon, + Keyword("set"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnIndexerAccessors(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnIndexerAccessors(TestHost testHost) + { + await TestInClassAsync( @"int this[int i] { [return: T] @@ -2611,68 +2611,68 @@ await TestInClassAsync( { } }", - testHost, - Keyword("int"), - Keyword("this"), - Punctuation.OpenBracket, - Keyword("int"), - Parameter("i"), - Punctuation.CloseBracket, - Punctuation.OpenCurly, - Punctuation.OpenBracket, - Keyword("return"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Keyword("get"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.OpenBracket, - Keyword("param"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Punctuation.OpenBracket, - Keyword("method"), - Punctuation.Colon, - Identifier("T"), - Punctuation.CloseBracket, - Keyword("set"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("int"), + Keyword("this"), + Punctuation.OpenBracket, + Keyword("int"), + Parameter("i"), + Punctuation.CloseBracket, + Punctuation.OpenCurly, + Punctuation.OpenBracket, + Keyword("return"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Keyword("get"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.OpenBracket, + Keyword("param"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Punctuation.OpenBracket, + Keyword("method"), + Punctuation.Colon, + Identifier("T"), + Punctuation.CloseBracket, + Keyword("set"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task AttributeTargetSpecifiersOnField(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task AttributeTargetSpecifiersOnField(TestHost testHost) + { + await TestInClassAsync( @"[field: A] const int a = 0;", - testHost, - Punctuation.OpenBracket, - Keyword("field"), - Punctuation.Colon, - Identifier("A"), - Punctuation.CloseBracket, - Keyword("const"), - Keyword("int"), - Constant("a"), - Static("a"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon); - } + testHost, + Punctuation.OpenBracket, + Keyword("field"), + Punctuation.Colon, + Identifier("A"), + Punctuation.CloseBracket, + Keyword("const"), + Keyword("int"), + Constant("a"), + Static("a"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestAllKeywords(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAllKeywords(TestHost testHost) + { + await TestAsync( @"using System; #region TaoRegion namespace MyNamespace @@ -2856,1054 +2856,1054 @@ interface Bar } } #endregion TaoRegion", - testHost, - new[] { new CSharpParseOptions(LanguageVersion.CSharp8) }, - Keyword("using"), - Identifier("System"), - Punctuation.Semicolon, - PPKeyword("#"), - PPKeyword("region"), - PPText("TaoRegion"), - Keyword("namespace"), - Namespace("MyNamespace"), - Punctuation.OpenCurly, - Keyword("abstract"), - Keyword("class"), - Class("Goo"), - Punctuation.Colon, - Identifier("Bar"), - Punctuation.OpenCurly, - Keyword("bool"), - Field("goo"), - Operators.Equals, - Keyword("default"), - Punctuation.OpenParen, - Keyword("bool"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("byte"), - Field("goo1"), - Punctuation.Semicolon, - Keyword("char"), - Field("goo2"), - Punctuation.Semicolon, - Keyword("const"), - Keyword("int"), - Constant("goo3"), - Static("goo3"), - Operators.Equals, - Number("999"), - Punctuation.Semicolon, - Keyword("decimal"), - Field("goo4"), - Punctuation.Semicolon, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("delegate"), - Operators.Asterisk, - Keyword("managed"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.Comma, - Keyword("int"), - Punctuation.CloseAngle, - Field("mgdfun"), - Punctuation.Semicolon, - Keyword("delegate"), - Operators.Asterisk, - Keyword("unmanaged"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.Comma, - Keyword("int"), - Punctuation.CloseAngle, - Field("unmgdfun"), - Punctuation.Semicolon, - Keyword("double"), - Field("goo5"), - Punctuation.Semicolon, - Keyword("enum"), - Enum("MyEnum"), - Punctuation.OpenCurly, - EnumMember("one"), - Punctuation.Comma, - EnumMember("two"), - Punctuation.Comma, - EnumMember("three"), - Punctuation.CloseCurly, - Punctuation.Semicolon, - Keyword("event"), - Identifier("D"), - Event("MyEvent"), - Punctuation.Semicolon, - Keyword("float"), - Field("goo6"), - Punctuation.Semicolon, - Keyword("static"), - Keyword("int"), - Field("x"), - Static("x"), - Punctuation.Semicolon, - Keyword("long"), - Field("goo7"), - Punctuation.Semicolon, - Keyword("sbyte"), - Field("goo8"), - Punctuation.Semicolon, - Keyword("short"), - Field("goo9"), - Punctuation.Semicolon, - Keyword("int"), - Field("goo10"), - Operators.Equals, - Keyword("sizeof"), - Punctuation.OpenParen, - Keyword("int"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("string"), - Field("goo11"), - Punctuation.Semicolon, - Keyword("uint"), - Field("goo12"), - Punctuation.Semicolon, - Keyword("ulong"), - Field("goo13"), - Punctuation.Semicolon, - Keyword("volatile"), - Keyword("ushort"), - Field("goo14"), - Punctuation.Semicolon, - Keyword("struct"), - Struct("SomeStruct"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("protected"), - Keyword("virtual"), - Keyword("void"), - Method("someMethod"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("public"), - Class("Goo"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("i"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("bool"), - Local("var"), - Operators.Equals, - Identifier("i"), - Keyword("is"), - Keyword("int"), - Punctuation.Semicolon, - ControlKeyword("try"), - Punctuation.OpenCurly, - ControlKeyword("while"), - Punctuation.OpenParen, - Keyword("true"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("continue"), - Punctuation.Semicolon, - ControlKeyword("break"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - ControlKeyword("switch"), - Punctuation.OpenParen, - Identifier("goo"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("case"), - Keyword("true"), - Punctuation.Colon, - ControlKeyword("break"), - Punctuation.Semicolon, - ControlKeyword("default"), - Punctuation.Colon, - ControlKeyword("break"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - ControlKeyword("catch"), - Punctuation.OpenParen, - Identifier("System"), - Operators.Dot, - Identifier("Exception"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - ControlKeyword("finally"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("checked"), - Punctuation.OpenCurly, - Keyword("int"), - Local("i2"), - Operators.Equals, - Number("10000"), - Punctuation.Semicolon, - Identifier("i2"), - Operators.PlusPlus, - Punctuation.Semicolon, - Punctuation.CloseCurly, - ControlKeyword("do"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - ControlKeyword("while"), - Punctuation.OpenParen, - Keyword("true"), - Punctuation.CloseParen, - Punctuation.Semicolon, - ControlKeyword("if"), - Punctuation.OpenParen, - Keyword("false"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - ControlKeyword("else"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("unsafe"), - Punctuation.OpenCurly, - Keyword("fixed"), - Punctuation.OpenParen, - Keyword("int"), - Operators.Asterisk, - Local("p"), - Operators.Equals, - Operators.Ampersand, - Identifier("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("char"), - Operators.Asterisk, - Local("buffer"), - Operators.Equals, - Keyword("stackalloc"), - Keyword("char"), - Punctuation.OpenBracket, - Number("16"), - Punctuation.CloseBracket, - Punctuation.Semicolon, - Punctuation.CloseCurly, - ControlKeyword("for"), - Punctuation.OpenParen, - Keyword("int"), - Local("i1"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - Identifier("i1"), - Operators.LessThan, - Number("10"), - Punctuation.Semicolon, - Identifier("i1"), - Operators.PlusPlus, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Identifier("System"), - Operators.Dot, - Identifier("Collections"), - Operators.Dot, - Identifier("ArrayList"), - Local("al"), - Operators.Equals, - Keyword("new"), - Identifier("System"), - Operators.Dot, - Identifier("Collections"), - Operators.Dot, - Identifier("ArrayList"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - ControlKeyword("foreach"), - Punctuation.OpenParen, - Keyword("object"), - Local("o"), - ControlKeyword("in"), - Identifier("al"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("object"), - Local("o1"), - Operators.Equals, - Identifier("o"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("lock"), - Punctuation.OpenParen, - Keyword("this"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Identifier("Goo"), - Method("method"), - Punctuation.OpenParen, - Identifier("Bar"), - Parameter("i"), - Punctuation.Comma, - Keyword("out"), - Keyword("int"), - Parameter("z"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Identifier("z"), - Operators.Equals, - Number("5"), - Punctuation.Semicolon, - ControlKeyword("return"), - Identifier("i"), - Keyword("as"), - Identifier("Goo"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("public"), - Keyword("static"), - Keyword("explicit"), - Keyword("operator"), - Identifier("Goo"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("i"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Keyword("new"), - Identifier("Baz"), - Punctuation.OpenParen, - Number("1"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("public"), - Keyword("static"), - Keyword("implicit"), - Keyword("operator"), - Identifier("Goo"), - Punctuation.OpenParen, - Keyword("double"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Keyword("new"), - Identifier("Baz"), - Punctuation.OpenParen, - Number("1"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("public"), - Keyword("extern"), - Keyword("void"), - Method("doSomething"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("internal"), - Keyword("void"), - Method("method2"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("if"), - Punctuation.OpenParen, - Identifier("o"), - Operators.EqualsEquals, - Keyword("null"), - Punctuation.CloseParen, - ControlKeyword("goto"), - Identifier("Output"), - Punctuation.Semicolon, - ControlKeyword("if"), - Punctuation.OpenParen, - Identifier("o"), - Keyword("is"), - Identifier("Baz"), - Punctuation.CloseParen, - ControlKeyword("return"), - Punctuation.Semicolon, - ControlKeyword("else"), - ControlKeyword("throw"), - Keyword("new"), - Identifier("System"), - Operators.Dot, - Identifier("Exception"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Label("Output"), - Punctuation.Colon, - Identifier("Console"), - Operators.Dot, - Identifier("WriteLine"), - Punctuation.OpenParen, - String(@"""Finished"""), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("sealed"), - Keyword("class"), - Class("Baz"), - Punctuation.Colon, - Identifier("Goo"), - Punctuation.OpenCurly, - Keyword("readonly"), - Keyword("int"), - Field("field"), - Punctuation.Semicolon, - Keyword("public"), - Class("Baz"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("i"), - Punctuation.CloseParen, - Punctuation.Colon, - Keyword("base"), - Punctuation.OpenParen, - Identifier("i"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("public"), - Keyword("void"), - Method("someOtherMethod"), - Punctuation.OpenParen, - Keyword("ref"), - Keyword("int"), - Parameter("i"), - Punctuation.Comma, - Identifier("System"), - Operators.Dot, - Identifier("Type"), - Parameter("c"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("int"), - Local("f"), - Operators.Equals, - Number("1"), - Punctuation.Semicolon, - Identifier("someOtherMethod"), - Punctuation.OpenParen, - Keyword("ref"), - Identifier("f"), - Punctuation.Comma, - Keyword("typeof"), - Punctuation.OpenParen, - Keyword("int"), - Punctuation.CloseParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("protected"), - Keyword("override"), - Keyword("void"), - Method("someMethod"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("unchecked"), - Punctuation.OpenCurly, - Keyword("int"), - Local("i"), - Operators.Equals, - Number("1"), - Punctuation.Semicolon, - Identifier("i"), - Operators.PlusPlus, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("private"), - Keyword("void"), - Method("method"), - Punctuation.OpenParen, - Keyword("params"), - Keyword("object"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("args"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("private"), - Keyword("string"), - Method("aMethod"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Identifier("o"), - ControlKeyword("switch"), - Punctuation.OpenCurly, - Keyword("int"), - Operators.EqualsGreaterThan, - Keyword("string"), - Operators.Dot, - Identifier("Empty"), - Punctuation.Comma, - Keyword("_"), - ControlKeyword("when"), - Keyword("true"), - Operators.EqualsGreaterThan, - ControlKeyword("throw"), - Keyword("new"), - Identifier("System"), - Operators.Dot, - Identifier("Exception"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.CloseCurly, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("interface"), - Interface("Bar"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - PPKeyword("#"), - PPKeyword("endregion"), - PPText("TaoRegion")); - } - - [Theory, CombinatorialData] - public async Task TestAllOperators(TestHost testHost) - { - await TestAsync( -@"using IO = System.IO; - -public class Goo -{ - public void method() - { - int[] a = new int[5]; - int[] var = { - 1, - 2, - 3, - 4, - 5 - }; - int i = a[i]; - Goo f = new Goo(); - f.method(); - i = i + i - i * i / i % i & i | i ^ i; - bool b = true & false | true ^ false; - b = !b; - i = ~i; - b = i < i && i > i; - int? ii = 5; - int f = true ? 1 : 0; - i++; - i--; - b = true && false || true; - i << 5; - i >> 5; - i >>> 5; - b = i == i && i != i && i <= i && i >= i; - i += 5.0; - i -= i; - i *= i; - i /= i; - i %= i; - i &= i; - i |= i; - i ^= i; - i <<= i; - i >>= i; - i >>>= i; - i ??= i; - object s = x => x + 1; - Point point; - unsafe - { - Point* p = &point; - p->x = 10; - } - - IO::BinaryReader br = null; - } -}", - testHost, - Keyword("using"), - Identifier("IO"), - Operators.Equals, - Identifier("System"), - Operators.Dot, - Identifier("IO"), - Punctuation.Semicolon, - Keyword("public"), - Keyword("class"), - Class("Goo"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Keyword("public"), - Keyword("void"), - Method("method"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Local("a"), - Operators.Equals, - Keyword("new"), - Keyword("int"), - Punctuation.OpenBracket, - Number("5"), - Punctuation.CloseBracket, - Punctuation.Semicolon, - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Local("var"), - Operators.Equals, - Punctuation.OpenCurly, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.Comma, - Number("3"), - Punctuation.Comma, - Number("4"), - Punctuation.Comma, - Number("5"), - Punctuation.CloseCurly, - Punctuation.Semicolon, - Keyword("int"), - Local("i"), - Operators.Equals, - Identifier("a"), - Punctuation.OpenBracket, - Identifier("i"), - Punctuation.CloseBracket, - Punctuation.Semicolon, - Identifier("Goo"), - Punctuation.OpenAngle, - Identifier("T"), - Punctuation.CloseAngle, - Local("f"), - Operators.Equals, - Keyword("new"), - Identifier("Goo"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Identifier("f"), - Operators.Dot, - Identifier("method"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Identifier("i"), - Operators.Equals, - Identifier("i"), - Operators.Plus, - Identifier("i"), - Operators.Minus, - Identifier("i"), - Operators.Asterisk, - Identifier("i"), - Operators.Slash, - Identifier("i"), - Operators.Percent, - Identifier("i"), - Operators.Ampersand, - Identifier("i"), - Operators.Bar, - Identifier("i"), - Operators.Caret, - Identifier("i"), - Punctuation.Semicolon, - Keyword("bool"), - Local("b"), - Operators.Equals, - Keyword("true"), - Operators.Ampersand, - Keyword("false"), - Operators.Bar, - Keyword("true"), - Operators.Caret, - Keyword("false"), - Punctuation.Semicolon, - Identifier("b"), - Operators.Equals, - Operators.Exclamation, - Identifier("b"), - Punctuation.Semicolon, - Identifier("i"), - Operators.Equals, - Operators.Tilde, - Identifier("i"), - Punctuation.Semicolon, - Identifier("b"), - Operators.Equals, - Identifier("i"), - Operators.LessThan, - Identifier("i"), - Operators.AmpersandAmpersand, - Identifier("i"), - Operators.GreaterThan, - Identifier("i"), - Punctuation.Semicolon, - Keyword("int"), - Operators.QuestionMark, - Local("ii"), - Operators.Equals, - Number("5"), - Punctuation.Semicolon, - Keyword("int"), - Local("f"), - Operators.Equals, - Keyword("true"), - Operators.QuestionMark, - Number("1"), - Operators.Colon, - Number("0"), - Punctuation.Semicolon, - Identifier("i"), - Operators.PlusPlus, - Punctuation.Semicolon, - Identifier("i"), - Operators.MinusMinus, - Punctuation.Semicolon, - Identifier("b"), - Operators.Equals, - Keyword("true"), - Operators.AmpersandAmpersand, - Keyword("false"), - Operators.BarBar, - Keyword("true"), - Punctuation.Semicolon, - Identifier("i"), - Operators.LessThanLessThan, - Number("5"), - Punctuation.Semicolon, - Identifier("i"), - Operators.GreaterThanGreaterThan, - Number("5"), - Punctuation.Semicolon, - Identifier("i"), - Operators.GreaterThanGreaterThanGreaterThan, - Number("5"), - Punctuation.Semicolon, - Identifier("b"), - Operators.Equals, - Identifier("i"), - Operators.EqualsEquals, - Identifier("i"), - Operators.AmpersandAmpersand, - Identifier("i"), - Operators.ExclamationEquals, - Identifier("i"), - Operators.AmpersandAmpersand, - Identifier("i"), - Operators.LessThanEquals, - Identifier("i"), - Operators.AmpersandAmpersand, - Identifier("i"), - Operators.GreaterThanEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.PlusEquals, - Number("5.0"), - Punctuation.Semicolon, - Identifier("i"), - Operators.MinusEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.AsteriskEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.SlashEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.PercentEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.AmpersandEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.BarEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.CaretEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.LessThanLessThanEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.GreaterThanGreaterThanEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.GreaterThanGreaterThanGreaterThanEquals, - Identifier("i"), - Punctuation.Semicolon, - Identifier("i"), - Operators.QuestionQuestionEquals, - Identifier("i"), - Punctuation.Semicolon, - Keyword("object"), - Local("s"), - Operators.Equals, - Parameter("x"), - Operators.EqualsGreaterThan, - Identifier("x"), - Operators.Plus, - Number("1"), - Punctuation.Semicolon, - Identifier("Point"), - Local("point"), - Punctuation.Semicolon, - Keyword("unsafe"), - Punctuation.OpenCurly, - Identifier("Point"), - Operators.Asterisk, - Local("p"), - Operators.Equals, - Operators.Ampersand, - Identifier("point"), - Punctuation.Semicolon, - Identifier("p"), - Operators.MinusGreaterThan, - Identifier("x"), - Operators.Equals, - Number("10"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Identifier("IO"), - Operators.ColonColon, - Identifier("BinaryReader"), - Local("br"), - Operators.Equals, - Keyword("null"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestPartialMethodWithNamePartial(TestHost testHost) - { - await TestAsync( -@"partial class C -{ - partial void partial(string bar); - - partial void partial(string baz) - { - } - - partial int Goo(); - - partial int Goo() - { - } - - public partial void partial void -}", - testHost, - Keyword("partial"), - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("partial"), - Keyword("void"), - Method("partial"), - Punctuation.OpenParen, - Keyword("string"), - Parameter("bar"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("partial"), - Keyword("void"), - Method("partial"), - Punctuation.OpenParen, - Keyword("string"), - Parameter("baz"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("partial"), - Keyword("int"), - Method("Goo"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("partial"), - Keyword("int"), - Method("Goo"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("public"), - Keyword("partial"), - Keyword("void"), - Field("partial"), - Keyword("void"), - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task ValueInSetterAndAnonymousTypePropertyName(TestHost testHost) - { - await TestAsync( -@"class C -{ - int P - { - set - { - var t = new { value = value }; - } - } -}", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("int"), - Property("P"), - Punctuation.OpenCurly, - Keyword("set"), - Punctuation.OpenCurly, - Keyword("var"), - Local("t"), - Operators.Equals, - Keyword("new"), - Punctuation.OpenCurly, - Identifier("value"), - Operators.Equals, - Identifier("value"), - Punctuation.CloseCurly, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538680")] - [CombinatorialData] - public async Task TestValueInLabel(TestHost testHost) - { - await TestAsync( -@"class C -{ - int X - { - set - { - value: - ; - } - } -}", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("int"), - Property("X"), - Punctuation.OpenCurly, - Keyword("set"), - Punctuation.OpenCurly, - Label("value"), - Punctuation.Colon, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541150")] - [CombinatorialData] - public async Task TestGenericVar(TestHost testHost) - { - await TestAsync( -@"using System; - -static class Program -{ - static void Main() - { - var x = 1; - } -} - -class var + testHost, + new[] { new CSharpParseOptions(LanguageVersion.CSharp8) }, + Keyword("using"), + Identifier("System"), + Punctuation.Semicolon, + PPKeyword("#"), + PPKeyword("region"), + PPText("TaoRegion"), + Keyword("namespace"), + Namespace("MyNamespace"), + Punctuation.OpenCurly, + Keyword("abstract"), + Keyword("class"), + Class("Goo"), + Punctuation.Colon, + Identifier("Bar"), + Punctuation.OpenCurly, + Keyword("bool"), + Field("goo"), + Operators.Equals, + Keyword("default"), + Punctuation.OpenParen, + Keyword("bool"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("byte"), + Field("goo1"), + Punctuation.Semicolon, + Keyword("char"), + Field("goo2"), + Punctuation.Semicolon, + Keyword("const"), + Keyword("int"), + Constant("goo3"), + Static("goo3"), + Operators.Equals, + Number("999"), + Punctuation.Semicolon, + Keyword("decimal"), + Field("goo4"), + Punctuation.Semicolon, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("delegate"), + Operators.Asterisk, + Keyword("managed"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.Comma, + Keyword("int"), + Punctuation.CloseAngle, + Field("mgdfun"), + Punctuation.Semicolon, + Keyword("delegate"), + Operators.Asterisk, + Keyword("unmanaged"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.Comma, + Keyword("int"), + Punctuation.CloseAngle, + Field("unmgdfun"), + Punctuation.Semicolon, + Keyword("double"), + Field("goo5"), + Punctuation.Semicolon, + Keyword("enum"), + Enum("MyEnum"), + Punctuation.OpenCurly, + EnumMember("one"), + Punctuation.Comma, + EnumMember("two"), + Punctuation.Comma, + EnumMember("three"), + Punctuation.CloseCurly, + Punctuation.Semicolon, + Keyword("event"), + Identifier("D"), + Event("MyEvent"), + Punctuation.Semicolon, + Keyword("float"), + Field("goo6"), + Punctuation.Semicolon, + Keyword("static"), + Keyword("int"), + Field("x"), + Static("x"), + Punctuation.Semicolon, + Keyword("long"), + Field("goo7"), + Punctuation.Semicolon, + Keyword("sbyte"), + Field("goo8"), + Punctuation.Semicolon, + Keyword("short"), + Field("goo9"), + Punctuation.Semicolon, + Keyword("int"), + Field("goo10"), + Operators.Equals, + Keyword("sizeof"), + Punctuation.OpenParen, + Keyword("int"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("string"), + Field("goo11"), + Punctuation.Semicolon, + Keyword("uint"), + Field("goo12"), + Punctuation.Semicolon, + Keyword("ulong"), + Field("goo13"), + Punctuation.Semicolon, + Keyword("volatile"), + Keyword("ushort"), + Field("goo14"), + Punctuation.Semicolon, + Keyword("struct"), + Struct("SomeStruct"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("protected"), + Keyword("virtual"), + Keyword("void"), + Method("someMethod"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("public"), + Class("Goo"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("i"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("bool"), + Local("var"), + Operators.Equals, + Identifier("i"), + Keyword("is"), + Keyword("int"), + Punctuation.Semicolon, + ControlKeyword("try"), + Punctuation.OpenCurly, + ControlKeyword("while"), + Punctuation.OpenParen, + Keyword("true"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("continue"), + Punctuation.Semicolon, + ControlKeyword("break"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + ControlKeyword("switch"), + Punctuation.OpenParen, + Identifier("goo"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("case"), + Keyword("true"), + Punctuation.Colon, + ControlKeyword("break"), + Punctuation.Semicolon, + ControlKeyword("default"), + Punctuation.Colon, + ControlKeyword("break"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + ControlKeyword("catch"), + Punctuation.OpenParen, + Identifier("System"), + Operators.Dot, + Identifier("Exception"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + ControlKeyword("finally"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("checked"), + Punctuation.OpenCurly, + Keyword("int"), + Local("i2"), + Operators.Equals, + Number("10000"), + Punctuation.Semicolon, + Identifier("i2"), + Operators.PlusPlus, + Punctuation.Semicolon, + Punctuation.CloseCurly, + ControlKeyword("do"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + ControlKeyword("while"), + Punctuation.OpenParen, + Keyword("true"), + Punctuation.CloseParen, + Punctuation.Semicolon, + ControlKeyword("if"), + Punctuation.OpenParen, + Keyword("false"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + ControlKeyword("else"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("unsafe"), + Punctuation.OpenCurly, + Keyword("fixed"), + Punctuation.OpenParen, + Keyword("int"), + Operators.Asterisk, + Local("p"), + Operators.Equals, + Operators.Ampersand, + Identifier("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("char"), + Operators.Asterisk, + Local("buffer"), + Operators.Equals, + Keyword("stackalloc"), + Keyword("char"), + Punctuation.OpenBracket, + Number("16"), + Punctuation.CloseBracket, + Punctuation.Semicolon, + Punctuation.CloseCurly, + ControlKeyword("for"), + Punctuation.OpenParen, + Keyword("int"), + Local("i1"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + Identifier("i1"), + Operators.LessThan, + Number("10"), + Punctuation.Semicolon, + Identifier("i1"), + Operators.PlusPlus, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Identifier("System"), + Operators.Dot, + Identifier("Collections"), + Operators.Dot, + Identifier("ArrayList"), + Local("al"), + Operators.Equals, + Keyword("new"), + Identifier("System"), + Operators.Dot, + Identifier("Collections"), + Operators.Dot, + Identifier("ArrayList"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + ControlKeyword("foreach"), + Punctuation.OpenParen, + Keyword("object"), + Local("o"), + ControlKeyword("in"), + Identifier("al"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("object"), + Local("o1"), + Operators.Equals, + Identifier("o"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("lock"), + Punctuation.OpenParen, + Keyword("this"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Identifier("Goo"), + Method("method"), + Punctuation.OpenParen, + Identifier("Bar"), + Parameter("i"), + Punctuation.Comma, + Keyword("out"), + Keyword("int"), + Parameter("z"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Identifier("z"), + Operators.Equals, + Number("5"), + Punctuation.Semicolon, + ControlKeyword("return"), + Identifier("i"), + Keyword("as"), + Identifier("Goo"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("public"), + Keyword("static"), + Keyword("explicit"), + Keyword("operator"), + Identifier("Goo"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("i"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("return"), + Keyword("new"), + Identifier("Baz"), + Punctuation.OpenParen, + Number("1"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("public"), + Keyword("static"), + Keyword("implicit"), + Keyword("operator"), + Identifier("Goo"), + Punctuation.OpenParen, + Keyword("double"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("return"), + Keyword("new"), + Identifier("Baz"), + Punctuation.OpenParen, + Number("1"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("public"), + Keyword("extern"), + Keyword("void"), + Method("doSomething"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("internal"), + Keyword("void"), + Method("method2"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("if"), + Punctuation.OpenParen, + Identifier("o"), + Operators.EqualsEquals, + Keyword("null"), + Punctuation.CloseParen, + ControlKeyword("goto"), + Identifier("Output"), + Punctuation.Semicolon, + ControlKeyword("if"), + Punctuation.OpenParen, + Identifier("o"), + Keyword("is"), + Identifier("Baz"), + Punctuation.CloseParen, + ControlKeyword("return"), + Punctuation.Semicolon, + ControlKeyword("else"), + ControlKeyword("throw"), + Keyword("new"), + Identifier("System"), + Operators.Dot, + Identifier("Exception"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Label("Output"), + Punctuation.Colon, + Identifier("Console"), + Operators.Dot, + Identifier("WriteLine"), + Punctuation.OpenParen, + String(@"""Finished"""), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("sealed"), + Keyword("class"), + Class("Baz"), + Punctuation.Colon, + Identifier("Goo"), + Punctuation.OpenCurly, + Keyword("readonly"), + Keyword("int"), + Field("field"), + Punctuation.Semicolon, + Keyword("public"), + Class("Baz"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("i"), + Punctuation.CloseParen, + Punctuation.Colon, + Keyword("base"), + Punctuation.OpenParen, + Identifier("i"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("public"), + Keyword("void"), + Method("someOtherMethod"), + Punctuation.OpenParen, + Keyword("ref"), + Keyword("int"), + Parameter("i"), + Punctuation.Comma, + Identifier("System"), + Operators.Dot, + Identifier("Type"), + Parameter("c"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("int"), + Local("f"), + Operators.Equals, + Number("1"), + Punctuation.Semicolon, + Identifier("someOtherMethod"), + Punctuation.OpenParen, + Keyword("ref"), + Identifier("f"), + Punctuation.Comma, + Keyword("typeof"), + Punctuation.OpenParen, + Keyword("int"), + Punctuation.CloseParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("protected"), + Keyword("override"), + Keyword("void"), + Method("someMethod"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("unchecked"), + Punctuation.OpenCurly, + Keyword("int"), + Local("i"), + Operators.Equals, + Number("1"), + Punctuation.Semicolon, + Identifier("i"), + Operators.PlusPlus, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("private"), + Keyword("void"), + Method("method"), + Punctuation.OpenParen, + Keyword("params"), + Keyword("object"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("args"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("private"), + Keyword("string"), + Method("aMethod"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Identifier("o"), + ControlKeyword("switch"), + Punctuation.OpenCurly, + Keyword("int"), + Operators.EqualsGreaterThan, + Keyword("string"), + Operators.Dot, + Identifier("Empty"), + Punctuation.Comma, + Keyword("_"), + ControlKeyword("when"), + Keyword("true"), + Operators.EqualsGreaterThan, + ControlKeyword("throw"), + Keyword("new"), + Identifier("System"), + Operators.Dot, + Identifier("Exception"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.CloseCurly, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("interface"), + Interface("Bar"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + PPKeyword("#"), + PPKeyword("endregion"), + PPText("TaoRegion")); + } + + [Theory, CombinatorialData] + public async Task TestAllOperators(TestHost testHost) + { + await TestAsync( +@"using IO = System.IO; + +public class Goo +{ + public void method() + { + int[] a = new int[5]; + int[] var = { + 1, + 2, + 3, + 4, + 5 + }; + int i = a[i]; + Goo f = new Goo(); + f.method(); + i = i + i - i * i / i % i & i | i ^ i; + bool b = true & false | true ^ false; + b = !b; + i = ~i; + b = i < i && i > i; + int? ii = 5; + int f = true ? 1 : 0; + i++; + i--; + b = true && false || true; + i << 5; + i >> 5; + i >>> 5; + b = i == i && i != i && i <= i && i >= i; + i += 5.0; + i -= i; + i *= i; + i /= i; + i %= i; + i &= i; + i |= i; + i ^= i; + i <<= i; + i >>= i; + i >>>= i; + i ??= i; + object s = x => x + 1; + Point point; + unsafe + { + Point* p = &point; + p->x = 10; + } + + IO::BinaryReader br = null; + } +}", + testHost, + Keyword("using"), + Identifier("IO"), + Operators.Equals, + Identifier("System"), + Operators.Dot, + Identifier("IO"), + Punctuation.Semicolon, + Keyword("public"), + Keyword("class"), + Class("Goo"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Keyword("public"), + Keyword("void"), + Method("method"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Local("a"), + Operators.Equals, + Keyword("new"), + Keyword("int"), + Punctuation.OpenBracket, + Number("5"), + Punctuation.CloseBracket, + Punctuation.Semicolon, + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Local("var"), + Operators.Equals, + Punctuation.OpenCurly, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.Comma, + Number("3"), + Punctuation.Comma, + Number("4"), + Punctuation.Comma, + Number("5"), + Punctuation.CloseCurly, + Punctuation.Semicolon, + Keyword("int"), + Local("i"), + Operators.Equals, + Identifier("a"), + Punctuation.OpenBracket, + Identifier("i"), + Punctuation.CloseBracket, + Punctuation.Semicolon, + Identifier("Goo"), + Punctuation.OpenAngle, + Identifier("T"), + Punctuation.CloseAngle, + Local("f"), + Operators.Equals, + Keyword("new"), + Identifier("Goo"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Identifier("f"), + Operators.Dot, + Identifier("method"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Identifier("i"), + Operators.Equals, + Identifier("i"), + Operators.Plus, + Identifier("i"), + Operators.Minus, + Identifier("i"), + Operators.Asterisk, + Identifier("i"), + Operators.Slash, + Identifier("i"), + Operators.Percent, + Identifier("i"), + Operators.Ampersand, + Identifier("i"), + Operators.Bar, + Identifier("i"), + Operators.Caret, + Identifier("i"), + Punctuation.Semicolon, + Keyword("bool"), + Local("b"), + Operators.Equals, + Keyword("true"), + Operators.Ampersand, + Keyword("false"), + Operators.Bar, + Keyword("true"), + Operators.Caret, + Keyword("false"), + Punctuation.Semicolon, + Identifier("b"), + Operators.Equals, + Operators.Exclamation, + Identifier("b"), + Punctuation.Semicolon, + Identifier("i"), + Operators.Equals, + Operators.Tilde, + Identifier("i"), + Punctuation.Semicolon, + Identifier("b"), + Operators.Equals, + Identifier("i"), + Operators.LessThan, + Identifier("i"), + Operators.AmpersandAmpersand, + Identifier("i"), + Operators.GreaterThan, + Identifier("i"), + Punctuation.Semicolon, + Keyword("int"), + Operators.QuestionMark, + Local("ii"), + Operators.Equals, + Number("5"), + Punctuation.Semicolon, + Keyword("int"), + Local("f"), + Operators.Equals, + Keyword("true"), + Operators.QuestionMark, + Number("1"), + Operators.Colon, + Number("0"), + Punctuation.Semicolon, + Identifier("i"), + Operators.PlusPlus, + Punctuation.Semicolon, + Identifier("i"), + Operators.MinusMinus, + Punctuation.Semicolon, + Identifier("b"), + Operators.Equals, + Keyword("true"), + Operators.AmpersandAmpersand, + Keyword("false"), + Operators.BarBar, + Keyword("true"), + Punctuation.Semicolon, + Identifier("i"), + Operators.LessThanLessThan, + Number("5"), + Punctuation.Semicolon, + Identifier("i"), + Operators.GreaterThanGreaterThan, + Number("5"), + Punctuation.Semicolon, + Identifier("i"), + Operators.GreaterThanGreaterThanGreaterThan, + Number("5"), + Punctuation.Semicolon, + Identifier("b"), + Operators.Equals, + Identifier("i"), + Operators.EqualsEquals, + Identifier("i"), + Operators.AmpersandAmpersand, + Identifier("i"), + Operators.ExclamationEquals, + Identifier("i"), + Operators.AmpersandAmpersand, + Identifier("i"), + Operators.LessThanEquals, + Identifier("i"), + Operators.AmpersandAmpersand, + Identifier("i"), + Operators.GreaterThanEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.PlusEquals, + Number("5.0"), + Punctuation.Semicolon, + Identifier("i"), + Operators.MinusEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.AsteriskEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.SlashEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.PercentEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.AmpersandEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.BarEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.CaretEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.LessThanLessThanEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.GreaterThanGreaterThanEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.GreaterThanGreaterThanGreaterThanEquals, + Identifier("i"), + Punctuation.Semicolon, + Identifier("i"), + Operators.QuestionQuestionEquals, + Identifier("i"), + Punctuation.Semicolon, + Keyword("object"), + Local("s"), + Operators.Equals, + Parameter("x"), + Operators.EqualsGreaterThan, + Identifier("x"), + Operators.Plus, + Number("1"), + Punctuation.Semicolon, + Identifier("Point"), + Local("point"), + Punctuation.Semicolon, + Keyword("unsafe"), + Punctuation.OpenCurly, + Identifier("Point"), + Operators.Asterisk, + Local("p"), + Operators.Equals, + Operators.Ampersand, + Identifier("point"), + Punctuation.Semicolon, + Identifier("p"), + Operators.MinusGreaterThan, + Identifier("x"), + Operators.Equals, + Number("10"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Identifier("IO"), + Operators.ColonColon, + Identifier("BinaryReader"), + Local("br"), + Operators.Equals, + Keyword("null"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestPartialMethodWithNamePartial(TestHost testHost) + { + await TestAsync( +@"partial class C { + partial void partial(string bar); + + partial void partial(string baz) + { + } + + partial int Goo(); + + partial int Goo() + { + } + + public partial void partial void }", - testHost, - Keyword("using"), - Identifier("System"), - Punctuation.Semicolon, - Keyword("static"), - Keyword("class"), - Class("Program"), - Static("Program"), - Punctuation.OpenCurly, - Keyword("static"), - Keyword("void"), - Method("Main"), - Static("Main"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("x"), - Operators.Equals, - Number("1"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("var"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); + testHost, + Keyword("partial"), + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("partial"), + Keyword("void"), + Method("partial"), + Punctuation.OpenParen, + Keyword("string"), + Parameter("bar"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("partial"), + Keyword("void"), + Method("partial"), + Punctuation.OpenParen, + Keyword("string"), + Parameter("baz"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("partial"), + Keyword("int"), + Method("Goo"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("partial"), + Keyword("int"), + Method("Goo"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("public"), + Keyword("partial"), + Keyword("void"), + Field("partial"), + Keyword("void"), + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task ValueInSetterAndAnonymousTypePropertyName(TestHost testHost) + { + await TestAsync( +@"class C +{ + int P + { + set + { + var t = new { value = value }; + } + } +}", + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("int"), + Property("P"), + Punctuation.OpenCurly, + Keyword("set"), + Punctuation.OpenCurly, + Keyword("var"), + Local("t"), + Operators.Equals, + Keyword("new"), + Punctuation.OpenCurly, + Identifier("value"), + Operators.Equals, + Identifier("value"), + Punctuation.CloseCurly, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538680")] + [CombinatorialData] + public async Task TestValueInLabel(TestHost testHost) + { + await TestAsync( +@"class C +{ + int X + { + set + { + value: + ; } + } +}", + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("int"), + Property("X"), + Punctuation.OpenCurly, + Keyword("set"), + Punctuation.OpenCurly, + Label("value"), + Punctuation.Colon, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541150")] + [CombinatorialData] + public async Task TestGenericVar(TestHost testHost) + { + await TestAsync( +@"using System; + +static class Program +{ + static void Main() + { + var x = 1; + } +} + +class var +{ +}", + testHost, + Keyword("using"), + Identifier("System"), + Punctuation.Semicolon, + Keyword("static"), + Keyword("class"), + Class("Program"), + Static("Program"), + Punctuation.OpenCurly, + Keyword("static"), + Keyword("void"), + Method("Main"), + Static("Main"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("x"), + Operators.Equals, + Number("1"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("var"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541154")] - [CombinatorialData] - public async Task TestInaccessibleVar(TestHost testHost) - { - await TestAsync( + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541154")] + [CombinatorialData] + public async Task TestInaccessibleVar(TestHost testHost) + { + await TestAsync( @"using System; class A @@ -3920,45 +3920,45 @@ static void Main() var x = 1; } }", - testHost, - Keyword("using"), - Identifier("System"), - Punctuation.Semicolon, - Keyword("class"), - Class("A"), - Punctuation.OpenCurly, - Keyword("private"), - Keyword("class"), - Class("var"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("B"), - Punctuation.Colon, - Identifier("A"), - Punctuation.OpenCurly, - Keyword("static"), - Keyword("void"), - Method("Main"), - Static("Main"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("x"), - Operators.Equals, - Number("1"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("using"), + Identifier("System"), + Punctuation.Semicolon, + Keyword("class"), + Class("A"), + Punctuation.OpenCurly, + Keyword("private"), + Keyword("class"), + Class("var"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("B"), + Punctuation.Colon, + Identifier("A"), + Punctuation.OpenCurly, + Keyword("static"), + Keyword("void"), + Method("Main"), + Static("Main"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("x"), + Operators.Equals, + Number("1"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541613")] - [CombinatorialData] - public async Task TestEscapedVar(TestHost testHost) - { - await TestAsync( + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541613")] + [CombinatorialData] + public async Task TestEscapedVar(TestHost testHost) + { + await TestAsync( @"class Program { static void Main(string[] args) @@ -3966,35 +3966,35 @@ static void Main(string[] args) @var v = 1; } }", - testHost, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("static"), - Keyword("void"), - Method("Main"), - Static("Main"), - Punctuation.OpenParen, - Keyword("string"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("args"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Identifier("@var"), - Local("v"), - Operators.Equals, - Number("1"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("static"), + Keyword("void"), + Method("Main"), + Static("Main"), + Punctuation.OpenParen, + Keyword("string"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("args"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Identifier("@var"), + Local("v"), + Operators.Equals, + Number("1"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542432")] - [CombinatorialData] - public async Task TestVar(TestHost testHost) - { - await TestAsync( + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542432")] + [CombinatorialData] + public async Task TestVar(TestHost testHost) + { + await TestAsync( @"class Program { class var @@ -4012,65 +4012,65 @@ static void Main() var y = new var(); } }", - testHost, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("class"), - Class("var"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("static"), - Identifier("var"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Method("GetVarT"), - Static("GetVarT"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Keyword("null"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("static"), - Keyword("void"), - Method("Main"), - Static("Main"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("x"), - Operators.Equals, - Identifier("GetVarT"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("var"), - Local("y"), - Operators.Equals, - Keyword("new"), - Identifier("var"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("class"), + Class("var"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("static"), + Identifier("var"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Method("GetVarT"), + Static("GetVarT"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("return"), + Keyword("null"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("static"), + Keyword("void"), + Method("Main"), + Static("Main"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("x"), + Operators.Equals, + Identifier("GetVarT"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("var"), + Local("y"), + Operators.Equals, + Keyword("new"), + Identifier("var"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543123")] - [CombinatorialData] - public async Task TestVar2(TestHost testHost) - { - await TestAsync( + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543123")] + [CombinatorialData] + public async Task TestVar2(TestHost testHost) + { + await TestAsync( @"class Program { void Main(string[] args) @@ -4080,132 +4080,132 @@ void Main(string[] args) } } }", - testHost, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Main"), - Punctuation.OpenParen, - Keyword("string"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("args"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("foreach"), - Punctuation.OpenParen, - Identifier("var"), - Local("v"), - ControlKeyword("in"), - Identifier("args"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Main"), + Punctuation.OpenParen, + Keyword("string"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("args"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("foreach"), + Punctuation.OpenParen, + Identifier("var"), + Local("v"), + ControlKeyword("in"), + Identifier("args"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task InterpolatedStrings1(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task InterpolatedStrings1(TestHost testHost) + { + var code = @" var x = ""World""; var y = $""Hello, {x}""; "; - await TestInMethodAsync(code, - testHost, - Keyword("var"), - Local("x"), - Operators.Equals, - String("\"World\""), - Punctuation.Semicolon, - Keyword("var"), - Local("y"), - Operators.Equals, - String("$\""), - String("Hello, "), - Punctuation.OpenCurly, - Identifier("x"), - Punctuation.CloseCurly, - String("\""), - Punctuation.Semicolon); - } + await TestInMethodAsync(code, + testHost, + Keyword("var"), + Local("x"), + Operators.Equals, + String("\"World\""), + Punctuation.Semicolon, + Keyword("var"), + Local("y"), + Operators.Equals, + String("$\""), + String("Hello, "), + Punctuation.OpenCurly, + Identifier("x"), + Punctuation.CloseCurly, + String("\""), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task InterpolatedStrings2(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task InterpolatedStrings2(TestHost testHost) + { + var code = @" var a = ""Hello""; var b = ""World""; var c = $""{a}, {b}""; "; - await TestInMethodAsync(code, - testHost, - Keyword("var"), - Local("a"), - Operators.Equals, - String("\"Hello\""), - Punctuation.Semicolon, - Keyword("var"), - Local("b"), - Operators.Equals, - String("\"World\""), - Punctuation.Semicolon, - Keyword("var"), - Local("c"), - Operators.Equals, - String("$\""), - Punctuation.OpenCurly, - Identifier("a"), - Punctuation.CloseCurly, - String(", "), - Punctuation.OpenCurly, - Identifier("b"), - Punctuation.CloseCurly, - String("\""), - Punctuation.Semicolon); - } + await TestInMethodAsync(code, + testHost, + Keyword("var"), + Local("a"), + Operators.Equals, + String("\"Hello\""), + Punctuation.Semicolon, + Keyword("var"), + Local("b"), + Operators.Equals, + String("\"World\""), + Punctuation.Semicolon, + Keyword("var"), + Local("c"), + Operators.Equals, + String("$\""), + Punctuation.OpenCurly, + Identifier("a"), + Punctuation.CloseCurly, + String(", "), + Punctuation.OpenCurly, + Identifier("b"), + Punctuation.CloseCurly, + String("\""), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task InterpolatedStrings3(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task InterpolatedStrings3(TestHost testHost) + { + var code = @" var a = ""Hello""; var b = ""World""; var c = $@""{a}, {b}""; "; - await TestInMethodAsync(code, - testHost, - Keyword("var"), - Local("a"), - Operators.Equals, - String("\"Hello\""), - Punctuation.Semicolon, - Keyword("var"), - Local("b"), - Operators.Equals, - String("\"World\""), - Punctuation.Semicolon, - Keyword("var"), - Local("c"), - Operators.Equals, - Verbatim("$@\""), - Punctuation.OpenCurly, - Identifier("a"), - Punctuation.CloseCurly, - Verbatim(", "), - Punctuation.OpenCurly, - Identifier("b"), - Punctuation.CloseCurly, - Verbatim("\""), - Punctuation.Semicolon); - } + await TestInMethodAsync(code, + testHost, + Keyword("var"), + Local("a"), + Operators.Equals, + String("\"Hello\""), + Punctuation.Semicolon, + Keyword("var"), + Local("b"), + Operators.Equals, + String("\"World\""), + Punctuation.Semicolon, + Keyword("var"), + Local("c"), + Operators.Equals, + Verbatim("$@\""), + Punctuation.OpenCurly, + Identifier("a"), + Punctuation.CloseCurly, + Verbatim(", "), + Punctuation.OpenCurly, + Identifier("b"), + Punctuation.CloseCurly, + Verbatim("\""), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task ExceptionFilter1(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task ExceptionFilter1(TestHost testHost) + { + var code = @" try { } @@ -4213,24 +4213,24 @@ public async Task ExceptionFilter1(TestHost testHost) { } "; - await TestInMethodAsync(code, - testHost, - ControlKeyword("try"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - ControlKeyword("catch"), - ControlKeyword("when"), - Punctuation.OpenParen, - Keyword("true"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestInMethodAsync(code, + testHost, + ControlKeyword("try"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + ControlKeyword("catch"), + ControlKeyword("when"), + Punctuation.OpenParen, + Keyword("true"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task ExceptionFilter2(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task ExceptionFilter2(TestHost testHost) + { + var code = @" try { } @@ -4238,179 +4238,179 @@ public async Task ExceptionFilter2(TestHost testHost) { } "; - await TestInMethodAsync(code, - testHost, - ControlKeyword("try"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - ControlKeyword("catch"), - Punctuation.OpenParen, - Identifier("System"), - Operators.Dot, - Identifier("Exception"), - Punctuation.CloseParen, - ControlKeyword("when"), - Punctuation.OpenParen, - Keyword("true"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + await TestInMethodAsync(code, + testHost, + ControlKeyword("try"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + ControlKeyword("catch"), + Punctuation.OpenParen, + Identifier("System"), + Operators.Dot, + Identifier("Exception"), + Punctuation.CloseParen, + ControlKeyword("when"), + Punctuation.OpenParen, + Keyword("true"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task OutVar(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task OutVar(TestHost testHost) + { + var code = @" F(out var);"; - await TestInMethodAsync(code, - testHost, - Identifier("F"), - Punctuation.OpenParen, - Keyword("out"), - Identifier("var"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } + await TestInMethodAsync(code, + testHost, + Identifier("F"), + Punctuation.OpenParen, + Keyword("out"), + Identifier("var"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task ReferenceDirective(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task ReferenceDirective(TestHost testHost) + { + var code = @" #r ""file.dll"""; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("r"), - String("\"file.dll\"")); - } + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("r"), + String("\"file.dll\"")); + } - [Theory, CombinatorialData] - public async Task LoadDirective(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task LoadDirective(TestHost testHost) + { + var code = @" #load ""file.csx"""; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("load"), - String("\"file.csx\"")); - } + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("load"), + String("\"file.csx\"")); + } - [Theory, CombinatorialData] - public async Task IncompleteAwaitInNonAsyncContext(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task IncompleteAwaitInNonAsyncContext(TestHost testHost) + { + var code = @" void M() { var x = await }"; - await TestInClassAsync(code, - testHost, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("x"), - Operators.Equals, - Keyword("await"), - Punctuation.CloseCurly); - } + await TestInClassAsync(code, + testHost, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("x"), + Operators.Equals, + Keyword("await"), + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CompleteAwaitInNonAsyncContext(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task CompleteAwaitInNonAsyncContext(TestHost testHost) + { + var code = @" void M() { var x = await; }"; - await TestInClassAsync(code, - testHost, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("x"), - Operators.Equals, - Identifier("await"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + await TestInClassAsync(code, + testHost, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("x"), + Operators.Equals, + Identifier("await"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TupleDeclaration(TestHost testHost) - { - await TestInMethodAsync("(int, string) x", - testHost, - ParseOptions(TestOptions.Regular, Options.Script), - Punctuation.OpenParen, - Keyword("int"), - Punctuation.Comma, - Keyword("string"), - Punctuation.CloseParen, - Local("x")); - } + [Theory, CombinatorialData] + public async Task TupleDeclaration(TestHost testHost) + { + await TestInMethodAsync("(int, string) x", + testHost, + ParseOptions(TestOptions.Regular, Options.Script), + Punctuation.OpenParen, + Keyword("int"), + Punctuation.Comma, + Keyword("string"), + Punctuation.CloseParen, + Local("x")); + } - [Theory, CombinatorialData] - public async Task TupleDeclarationWithNames(TestHost testHost) - { - await TestInMethodAsync("(int a, string b) x", - testHost, - ParseOptions(TestOptions.Regular, Options.Script), - Punctuation.OpenParen, - Keyword("int"), - Identifier("a"), - Punctuation.Comma, - Keyword("string"), - Identifier("b"), - Punctuation.CloseParen, - Local("x")); - } + [Theory, CombinatorialData] + public async Task TupleDeclarationWithNames(TestHost testHost) + { + await TestInMethodAsync("(int a, string b) x", + testHost, + ParseOptions(TestOptions.Regular, Options.Script), + Punctuation.OpenParen, + Keyword("int"), + Identifier("a"), + Punctuation.Comma, + Keyword("string"), + Identifier("b"), + Punctuation.CloseParen, + Local("x")); + } - [Theory, CombinatorialData] - public async Task TupleLiteral(TestHost testHost) - { - await TestInMethodAsync("var values = (1, 2)", - testHost, - ParseOptions(TestOptions.Regular, Options.Script), - Keyword("var"), - Local("values"), - Operators.Equals, - Punctuation.OpenParen, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.CloseParen); - } + [Theory, CombinatorialData] + public async Task TupleLiteral(TestHost testHost) + { + await TestInMethodAsync("var values = (1, 2)", + testHost, + ParseOptions(TestOptions.Regular, Options.Script), + Keyword("var"), + Local("values"), + Operators.Equals, + Punctuation.OpenParen, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.CloseParen); + } - [Theory, CombinatorialData] - public async Task TupleLiteralWithNames(TestHost testHost) - { - await TestInMethodAsync("var values = (a: 1, b: 2)", - testHost, - ParseOptions(TestOptions.Regular, Options.Script), - Keyword("var"), - Local("values"), - Operators.Equals, - Punctuation.OpenParen, - Identifier("a"), - Punctuation.Colon, - Number("1"), - Punctuation.Comma, - Identifier("b"), - Punctuation.Colon, - Number("2"), - Punctuation.CloseParen); - } + [Theory, CombinatorialData] + public async Task TupleLiteralWithNames(TestHost testHost) + { + await TestInMethodAsync("var values = (a: 1, b: 2)", + testHost, + ParseOptions(TestOptions.Regular, Options.Script), + Keyword("var"), + Local("values"), + Operators.Equals, + Punctuation.OpenParen, + Identifier("a"), + Punctuation.Colon, + Number("1"), + Punctuation.Comma, + Identifier("b"), + Punctuation.Colon, + Number("2"), + Punctuation.CloseParen); + } - [Theory, CombinatorialData] - public async Task TestConflictMarkers1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestConflictMarkers1(TestHost testHost) + { + await TestAsync( @"class C { <<<<<<< Start @@ -4419,32 +4419,32 @@ await TestAsync( public void Bar(); >>>>>>> End }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Comment("<<<<<<< Start"), - Keyword("public"), - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Comment("======="), - Keyword("public"), - Keyword("void"), - Identifier("Bar"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Comment(">>>>>>> End"), - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Comment("<<<<<<< Start"), + Keyword("public"), + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Comment("======="), + Keyword("public"), + Keyword("void"), + Identifier("Bar"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Comment(">>>>>>> End"), + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestConflictMarkers2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestConflictMarkers2(TestHost testHost) + { + await TestAsync( @"class C { <<<<<<< Start @@ -4455,188 +4455,188 @@ await TestAsync( public void Bar(); >>>>>>> End }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Comment("<<<<<<< Start"), - Keyword("public"), - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Comment("||||||| Baseline"), - Keyword("int"), - Identifier("removed"), - Punctuation.Semicolon, - Comment("======="), - Keyword("public"), - Keyword("void"), - Identifier("Bar"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Comment(">>>>>>> End"), - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Comment("<<<<<<< Start"), + Keyword("public"), + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Comment("||||||| Baseline"), + Keyword("int"), + Identifier("removed"), + Punctuation.Semicolon, + Comment("======="), + Keyword("public"), + Keyword("void"), + Identifier("Bar"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Comment(">>>>>>> End"), + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_InsideMethod(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_InsideMethod(TestHost testHost) + { + await TestInMethodAsync(@" var unmanaged = 0; unmanaged++;", - testHost, - Keyword("var"), - Local("unmanaged"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - Identifier("unmanaged"), - Operators.PlusPlus, - Punctuation.Semicolon); - } + testHost, + Keyword("var"), + Local("unmanaged"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + Identifier("unmanaged"), + Operators.PlusPlus, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_Keyword(TestHost testHost) - { - await TestAsync( - "class X where T : unmanaged { }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_Keyword(TestHost testHost) + { + await TestAsync( + "class X where T : unmanaged { }", + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface unmanaged {} class X where T : unmanaged { }", - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface unmanaged {} } class X where T : unmanaged { }", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_Keyword(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_Keyword(TestHost testHost) + { + await TestAsync(@" class X { void M() where T : unmanaged { } }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface unmanaged {} class X { void M() where T : unmanaged { } }", - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface unmanaged {} @@ -4645,118 +4645,118 @@ class X { void M() where T : unmanaged { } }", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_Keyword(TestHost testHost) - { - await TestAsync( - "delegate void D() where T : unmanaged;", - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.Semicolon); - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_Keyword(TestHost testHost) + { + await TestAsync( + "delegate void D() where T : unmanaged;", + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface unmanaged {} delegate void D() where T : unmanaged;", - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.Semicolon); - } + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface unmanaged {} } delegate void D() where T : unmanaged;", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.Semicolon); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_Keyword(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_Keyword(TestHost testHost) + { + await TestAsync(@" class X { void N() @@ -4764,36 +4764,36 @@ void N() void M() where T : unmanaged { } } }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface unmanaged {} class X { @@ -4802,40 +4802,40 @@ void N() void M() where T : unmanaged { } } }", - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface unmanaged {} @@ -4847,68 +4847,68 @@ void N() void M() where T : unmanaged { } } }", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestDeclarationIsPattern(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + public async Task TestDeclarationIsPattern(TestHost testHost) + { + await TestInMethodAsync(@" object foo; if (foo is Action action) { }", - testHost, - Keyword("object"), - Local("foo"), - Punctuation.Semicolon, - ControlKeyword("if"), - Punctuation.OpenParen, - Identifier("foo"), - Keyword("is"), - Identifier("Action"), - Local("action"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("object"), + Local("foo"), + Punctuation.Semicolon, + ControlKeyword("if"), + Punctuation.OpenParen, + Identifier("foo"), + Keyword("is"), + Identifier("Action"), + Local("action"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestDeclarationSwitchPattern(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + public async Task TestDeclarationSwitchPattern(TestHost testHost) + { + await TestInMethodAsync(@" object y; switch (y) @@ -4917,478 +4917,478 @@ await TestInMethodAsync(@" break; }", testHost, - Keyword("object"), - Local("y"), - Punctuation.Semicolon, - ControlKeyword("switch"), - Punctuation.OpenParen, - Identifier("y"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("case"), - Keyword("int"), - Local("x"), - Punctuation.Colon, - ControlKeyword("break"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestDeclarationExpression(TestHost testHost) - { - await TestInMethodAsync(@" -int (foo, bar) = (1, 2);", - testHost, - Keyword("int"), - Punctuation.OpenParen, - Local("foo"), - Punctuation.Comma, - Local("bar"), - Punctuation.CloseParen, - Operators.Equals, - Punctuation.OpenParen, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/18956")] - public async Task TestListPattern(TestHost testHost) - { - await TestInMethodAsync(@" -switch (new int[0]) -{ - case [1, 2]: - break; - case [1, .. var end]: - break; -}", - testHost, + Keyword("object"), + Local("y"), + Punctuation.Semicolon, ControlKeyword("switch"), Punctuation.OpenParen, - Keyword("new"), - Keyword("int"), - Punctuation.OpenBracket, - Number("0"), - Punctuation.CloseBracket, + Identifier("y"), Punctuation.CloseParen, Punctuation.OpenCurly, ControlKeyword("case"), - Punctuation.OpenBracket, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.CloseBracket, - Punctuation.Colon, - ControlKeyword("break"), - Punctuation.Semicolon, - ControlKeyword("case"), - Punctuation.OpenBracket, - Number("1"), - Punctuation.Comma, - Punctuation.DotDot, - Keyword("var"), - Local("end"), - Punctuation.CloseBracket, + Keyword("int"), + Local("x"), Punctuation.Colon, ControlKeyword("break"), Punctuation.Semicolon, Punctuation.CloseCurly); - } + } + + [Theory, CombinatorialData] + public async Task TestDeclarationExpression(TestHost testHost) + { + await TestInMethodAsync(@" +int (foo, bar) = (1, 2);", + testHost, + Keyword("int"), + Punctuation.OpenParen, + Local("foo"), + Punctuation.Comma, + Local("bar"), + Punctuation.CloseParen, + Operators.Equals, + Punctuation.OpenParen, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/18956")] - public async Task TestListPattern2(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/18956")] + public async Task TestListPattern(TestHost testHost) + { + await TestInMethodAsync(@" +switch (new int[0]) +{ + case [1, 2]: + break; + case [1, .. var end]: + break; +}", + testHost, + ControlKeyword("switch"), + Punctuation.OpenParen, + Keyword("new"), + Keyword("int"), + Punctuation.OpenBracket, + Number("0"), + Punctuation.CloseBracket, + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("case"), + Punctuation.OpenBracket, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.CloseBracket, + Punctuation.Colon, + ControlKeyword("break"), + Punctuation.Semicolon, + ControlKeyword("case"), + Punctuation.OpenBracket, + Number("1"), + Punctuation.Comma, + Punctuation.DotDot, + Keyword("var"), + Local("end"), + Punctuation.CloseBracket, + Punctuation.Colon, + ControlKeyword("break"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/18956")] + public async Task TestListPattern2(TestHost testHost) + { + await TestInMethodAsync(@" _ = x switch { [var start, .. var end] => 1 }", - testHost, - Identifier("_"), - Operators.Equals, - Identifier("x"), - ControlKeyword("switch"), - Punctuation.OpenCurly, - Punctuation.OpenBracket, - Keyword("var"), - Local("start"), - Punctuation.Comma, - Punctuation.DotDot, - Keyword("var"), - Local("end"), - Punctuation.CloseBracket, - Operators.EqualsGreaterThan, - Number("1"), - Punctuation.CloseCurly); - } + testHost, + Identifier("_"), + Operators.Equals, + Identifier("x"), + ControlKeyword("switch"), + Punctuation.OpenCurly, + Punctuation.OpenBracket, + Keyword("var"), + Local("start"), + Punctuation.Comma, + Punctuation.DotDot, + Keyword("var"), + Local("end"), + Punctuation.CloseBracket, + Operators.EqualsGreaterThan, + Number("1"), + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/18956")] - public async Task TestVarPattern(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/18956")] + public async Task TestVarPattern(TestHost testHost) + { + await TestInMethodAsync(@" _ = 1 is var x; ", - testHost, - Identifier("_"), - Operators.Equals, - Number("1"), - Keyword("is"), - Keyword("var"), - Local("x"), - Punctuation.Semicolon); - } + testHost, + Identifier("_"), + Operators.Equals, + Number("1"), + Keyword("is"), + Keyword("var"), + Local("x"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestTupleTypeSyntax(TestHost testHost) - { - await TestInClassAsync(@" + [Theory, CombinatorialData] + public async Task TestTupleTypeSyntax(TestHost testHost) + { + await TestInClassAsync(@" public (int a, int b) Get() => null;", - testHost, - Keyword("public"), - Punctuation.OpenParen, - Keyword("int"), - Identifier("a"), - Punctuation.Comma, - Keyword("int"), - Identifier("b"), - Punctuation.CloseParen, - Method("Get"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Keyword("null"), - Punctuation.Semicolon); - } + testHost, + Keyword("public"), + Punctuation.OpenParen, + Keyword("int"), + Identifier("a"), + Punctuation.Comma, + Keyword("int"), + Identifier("b"), + Punctuation.CloseParen, + Method("Get"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Keyword("null"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestOutParameter(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + public async Task TestOutParameter(TestHost testHost) + { + await TestInMethodAsync(@" if (int.TryParse(""1"", out int x)) { }", - testHost, - ControlKeyword("if"), - Punctuation.OpenParen, - Keyword("int"), - Operators.Dot, - Identifier("TryParse"), - Punctuation.OpenParen, - String(@"""1"""), - Punctuation.Comma, - Keyword("out"), - Keyword("int"), - Local("x"), - Punctuation.CloseParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + ControlKeyword("if"), + Punctuation.OpenParen, + Keyword("int"), + Operators.Dot, + Identifier("TryParse"), + Punctuation.OpenParen, + String(@"""1"""), + Punctuation.Comma, + Keyword("out"), + Keyword("int"), + Local("x"), + Punctuation.CloseParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestOutParameter2(TestHost testHost) - { - await TestInClassAsync(@" + [Theory, CombinatorialData] + public async Task TestOutParameter2(TestHost testHost) + { + await TestInClassAsync(@" int F = int.TryParse(""1"", out int x) ? x : -1; ", - testHost, - Keyword("int"), - Field("F"), - Operators.Equals, - Keyword("int"), - Operators.Dot, - Identifier("TryParse"), - Punctuation.OpenParen, - String(@"""1"""), - Punctuation.Comma, - Keyword("out"), - Keyword("int"), - Local("x"), - Punctuation.CloseParen, - Operators.QuestionMark, - Identifier("x"), - Operators.Colon, - Operators.Minus, - Number("1"), - Punctuation.Semicolon); - } + testHost, + Keyword("int"), + Field("F"), + Operators.Equals, + Keyword("int"), + Operators.Dot, + Identifier("TryParse"), + Punctuation.OpenParen, + String(@"""1"""), + Punctuation.Comma, + Keyword("out"), + Keyword("int"), + Local("x"), + Punctuation.CloseParen, + Operators.QuestionMark, + Identifier("x"), + Operators.Colon, + Operators.Minus, + Number("1"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUsingDirective(TestHost testHost) - { - var code = @"using System.Collections.Generic;"; + [Theory, CombinatorialData] + public async Task TestUsingDirective(TestHost testHost) + { + var code = @"using System.Collections.Generic;"; - await TestAsync(code, - testHost, - Keyword("using"), - Identifier("System"), - Operators.Dot, - Identifier("Collections"), - Operators.Dot, - Identifier("Generic"), - Punctuation.Semicolon); - } + await TestAsync(code, + testHost, + Keyword("using"), + Identifier("System"), + Operators.Dot, + Identifier("Collections"), + Operators.Dot, + Identifier("Generic"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUsingAliasDirectiveForIdentifier(TestHost testHost) - { - var code = @"using Col = System.Collections;"; + [Theory, CombinatorialData] + public async Task TestUsingAliasDirectiveForIdentifier(TestHost testHost) + { + var code = @"using Col = System.Collections;"; - await TestAsync(code, - testHost, - Keyword("using"), - Identifier("Col"), - Operators.Equals, - Identifier("System"), - Operators.Dot, - Identifier("Collections"), - Punctuation.Semicolon); - } + await TestAsync(code, + testHost, + Keyword("using"), + Identifier("Col"), + Operators.Equals, + Identifier("System"), + Operators.Dot, + Identifier("Collections"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUsingAliasDirectiveForClass(TestHost testHost) - { - var code = @"using Con = System.Console;"; + [Theory, CombinatorialData] + public async Task TestUsingAliasDirectiveForClass(TestHost testHost) + { + var code = @"using Con = System.Console;"; - await TestAsync(code, - testHost, - Keyword("using"), - Identifier("Con"), - Operators.Equals, - Identifier("System"), - Operators.Dot, - Identifier("Console"), - Punctuation.Semicolon); - } + await TestAsync(code, + testHost, + Keyword("using"), + Identifier("Con"), + Operators.Equals, + Identifier("System"), + Operators.Dot, + Identifier("Console"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestUsingStaticDirective(TestHost testHost) - { - var code = @"using static System.Console;"; + [Theory, CombinatorialData] + public async Task TestUsingStaticDirective(TestHost testHost) + { + var code = @"using static System.Console;"; - await TestAsync(code, - testHost, - Keyword("using"), - Keyword("static"), - Identifier("System"), - Operators.Dot, - Identifier("Console"), - Punctuation.Semicolon); - } + await TestAsync(code, + testHost, + Keyword("using"), + Keyword("static"), + Identifier("System"), + Operators.Dot, + Identifier("Console"), + Punctuation.Semicolon); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33039")] - [CombinatorialData] - public async Task ForEachVariableStatement(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/33039")] + [CombinatorialData] + public async Task ForEachVariableStatement(TestHost testHost) + { + await TestInMethodAsync(@" foreach (var (x, y) in new[] { (1, 2) }); ", - testHost, - ControlKeyword("foreach"), - Punctuation.OpenParen, - Identifier("var"), - Punctuation.OpenParen, - Local("x"), - Punctuation.Comma, - Local("y"), - Punctuation.CloseParen, - ControlKeyword("in"), - Keyword("new"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Punctuation.OpenCurly, - Punctuation.OpenParen, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.CloseParen, - Punctuation.CloseCurly, - Punctuation.CloseParen, - Punctuation.Semicolon); - } + testHost, + ControlKeyword("foreach"), + Punctuation.OpenParen, + Identifier("var"), + Punctuation.OpenParen, + Local("x"), + Punctuation.Comma, + Local("y"), + Punctuation.CloseParen, + ControlKeyword("in"), + Keyword("new"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Punctuation.OpenCurly, + Punctuation.OpenParen, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.CloseParen, + Punctuation.CloseCurly, + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task CatchDeclarationStatement(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + public async Task CatchDeclarationStatement(TestHost testHost) + { + await TestInMethodAsync(@" try { } catch (Exception ex) { } ", - testHost, - ControlKeyword("try"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - ControlKeyword("catch"), - Punctuation.OpenParen, - Identifier("Exception"), - Local("ex"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + ControlKeyword("try"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + ControlKeyword("catch"), + Punctuation.OpenParen, + Identifier("Exception"), + Local("ex"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_InsideMethod(TestHost testHost) - { - await TestInMethodAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_InsideMethod(TestHost testHost) + { + await TestInMethodAsync(@" var notnull = 0; notnull++;", - testHost, - Keyword("var"), - Local("notnull"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - Identifier("notnull"), - Operators.PlusPlus, - Punctuation.Semicolon); - } + testHost, + Keyword("var"), + Local("notnull"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + Identifier("notnull"), + Operators.PlusPlus, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_Keyword(TestHost testHost) - { - await TestAsync( - "class X where T : notnull { }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_Keyword(TestHost testHost) + { + await TestAsync( + "class X where T : notnull { }", + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface notnull {} class X where T : notnull { }", - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface notnull {} } class X where T : notnull { }", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_Keyword(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_Keyword(TestHost testHost) + { + await TestAsync(@" class X { void M() where T : notnull { } }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface notnull {} class X { void M() where T : notnull { } }", - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface notnull {} @@ -5397,118 +5397,118 @@ class X { void M() where T : notnull { } }", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_Keyword(TestHost testHost) - { - await TestAsync( - "delegate void D() where T : notnull;", - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.Semicolon); - } + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_Keyword(TestHost testHost) + { + await TestAsync( + "delegate void D() where T : notnull;", + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface notnull {} delegate void D() where T : notnull;", - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.Semicolon); - } + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface notnull {} } delegate void D() where T : notnull;", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.Semicolon); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_Keyword(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_Keyword(TestHost testHost) + { + await TestAsync(@" class X { void N() @@ -5516,36 +5516,36 @@ void N() void M() where T : notnull { } } }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_ExistingInterface(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_ExistingInterface(TestHost testHost) + { + await TestAsync(@" interface notnull {} class X { @@ -5554,40 +5554,40 @@ void N() void M() where T : notnull { } } }", - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(@" + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(@" namespace OtherScope { interface notnull {} @@ -5599,133 +5599,133 @@ void N() void M() where T : notnull { } } }", - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - Identifier("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/45807")] - public async Task FunctionPointer(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/45807")] + public async Task FunctionPointer(TestHost testHost) + { + var code = @" class C { delegate* unmanaged[Stdcall, SuppressGCTransition] x; }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("delegate"), - Operators.Asterisk, - Keyword("unmanaged"), - Punctuation.OpenBracket, - Identifier("Stdcall"), - Punctuation.Comma, - Identifier("SuppressGCTransition"), - Punctuation.CloseBracket, - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.Comma, - Keyword("int"), - Punctuation.CloseAngle, - Field("x"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48094")] - public async Task TestXmlAttributeNameSpan1() - { - var source = @"/// "; - using var workspace = CreateWorkspace(source, options: null, TestHost.InProcess); - var document = workspace.CurrentSolution.Projects.First().Documents.First(); + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("delegate"), + Operators.Asterisk, + Keyword("unmanaged"), + Punctuation.OpenBracket, + Identifier("Stdcall"), + Punctuation.Comma, + Identifier("SuppressGCTransition"), + Punctuation.CloseBracket, + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.Comma, + Keyword("int"), + Punctuation.CloseAngle, + Field("x"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - var classifications = await GetSyntacticClassificationsAsync(document, ImmutableArray.Create(new TextSpan(0, source.Length))); - Assert.Equal(new[] - { - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(0, 3)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentText, new TextSpan(3, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(4, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(5, 5)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeName, new TextSpan(11, 4)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(15, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(16, 1)), - new ClassifiedSpan(ClassificationTypeNames.Identifier, new TextSpan(17, 5)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(22, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(23, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(24, 2)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(26, 5)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(31, 1)) - }, classifications); - } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48094")] + public async Task TestXmlAttributeNameSpan1() + { + var source = @"/// "; + using var workspace = CreateWorkspace(source, options: null, TestHost.InProcess); + var document = workspace.CurrentSolution.Projects.First().Documents.First(); + + var classifications = await GetSyntacticClassificationsAsync(document, ImmutableArray.Create(new TextSpan(0, source.Length))); + Assert.Equal(new[] + { + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(0, 3)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentText, new TextSpan(3, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(4, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(5, 5)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeName, new TextSpan(11, 4)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(15, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(16, 1)), + new ClassifiedSpan(ClassificationTypeNames.Identifier, new TextSpan(17, 5)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(22, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(23, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(24, 2)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(26, 5)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(31, 1)) + }, classifications); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48094")] - public async Task TestXmlAttributeNameSpan2() - { - var source = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48094")] + public async Task TestXmlAttributeNameSpan2() + { + var source = @" /// "; - using var workspace = CreateWorkspace(source, options: null, TestHost.InProcess); - var document = workspace.CurrentSolution.Projects.First().Documents.First(); - - var classifications = await GetSyntacticClassificationsAsync(document, ImmutableArray.Create(new TextSpan(0, source.Length))); - Assert.Equal(new[] - { - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(2, 3)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentText, new TextSpan(5, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(6, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(7, 5)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(14, 3)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeName, new TextSpan(18, 4)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(22, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(23, 1)), - new ClassifiedSpan(ClassificationTypeNames.Identifier, new TextSpan(24, 5)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(29, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(30, 1)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(31, 2)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(33, 5)), - new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(38, 1)) - }, classifications); - } + using var workspace = CreateWorkspace(source, options: null, TestHost.InProcess); + var document = workspace.CurrentSolution.Projects.First().Documents.First(); + + var classifications = await GetSyntacticClassificationsAsync(document, ImmutableArray.Create(new TextSpan(0, source.Length))); + Assert.Equal(new[] + { + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(2, 3)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentText, new TextSpan(5, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(6, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(7, 5)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(14, 3)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeName, new TextSpan(18, 4)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(22, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(23, 1)), + new ClassifiedSpan(ClassificationTypeNames.Identifier, new TextSpan(24, 5)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentAttributeQuotes, new TextSpan(29, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(30, 1)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(31, 2)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentName, new TextSpan(33, 5)), + new ClassifiedSpan(ClassificationTypeNames.XmlDocCommentDelimiter, new TextSpan(38, 1)) + }, classifications); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/52290")] - [CombinatorialData] - public async Task TestStaticLocalFunction(TestHost testHost) - { - var code = @" + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/52290")] + [CombinatorialData] + public async Task TestStaticLocalFunction(TestHost testHost) + { + var code = @" class C { public static void M() @@ -5734,36 +5734,36 @@ static void LocalFunc() { } } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("static"), - Keyword("void"), - Method("LocalFunc"), - Static("LocalFunc"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("static"), + Keyword("void"), + Method("LocalFunc"), + Static("LocalFunc"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/52290")] - [CombinatorialData] - public async Task TestConstantLocalVariable(TestHost testHost) - { - var code = @" + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/52290")] + [CombinatorialData] + public async Task TestConstantLocalVariable(TestHost testHost) + { + var code = @" class C { public static void M() @@ -5772,34 +5772,34 @@ public static void M() } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("const"), - Keyword("int"), - Constant("Zero"), - Static("Zero"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("const"), + Keyword("int"), + Constant("Zero"), + Static("Zero"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteral(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteral(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -5808,34 +5808,34 @@ public static void M(int x) } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String("\"\"\"Hello world\"\"\""), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String("\"\"\"Hello world\"\"\""), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralUtf8_01(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralUtf8_01(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -5844,35 +5844,35 @@ public static void M(int x) } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String("\"\"\"Hello world\"\"\""), - Keyword("u8"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String("\"\"\"Hello world\"\"\""), + Keyword("u8"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralUtf8_02(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralUtf8_02(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -5881,35 +5881,35 @@ public static void M(int x) } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String("\"\"\"Hello world\"\"\""), - Keyword("U8"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String("\"\"\"Hello world\"\"\""), + Keyword("U8"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralMultiline(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralMultiline(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -5920,36 +5920,36 @@ Hello world } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String(@""""""" + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String(@""""""" Hello world """""""), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralMultilineUtf8_01(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralMultilineUtf8_01(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -5960,37 +5960,37 @@ Hello world } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String(@""""""" + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String(@""""""" Hello world """""""), - Keyword("u8"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + Keyword("u8"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralMultilineUtf8_02(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralMultilineUtf8_02(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -6001,37 +6001,37 @@ Hello world } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String(@""""""" + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String(@""""""" Hello world """""""), - Keyword("U8"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + Keyword("U8"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralInterpolation1(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralInterpolation1(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -6040,38 +6040,38 @@ public static void M(int x) } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String("$\"\"\""), - Punctuation.OpenCurly, - Identifier("x"), - Punctuation.CloseCurly, - String("\"\"\""), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String("$\"\"\""), + Punctuation.OpenCurly, + Identifier("x"), + Punctuation.CloseCurly, + String("\"\"\""), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralInterpolation2(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralInterpolation2(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -6080,38 +6080,38 @@ public static void M(int x) } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String("$$\"\"\""), - PunctuationText("{{"), - Identifier("x"), - PunctuationText("}}"), - String("\"\"\""), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String("$$\"\"\""), + PunctuationText("{{"), + Identifier("x"), + PunctuationText("}}"), + String("\"\"\""), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestRawStringLiteralInterpolation3(TestHost testHost) - { - var code = @" + [Theory, CombinatorialData] + public async Task TestRawStringLiteralInterpolation3(TestHost testHost) + { + var code = @" class C { public static void M(int x) @@ -6120,522 +6120,569 @@ public static void M(int x) } }"; - await TestAsync(code, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - Method("M"), - Static("M"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("s"), - Operators.Equals, - String("$$\"\"\""), - String("{"), - PunctuationText("{{"), - Identifier("x"), - PunctuationText("}}"), - String("}"), - String("\"\"\""), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + await TestAsync(code, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + Method("M"), + Static("M"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("s"), + Operators.Equals, + String("$$\"\"\""), + String("{"), + PunctuationText("{{"), + Identifier("x"), + PunctuationText("}}"), + String("}"), + String("\"\"\""), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CheckedUserDefinedOperators_01(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task CheckedUserDefinedOperators_01(TestHost testHost) + { + await TestInClassAsync( @" static T operator checked -(T a) { }", - testHost, - Keyword("static"), - Identifier("T"), - Keyword("operator"), - Keyword("checked"), - Operators.Minus, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Identifier("T"), + Keyword("operator"), + Keyword("checked"), + Operators.Minus, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CheckedUserDefinedOperators_02(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task CheckedUserDefinedOperators_02(TestHost testHost) + { + await TestInClassAsync( @" static T operator checked +(T a, T b) { }", - testHost, - Keyword("static"), - Identifier("T"), - Keyword("operator"), - Keyword("checked"), - Operators.Plus, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.Comma, - Identifier("T"), - Parameter("b"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Identifier("T"), + Keyword("operator"), + Keyword("checked"), + Operators.Plus, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.Comma, + Identifier("T"), + Parameter("b"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CheckedUserDefinedOperators_03(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task CheckedUserDefinedOperators_03(TestHost testHost) + { + await TestInClassAsync( @" static explicit operator checked T(T a) { }", - testHost, - Keyword("static"), - Keyword("explicit"), - Keyword("operator"), - Keyword("checked"), - Identifier("T"), - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Keyword("explicit"), + Keyword("operator"), + Keyword("checked"), + Identifier("T"), + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CheckedUserDefinedOperators_04(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task CheckedUserDefinedOperators_04(TestHost testHost) + { + await TestInClassAsync( @" static T I1.operator checked -(T a) { }", - testHost, - Keyword("static"), - Identifier("T"), - Identifier("I1"), - Operators.Dot, - Keyword("operator"), - Keyword("checked"), - Operators.Minus, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Identifier("T"), + Identifier("I1"), + Operators.Dot, + Keyword("operator"), + Keyword("checked"), + Operators.Minus, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CheckedUserDefinedOperators_05(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task CheckedUserDefinedOperators_05(TestHost testHost) + { + await TestInClassAsync( @" static T I1.operator checked +(T a, T b) { }", - testHost, - Keyword("static"), - Identifier("T"), - Identifier("I1"), - Operators.Dot, - Keyword("operator"), - Keyword("checked"), - Operators.Plus, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.Comma, - Identifier("T"), - Parameter("b"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Identifier("T"), + Identifier("I1"), + Operators.Dot, + Keyword("operator"), + Keyword("checked"), + Operators.Plus, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.Comma, + Identifier("T"), + Parameter("b"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task CheckedUserDefinedOperators_06(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task CheckedUserDefinedOperators_06(TestHost testHost) + { + await TestInClassAsync( @" static explicit I1.operator checked T(T a) { }", - testHost, - Keyword("static"), - Keyword("explicit"), - Identifier("I1"), - Operators.Dot, - Keyword("operator"), - Keyword("checked"), - Identifier("T"), - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Keyword("explicit"), + Identifier("I1"), + Operators.Dot, + Keyword("operator"), + Keyword("checked"), + Identifier("T"), + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task UnsignedRightShift_01(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task UnsignedRightShift_01(TestHost testHost) + { + await TestInClassAsync( @" static T operator >>>(T a, int b) { }", - testHost, - Keyword("static"), - Identifier("T"), - Keyword("operator"), - Operators.GreaterThanGreaterThanGreaterThan, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.Comma, - Keyword("int"), - Parameter("b"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Identifier("T"), + Keyword("operator"), + Operators.GreaterThanGreaterThanGreaterThan, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.Comma, + Keyword("int"), + Parameter("b"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task UnsignedRightShift_02(TestHost testHost) - { - await TestInClassAsync( + [Theory, CombinatorialData] + public async Task UnsignedRightShift_02(TestHost testHost) + { + await TestInClassAsync( @" static T I1.operator checked >>>(T a, T b) { }", - testHost, - Keyword("static"), - Identifier("T"), - Identifier("I1"), - Operators.Dot, - Keyword("operator"), - Keyword("checked"), - Operators.GreaterThanGreaterThanGreaterThan, - Punctuation.OpenParen, - Identifier("T"), - Parameter("a"), - Punctuation.Comma, - Identifier("T"), - Parameter("b"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("static"), + Identifier("T"), + Identifier("I1"), + Operators.Dot, + Keyword("operator"), + Keyword("checked"), + Operators.GreaterThanGreaterThanGreaterThan, + Punctuation.OpenParen, + Identifier("T"), + Parameter("a"), + Punctuation.Comma, + Identifier("T"), + Parameter("b"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task TestExclamationExclamation(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestExclamationExclamation(TestHost testHost) + { + await TestAsync( @"class C { void M(string v!!) { } }", - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Keyword("string"), - Parameter("v"), - Operators.Exclamation, - Operators.Exclamation, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Keyword("string"), + Parameter("v"), + Operators.Exclamation, + Operators.Exclamation, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - /// - /// - [Theory, CombinatorialData] - public async Task LocalFunctionDeclaration(TestHost testHost) - { - await TestAsync( - """ - using System; + /// + /// + [Theory, CombinatorialData] + public async Task LocalFunctionDeclaration(TestHost testHost) + { + await TestAsync( + """ + using System; - class C + class C + { + void M(Action action) { - void M(Action action) - { - [|localFunction(); - staticLocalFunction(); + [|localFunction(); + staticLocalFunction(); - M(localFunction); - M(staticLocalFunction); + M(localFunction); + M(staticLocalFunction); - void localFunction() { } - static void staticLocalFunction() { }|] - } + void localFunction() { } + static void staticLocalFunction() { }|] } + } - """, - testHost, - Identifier("localFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Identifier("staticLocalFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Identifier("M"), - Punctuation.OpenParen, - Identifier("localFunction"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Identifier("M"), - Punctuation.OpenParen, - Identifier("staticLocalFunction"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("void"), - Method("localFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("static"), - Keyword("void"), - Method("staticLocalFunction"), - Static("staticLocalFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } + """, + testHost, + Identifier("localFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Identifier("staticLocalFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Identifier("M"), + Punctuation.OpenParen, + Identifier("localFunction"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Identifier("M"), + Punctuation.OpenParen, + Identifier("staticLocalFunction"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("void"), + Method("localFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("static"), + Keyword("void"), + Method("staticLocalFunction"), + Static("staticLocalFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task ScopedParameter(TestHost testHost) - { - await TestInMethodAsync(@"interface I { void F(scoped R r); }", - testHost, - Keyword("interface"), - Interface("I"), - Punctuation.OpenCurly, - Keyword("void"), - Method("F"), - Punctuation.OpenParen, - Keyword("scoped"), - Identifier("R"), - Parameter("r"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly); - } + [Theory, CombinatorialData] + public async Task ScopedParameter(TestHost testHost) + { + await TestInMethodAsync(@"interface I { void F(scoped R r); }", + testHost, + Keyword("interface"), + Interface("I"), + Punctuation.OpenCurly, + Keyword("void"), + Method("F"), + Punctuation.OpenParen, + Keyword("scoped"), + Identifier("R"), + Parameter("r"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task ScopedLocalDeclaration(TestHost testHost) - { - await TestInMethodAsync(@"scoped var v;", - testHost, - Keyword("scoped"), - Identifier("var"), - Local("v"), - Punctuation.Semicolon); - } + [Theory, CombinatorialData] + public async Task ScopedLocalDeclaration(TestHost testHost) + { + await TestInMethodAsync(@"scoped var v;", + testHost, + Keyword("scoped"), + Identifier("var"), + Local("v"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task ScopedOutDeclaration(TestHost testHost) - { - await TestInMethodAsync(@"F(x, out scoped R y);", - testHost, - Identifier("F"), - Punctuation.OpenParen, - Identifier("x"), - Punctuation.Comma, - Keyword("out"), - Keyword("scoped"), - Identifier("R"), - Local("y"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } + [Theory, CombinatorialData] + public async Task ScopedOutDeclaration(TestHost testHost) + { + await TestInMethodAsync(@"F(x, out scoped R y);", + testHost, + Identifier("F"), + Punctuation.OpenParen, + Identifier("x"), + Punctuation.Comma, + Keyword("out"), + Keyword("scoped"), + Identifier("R"), + Local("y"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task LambdaDefaultParameter_01(TestHost testHost) - { - await TestAsync( - """ - using System; - class Program + [Theory, CombinatorialData] + public async Task LambdaDefaultParameter_01(TestHost testHost) + { + await TestAsync( + """ + using System; + class Program + { + void M() { - void M() - { - const int n = 100; - const int m = 200; - var lam = (int x = n + m) => x; - } + const int n = 100; + const int m = 200; + var lam = (int x = n + m) => x; } + } - """, - testHost, - Keyword("using"), - Identifier("System"), - Punctuation.Semicolon, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("const"), - Keyword("int"), - Constant("n"), - Static("n"), - Operators.Equals, - Number("100"), - Punctuation.Semicolon, - Keyword("const"), - Keyword("int"), - Constant("m"), - Static("m"), - Operators.Equals, - Number("200"), - Punctuation.Semicolon, - Keyword("var"), - Local("lam"), - Operators.Equals, - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Operators.Equals, - Identifier("n"), - Operators.Plus, - Identifier("m"), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Identifier("x"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + """, + testHost, + Keyword("using"), + Identifier("System"), + Punctuation.Semicolon, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("const"), + Keyword("int"), + Constant("n"), + Static("n"), + Operators.Equals, + Number("100"), + Punctuation.Semicolon, + Keyword("const"), + Keyword("int"), + Constant("m"), + Static("m"), + Operators.Equals, + Number("200"), + Punctuation.Semicolon, + Keyword("var"), + Local("lam"), + Operators.Equals, + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Operators.Equals, + Identifier("n"), + Operators.Plus, + Identifier("m"), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Identifier("x"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LambdaDefaultParameter_02(TestHost testHost) - { - await TestAsync( - """ - class Program + [Theory, CombinatorialData] + public async Task LambdaDefaultParameter_02(TestHost testHost) + { + await TestAsync( + """ + class Program + { + void M() { - void M() - { - var lam = (string s = "a string") => s; - } + var lam = (string s = "a string") => s; } + } - """, - testHost, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("lam"), - Operators.Equals, - Punctuation.OpenParen, - Keyword("string"), - Parameter("s"), - Operators.Equals, - String(@"""a string"""), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Identifier("s"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } + """, + testHost, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("lam"), + Operators.Equals, + Punctuation.OpenParen, + Keyword("string"), + Parameter("s"), + Operators.Equals, + String(@"""a string"""), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Identifier("s"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [Theory, CombinatorialData] - public async Task LambdaParamsArray(TestHost testHost) - { - await TestInMethodAsync("var lam = (params int[] xs) => xs.Length;", - testHost, - Keyword("var"), - Local("lam"), - Operators.Equals, - Punctuation.OpenParen, - Keyword("params"), - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("xs"), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Identifier("xs"), - Operators.Dot, - Identifier("Length"), - Punctuation.Semicolon); - } + [Theory, CombinatorialData] + public async Task LambdaParamsArray(TestHost testHost) + { + await TestInMethodAsync("var lam = (params int[] xs) => xs.Length;", + testHost, + Keyword("var"), + Local("lam"), + Operators.Equals, + Punctuation.OpenParen, + Keyword("params"), + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("xs"), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Identifier("xs"), + Operators.Dot, + Identifier("Length"), + Punctuation.Semicolon); + } - [Theory, CombinatorialData] - public async Task LambdaParamsArray_Multiple(TestHost testHost) - { - await TestInMethodAsync("var lam = (int a, int b = 1, params int[] xs, params int[] ys.Length) => { };", - testHost, - Keyword("var"), - Local("lam"), - Operators.Equals, - Punctuation.OpenParen, - Keyword("int"), - Local("a"), - Punctuation.Comma, - Keyword("int"), - Identifier("b"), - Operators.Equals, - Number("1"), - Punctuation.Comma, - Keyword("params"), - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Local("xs"), - Punctuation.Comma, - Keyword("params"), - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Local("ys"), - Operators.Dot, - Identifier("Length"), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.Semicolon); - } + [Theory, CombinatorialData] + public async Task LambdaParamsArray_Multiple(TestHost testHost) + { + await TestInMethodAsync("var lam = (int a, int b = 1, params int[] xs, params int[] ys.Length) => { };", + testHost, + Keyword("var"), + Local("lam"), + Operators.Equals, + Punctuation.OpenParen, + Keyword("int"), + Local("a"), + Punctuation.Comma, + Keyword("int"), + Identifier("b"), + Operators.Equals, + Number("1"), + Punctuation.Comma, + Keyword("params"), + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Local("xs"), + Punctuation.Comma, + Keyword("params"), + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Local("ys"), + Operators.Dot, + Identifier("Length"), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestAllowsRefStructConstraint_01(TestHost testHost) + { + await TestAsync( + "class X where T : allows ref struct { }", + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("allows"), + Keyword("ref"), + Keyword("struct"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestAllowsRefStructConstraint_02(TestHost testHost) + { + await TestAsync( + "class X { void M() where T : allows ref struct { } }", + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + Identifier("T"), + Punctuation.Colon, + Keyword("allows"), + Keyword("ref"), + Keyword("struct"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests_Preprocessor.cs b/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests_Preprocessor.cs index d5c9413138983..e2ebf43e96a5c 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests_Preprocessor.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SyntacticClassifierTests_Preprocessor.cs @@ -2,7 +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. -using System; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Remote.Testing; using Microsoft.CodeAnalysis.Test.Utilities; @@ -10,1379 +9,1378 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +[Trait(Traits.Feature, Traits.Features.Classification)] +public partial class SyntacticClassifierTests { - [Trait(Traits.Feature, Traits.Features.Classification)] - public partial class SyntacticClassifierTests - { - [Theory, CombinatorialData] - public async Task PP_IfTrue(TestHost testHost) - { - var code = - """ - #if true - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Keyword("true"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfTrueWithComment(TestHost testHost) - { - var code = - """ - #if true //Goo - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Keyword("true"), - Comment("//Goo"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfFalse(TestHost testHost) - { - var code = - """ - #if false - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Keyword("false"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfGOO(TestHost testHost) - { - var code = - """ - #if GOO - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("GOO"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfNotTrue(TestHost testHost) - { - var code = - """ - #if !true - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Operators.Exclamation, - Keyword("true"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfNotFalse(TestHost testHost) - { - var code = - """ - #if !false - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Operators.Exclamation, - Keyword("false"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfNotGOO(TestHost testHost) - { - var code = - """ - #if !GOO - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Operators.Exclamation, - Identifier("GOO"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfTrueWithParens(TestHost testHost) - { - var code = - """ - #if (true) - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Punctuation.OpenParen, - Keyword("true"), - Punctuation.CloseParen, - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfFalseWithParens(TestHost testHost) - { - var code = - """ - #if (false) - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Punctuation.OpenParen, - Keyword("false"), - Punctuation.CloseParen, - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfGOOWithParens(TestHost testHost) - { - var code = - """ - #if (GOO) - #endif - """; - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Punctuation.OpenParen, - Identifier("GOO"), - Punctuation.CloseParen, - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfOrExpression(TestHost testHost) - { - var code = - """ - #if GOO || BAR - #endif - """; - - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("GOO"), - Operators.BarBar, - Identifier("BAR"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfAndExpression(TestHost testHost) - { - var code = - """ - #if GOO && BAR - #endif - """; - - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("GOO"), - Operators.AmpersandAmpersand, - Identifier("BAR"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfOrAndExpression(TestHost testHost) - { - var code = - """ - #if GOO || BAR && BAZ - #endif - """; - - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("GOO"), - Operators.BarBar, - Identifier("BAR"), - Operators.AmpersandAmpersand, - Identifier("BAZ"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfOrExpressionWithParens(TestHost testHost) - { - var code = - """ - #if (GOO || BAR) - #endif - """; - - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Punctuation.OpenParen, - Identifier("GOO"), - Operators.BarBar, - Identifier("BAR"), - Punctuation.CloseParen, - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfAndExpressionWithParens(TestHost testHost) - { - var code = - """ - #if (GOO && BAR) - #endif - """; - - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Punctuation.OpenParen, - Identifier("GOO"), - Operators.AmpersandAmpersand, - Identifier("BAR"), - Punctuation.CloseParen, - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_IfOrAndExpressionWithParens(TestHost testHost) - { - var code = - """ - #if GOO || (BAR && BAZ) - #endif - """; - - await TestInMethodAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("GOO"), - Operators.BarBar, - Punctuation.OpenParen, - Identifier("BAR"), - Operators.AmpersandAmpersand, - Identifier("BAZ"), - Punctuation.CloseParen, - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_If1(TestHost testHost) - { - await TestAsync("#if goo", - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("goo")); - } - - [Theory, CombinatorialData] - public async Task PP_If2(TestHost testHost) - { - await TestAsync(" #if goo", - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("goo")); - } - - [Theory, CombinatorialData] - public async Task PP_If3(TestHost testHost) - { - var code = - """ - #if goo - #endif - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Identifier("goo"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_If4(TestHost testHost) - { - var code = - """ - #if - #endif - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_If5(TestHost testHost) - { - var code = - """ - #if - aoeu - aoeu - #endif - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Inactive(""" - aoeu - aoeu - - """), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_If6(TestHost testHost) - { - var code = - """ - #if - #else - aeu - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - PPKeyword("#"), - PPKeyword("else"), - Identifier("aeu")); - } - - [Theory, CombinatorialData] - public async Task PP_If7(TestHost testHost) - { - var code = - """ - #if - #else - #endif - aeu - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - PPKeyword("#"), - PPKeyword("else"), - PPKeyword("#"), - PPKeyword("endif"), - Identifier("aeu")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - [CombinatorialData] - public async Task PP_If8(bool script, TestHost testHost) - { - var code = - """ - #if - #else - aoeu - aoeu - aou - #endif - aeu - """; - - var parseOptions = script ? Options.Script : null; - - await TestAsync( - code, - code, - testHost, - parseOptions, - PPKeyword("#"), - PPKeyword("if"), - PPKeyword("#"), - PPKeyword("else"), - Identifier("aoeu"), - script ? Field("aoeu") : Local("aoeu"), - Identifier("aou"), - PPKeyword("#"), - PPKeyword("endif"), - script ? Field("aeu") : Identifier("aeu")); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - [CombinatorialData] - public async Task PP_If9(bool script, TestHost testHost) - { - var code = - """ - #if //Goo1 - #else //Goo2 + [Theory, CombinatorialData] + public async Task PP_IfTrue(TestHost testHost) + { + var code = + """ + #if true + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Keyword("true"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfTrueWithComment(TestHost testHost) + { + var code = + """ + #if true //Goo + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Keyword("true"), + Comment("//Goo"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfFalse(TestHost testHost) + { + var code = + """ + #if false + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Keyword("false"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfGOO(TestHost testHost) + { + var code = + """ + #if GOO + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("GOO"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfNotTrue(TestHost testHost) + { + var code = + """ + #if !true + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Operators.Exclamation, + Keyword("true"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfNotFalse(TestHost testHost) + { + var code = + """ + #if !false + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Operators.Exclamation, + Keyword("false"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfNotGOO(TestHost testHost) + { + var code = + """ + #if !GOO + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Operators.Exclamation, + Identifier("GOO"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfTrueWithParens(TestHost testHost) + { + var code = + """ + #if (true) + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Punctuation.OpenParen, + Keyword("true"), + Punctuation.CloseParen, + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfFalseWithParens(TestHost testHost) + { + var code = + """ + #if (false) + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Punctuation.OpenParen, + Keyword("false"), + Punctuation.CloseParen, + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfGOOWithParens(TestHost testHost) + { + var code = + """ + #if (GOO) + #endif + """; + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Punctuation.OpenParen, + Identifier("GOO"), + Punctuation.CloseParen, + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfOrExpression(TestHost testHost) + { + var code = + """ + #if GOO || BAR + #endif + """; + + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("GOO"), + Operators.BarBar, + Identifier("BAR"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfAndExpression(TestHost testHost) + { + var code = + """ + #if GOO && BAR + #endif + """; + + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("GOO"), + Operators.AmpersandAmpersand, + Identifier("BAR"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfOrAndExpression(TestHost testHost) + { + var code = + """ + #if GOO || BAR && BAZ + #endif + """; + + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("GOO"), + Operators.BarBar, + Identifier("BAR"), + Operators.AmpersandAmpersand, + Identifier("BAZ"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfOrExpressionWithParens(TestHost testHost) + { + var code = + """ + #if (GOO || BAR) + #endif + """; + + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Punctuation.OpenParen, + Identifier("GOO"), + Operators.BarBar, + Identifier("BAR"), + Punctuation.CloseParen, + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfAndExpressionWithParens(TestHost testHost) + { + var code = + """ + #if (GOO && BAR) + #endif + """; + + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Punctuation.OpenParen, + Identifier("GOO"), + Operators.AmpersandAmpersand, + Identifier("BAR"), + Punctuation.CloseParen, + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_IfOrAndExpressionWithParens(TestHost testHost) + { + var code = + """ + #if GOO || (BAR && BAZ) + #endif + """; + + await TestInMethodAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("GOO"), + Operators.BarBar, + Punctuation.OpenParen, + Identifier("BAR"), + Operators.AmpersandAmpersand, + Identifier("BAZ"), + Punctuation.CloseParen, + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_If1(TestHost testHost) + { + await TestAsync("#if goo", + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("goo")); + } + + [Theory, CombinatorialData] + public async Task PP_If2(TestHost testHost) + { + await TestAsync(" #if goo", + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("goo")); + } + + [Theory, CombinatorialData] + public async Task PP_If3(TestHost testHost) + { + var code = + """ + #if goo + #endif + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Identifier("goo"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_If4(TestHost testHost) + { + var code = + """ + #if + #endif + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_If5(TestHost testHost) + { + var code = + """ + #if + aoeu + aoeu + #endif + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Inactive(""" aoeu aoeu - aou - #endif //Goo3 - aeu - """; - - var parseOptions = script ? Options.Script : null; - - await TestAsync( - code, - code, - testHost, - parseOptions, - PPKeyword("#"), - PPKeyword("if"), - Comment("//Goo1"), - PPKeyword("#"), - PPKeyword("else"), - Comment("//Goo2"), - Identifier("aoeu"), - script ? Field("aoeu") : Local("aoeu"), - Identifier("aou"), - PPKeyword("#"), - PPKeyword("endif"), - Comment("//Goo3"), - script ? Field("aeu") : Identifier("aeu")); - } - - [Theory, CombinatorialData] - public async Task PP_Region1(TestHost testHost) - { - await TestAsync("#region Goo", - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPText("Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_Region2(TestHost testHost) - { - await TestAsync(" #region goo", - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPText("goo")); - } - - [Theory, CombinatorialData] - public async Task PP_EndRegion1(TestHost testHost) - { - await TestAsync("#endregion", - testHost, - PPKeyword("#"), - PPKeyword("endregion")); - } - - [Theory, CombinatorialData] - public async Task PP_EndRegion2(TestHost testHost) - { - await TestAsync(" #endregion", - testHost, - PPKeyword("#"), - PPKeyword("endregion")); - } - - [Theory, CombinatorialData] - public async Task PP_EndRegion3(TestHost testHost) - { - await TestAsync("#endregion adsf", - testHost, - PPKeyword("#"), - PPKeyword("endregion"), - PPText("adsf")); - } - - [Theory, CombinatorialData] - public async Task PP_EndRegion4(TestHost testHost) - { - await TestAsync(" #endregion adsf", - testHost, - PPKeyword("#"), - PPKeyword("endregion"), - PPText("adsf")); - } - - [Theory, CombinatorialData] - public async Task PP_RegionEndRegion1(TestHost testHost) - { - await TestAsync( - """ - #region - #endregion - """, - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPKeyword("#"), - PPKeyword("endregion")); - } - - [Theory, CombinatorialData] - public async Task PP_CommentAfterRegion1(TestHost testHost) - { - await TestAsync( - """ - #region adsf //comment - #endregion - """, - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPText("adsf //comment"), - PPKeyword("#"), - PPKeyword("endregion")); - } - - [Theory, CombinatorialData] - public async Task PP_CommentAfterRegion2(TestHost testHost) - { - await TestAsync( - """ - #region //comment - #endregion - """, - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPText("//comment"), - PPKeyword("#"), - PPKeyword("endregion")); - } - - [Theory, CombinatorialData] - public async Task PP_CommentAfterEndRegion1(TestHost testHost) - { - await TestAsync( - """ - #region - #endregion adsf //comment - """, - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPKeyword("#"), - PPKeyword("endregion"), - PPText("adsf //comment")); - } - - [Theory, CombinatorialData] - public async Task PP_CommentAfterEndRegion2(TestHost testHost) - { - await TestAsync( - """ - #region - #endregion //comment - """, - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPKeyword("#"), - PPKeyword("endregion"), - Comment("//comment")); - } - - [Theory, CombinatorialData] - public async Task PP_DeclarationDirectives(TestHost testHost) - { - await TestAsync( - """ - #define A - #undef B - """, - testHost, - PPKeyword("#"), - PPKeyword("define"), - Identifier("A"), - PPKeyword("#"), - PPKeyword("undef"), - Identifier("B")); - } - - [Theory, CombinatorialData] - public async Task PP_IfElseEndIfDirectives(TestHost testHost) - { - var code = - """ - #if true - #elif DEBUG - #else - #endif - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("if"), - Keyword("true"), - PPKeyword("#"), - PPKeyword("elif"), - Identifier("DEBUG"), - PPKeyword("#"), - PPKeyword("else"), - PPKeyword("#"), - PPKeyword("endif")); - } - - [Theory, CombinatorialData] - public async Task PP_DefineDirective(TestHost testHost) - { - var code = @"#define GOO"; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("define"), - Identifier("GOO")); - } - - [Theory, CombinatorialData] - public async Task PP_DefineDirectiveWithCommentAndNoName(TestHost testHost) - { - var code = @"#define //Goo"; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("define"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_DefineDirectiveWithComment(TestHost testHost) - { - var code = @"#define GOO //Goo"; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("define"), - Identifier("GOO"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_UndefDirectives(TestHost testHost) - { - var code = @"#undef GOO"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("undef"), - Identifier("GOO")); - } - - [Theory, CombinatorialData] - public async Task PP_UndefDirectiveWithCommentAndNoName(TestHost testHost) - { - var code = @"#undef //Goo"; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("undef"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_UndefDirectiveWithComment(TestHost testHost) - { - var code = @"#undef GOO //Goo"; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("undef"), - Identifier("GOO"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_ErrorDirective(TestHost testHost) - { - var code = @"#error GOO"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("error"), - PPText("GOO")); - } - - [Theory, CombinatorialData] - public async Task PP_ErrorDirectiveWithComment(TestHost testHost) - { - var code = @"#error GOO //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("error"), - PPText("GOO //Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_WarningDirective(TestHost testHost) - { - var code = @"#warning GOO"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("warning"), - PPText("GOO")); - } - - [Theory, CombinatorialData] - public async Task PP_WarningDirectiveWithComment(TestHost testHost) - { - var code = @"#warning GOO //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("warning"), - PPText("GOO //Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_LineHidden(TestHost testHost) - { - var code = @"#line hidden"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - PPKeyword("hidden")); - } - - [Theory, CombinatorialData] - public async Task PP_LineHiddenWithComment(TestHost testHost) - { - var code = @"#line hidden //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - PPKeyword("hidden"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_LineDefault(TestHost testHost) - { - var code = @"#line default"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - PPKeyword("default")); - } - - [Theory, CombinatorialData] - public async Task PP_LineDefaultWithComment(TestHost testHost) - { - var code = @"#line default //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - PPKeyword("default"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_LineNumber(TestHost testHost) - { - var code = @"#line 100"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - Number("100")); - } - - [Theory, CombinatorialData] - public async Task PP_LineNumberWithComment(TestHost testHost) - { - var code = @"#line 100 //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - Number("100"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_LineNumberWithFilename(TestHost testHost) - { - var code = """ - #line 100 "C:\Goo" - """; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - Number("100"), - String(""" - "C:\Goo" - """)); - } - - [Theory, CombinatorialData] - public async Task PP_LineNumberWithFilenameAndComment(TestHost testHost) - { - var code = @"#line 100 ""C:\Goo"" //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - Number("100"), - String(""" - "C:\Goo" - """), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_LineSpanWithCharacterOffset(TestHost testHost) - { - var code = """ - #line (1, 2) - (3, 4) 5 "file.txt" - """; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - Punctuation.OpenParen, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.CloseParen, - Operators.Minus, - Punctuation.OpenParen, - Number("3"), - Punctuation.Comma, - Number("4"), - Punctuation.CloseParen, - Number("5"), - String(""" - "file.txt" - """)); - } - - [Theory, CombinatorialData] - public async Task PP_LineSpanWithComment(TestHost testHost) - { - var code = @"#line (1, 2) - (3, 4) """" //comment"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("line"), - Punctuation.OpenParen, - Number("1"), - Punctuation.Comma, - Number("2"), - Punctuation.CloseParen, - Operators.Minus, - Punctuation.OpenParen, - Number("3"), - Punctuation.Comma, - Number("4"), - Punctuation.CloseParen, - String(""" - "" - """), - Comment("//comment")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableEnable(TestHost testHost) - { - var code = @"#nullable enable"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("enable")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableEnableWithComment(TestHost testHost) - { - var code = @"#nullable enable //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("enable"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableEnableWarnings(TestHost testHost) - { - var code = @"#nullable enable warnings"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("enable"), - PPKeyword("warnings")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableEnableWarningsWithComment(TestHost testHost) - { - var code = @"#nullable enable warnings //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("enable"), - PPKeyword("warnings"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableEnableAnnotations(TestHost testHost) - { - var code = @"#nullable enable annotations"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("enable"), - PPKeyword("annotations")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableEnableAnnotationsWithComment(TestHost testHost) - { - var code = @"#nullable enable annotations //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("enable"), - PPKeyword("annotations"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableDisable(TestHost testHost) - { - var code = @"#nullable disable"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("disable")); - } - - [Theory, CombinatorialData] - public async Task PP_NullableDisableWithComment(TestHost testHost) - { - var code = @"#nullable disable //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("nullable"), - PPKeyword("disable"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaChecksum1(TestHost testHost) - { - await TestAsync( + + """), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_If6(TestHost testHost) + { + var code = + """ + #if + #else + aeu + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + PPKeyword("#"), + PPKeyword("else"), + Identifier("aeu")); + } + + [Theory, CombinatorialData] + public async Task PP_If7(TestHost testHost) + { + var code = + """ + #if + #else + #endif + aeu + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + PPKeyword("#"), + PPKeyword("else"), + PPKeyword("#"), + PPKeyword("endif"), + Identifier("aeu")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + [CombinatorialData] + public async Task PP_If8(bool script, TestHost testHost) + { + var code = + """ + #if + #else + aoeu + aoeu + aou + #endif + aeu + """; + + var parseOptions = script ? Options.Script : null; + + await TestAsync( + code, + code, + testHost, + parseOptions, + PPKeyword("#"), + PPKeyword("if"), + PPKeyword("#"), + PPKeyword("else"), + Identifier("aoeu"), + script ? Field("aoeu") : Local("aoeu"), + Identifier("aou"), + PPKeyword("#"), + PPKeyword("endif"), + script ? Field("aeu") : Identifier("aeu")); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + [CombinatorialData] + public async Task PP_If9(bool script, TestHost testHost) + { + var code = + """ + #if //Goo1 + #else //Goo2 + aoeu + aoeu + aou + #endif //Goo3 + aeu + """; + + var parseOptions = script ? Options.Script : null; + + await TestAsync( + code, + code, + testHost, + parseOptions, + PPKeyword("#"), + PPKeyword("if"), + Comment("//Goo1"), + PPKeyword("#"), + PPKeyword("else"), + Comment("//Goo2"), + Identifier("aoeu"), + script ? Field("aoeu") : Local("aoeu"), + Identifier("aou"), + PPKeyword("#"), + PPKeyword("endif"), + Comment("//Goo3"), + script ? Field("aeu") : Identifier("aeu")); + } + + [Theory, CombinatorialData] + public async Task PP_Region1(TestHost testHost) + { + await TestAsync("#region Goo", + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPText("Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_Region2(TestHost testHost) + { + await TestAsync(" #region goo", + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPText("goo")); + } + + [Theory, CombinatorialData] + public async Task PP_EndRegion1(TestHost testHost) + { + await TestAsync("#endregion", + testHost, + PPKeyword("#"), + PPKeyword("endregion")); + } + + [Theory, CombinatorialData] + public async Task PP_EndRegion2(TestHost testHost) + { + await TestAsync(" #endregion", + testHost, + PPKeyword("#"), + PPKeyword("endregion")); + } + + [Theory, CombinatorialData] + public async Task PP_EndRegion3(TestHost testHost) + { + await TestAsync("#endregion adsf", + testHost, + PPKeyword("#"), + PPKeyword("endregion"), + PPText("adsf")); + } + + [Theory, CombinatorialData] + public async Task PP_EndRegion4(TestHost testHost) + { + await TestAsync(" #endregion adsf", + testHost, + PPKeyword("#"), + PPKeyword("endregion"), + PPText("adsf")); + } + + [Theory, CombinatorialData] + public async Task PP_RegionEndRegion1(TestHost testHost) + { + await TestAsync( + """ + #region + #endregion + """, + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPKeyword("#"), + PPKeyword("endregion")); + } + + [Theory, CombinatorialData] + public async Task PP_CommentAfterRegion1(TestHost testHost) + { + await TestAsync( + """ + #region adsf //comment + #endregion + """, + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPText("adsf //comment"), + PPKeyword("#"), + PPKeyword("endregion")); + } + + [Theory, CombinatorialData] + public async Task PP_CommentAfterRegion2(TestHost testHost) + { + await TestAsync( + """ + #region //comment + #endregion + """, + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPText("//comment"), + PPKeyword("#"), + PPKeyword("endregion")); + } + + [Theory, CombinatorialData] + public async Task PP_CommentAfterEndRegion1(TestHost testHost) + { + await TestAsync( + """ + #region + #endregion adsf //comment + """, + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPKeyword("#"), + PPKeyword("endregion"), + PPText("adsf //comment")); + } + + [Theory, CombinatorialData] + public async Task PP_CommentAfterEndRegion2(TestHost testHost) + { + await TestAsync( + """ + #region + #endregion //comment + """, + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPKeyword("#"), + PPKeyword("endregion"), + Comment("//comment")); + } + + [Theory, CombinatorialData] + public async Task PP_DeclarationDirectives(TestHost testHost) + { + await TestAsync( + """ + #define A + #undef B + """, + testHost, + PPKeyword("#"), + PPKeyword("define"), + Identifier("A"), + PPKeyword("#"), + PPKeyword("undef"), + Identifier("B")); + } + + [Theory, CombinatorialData] + public async Task PP_IfElseEndIfDirectives(TestHost testHost) + { + var code = + """ + #if true + #elif DEBUG + #else + #endif + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("if"), + Keyword("true"), + PPKeyword("#"), + PPKeyword("elif"), + Identifier("DEBUG"), + PPKeyword("#"), + PPKeyword("else"), + PPKeyword("#"), + PPKeyword("endif")); + } + + [Theory, CombinatorialData] + public async Task PP_DefineDirective(TestHost testHost) + { + var code = @"#define GOO"; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("define"), + Identifier("GOO")); + } + + [Theory, CombinatorialData] + public async Task PP_DefineDirectiveWithCommentAndNoName(TestHost testHost) + { + var code = @"#define //Goo"; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("define"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_DefineDirectiveWithComment(TestHost testHost) + { + var code = @"#define GOO //Goo"; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("define"), + Identifier("GOO"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_UndefDirectives(TestHost testHost) + { + var code = @"#undef GOO"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("undef"), + Identifier("GOO")); + } + + [Theory, CombinatorialData] + public async Task PP_UndefDirectiveWithCommentAndNoName(TestHost testHost) + { + var code = @"#undef //Goo"; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("undef"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_UndefDirectiveWithComment(TestHost testHost) + { + var code = @"#undef GOO //Goo"; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("undef"), + Identifier("GOO"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_ErrorDirective(TestHost testHost) + { + var code = @"#error GOO"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("error"), + PPText("GOO")); + } + + [Theory, CombinatorialData] + public async Task PP_ErrorDirectiveWithComment(TestHost testHost) + { + var code = @"#error GOO //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("error"), + PPText("GOO //Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_WarningDirective(TestHost testHost) + { + var code = @"#warning GOO"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("warning"), + PPText("GOO")); + } + + [Theory, CombinatorialData] + public async Task PP_WarningDirectiveWithComment(TestHost testHost) + { + var code = @"#warning GOO //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("warning"), + PPText("GOO //Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_LineHidden(TestHost testHost) + { + var code = @"#line hidden"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + PPKeyword("hidden")); + } + + [Theory, CombinatorialData] + public async Task PP_LineHiddenWithComment(TestHost testHost) + { + var code = @"#line hidden //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + PPKeyword("hidden"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_LineDefault(TestHost testHost) + { + var code = @"#line default"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + PPKeyword("default")); + } + + [Theory, CombinatorialData] + public async Task PP_LineDefaultWithComment(TestHost testHost) + { + var code = @"#line default //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + PPKeyword("default"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_LineNumber(TestHost testHost) + { + var code = @"#line 100"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + Number("100")); + } + + [Theory, CombinatorialData] + public async Task PP_LineNumberWithComment(TestHost testHost) + { + var code = @"#line 100 //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + Number("100"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_LineNumberWithFilename(TestHost testHost) + { + var code = """ + #line 100 "C:\Goo" + """; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + Number("100"), + String(""" + "C:\Goo" + """)); + } + + [Theory, CombinatorialData] + public async Task PP_LineNumberWithFilenameAndComment(TestHost testHost) + { + var code = @"#line 100 ""C:\Goo"" //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + Number("100"), + String(""" + "C:\Goo" + """), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_LineSpanWithCharacterOffset(TestHost testHost) + { + var code = """ + #line (1, 2) - (3, 4) 5 "file.txt" + """; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + Punctuation.OpenParen, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.CloseParen, + Operators.Minus, + Punctuation.OpenParen, + Number("3"), + Punctuation.Comma, + Number("4"), + Punctuation.CloseParen, + Number("5"), + String(""" + "file.txt" + """)); + } + + [Theory, CombinatorialData] + public async Task PP_LineSpanWithComment(TestHost testHost) + { + var code = @"#line (1, 2) - (3, 4) """" //comment"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("line"), + Punctuation.OpenParen, + Number("1"), + Punctuation.Comma, + Number("2"), + Punctuation.CloseParen, + Operators.Minus, + Punctuation.OpenParen, + Number("3"), + Punctuation.Comma, + Number("4"), + Punctuation.CloseParen, + String(""" + "" + """), + Comment("//comment")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableEnable(TestHost testHost) + { + var code = @"#nullable enable"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("enable")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableEnableWithComment(TestHost testHost) + { + var code = @"#nullable enable //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("enable"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableEnableWarnings(TestHost testHost) + { + var code = @"#nullable enable warnings"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("enable"), + PPKeyword("warnings")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableEnableWarningsWithComment(TestHost testHost) + { + var code = @"#nullable enable warnings //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("enable"), + PPKeyword("warnings"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableEnableAnnotations(TestHost testHost) + { + var code = @"#nullable enable annotations"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("enable"), + PPKeyword("annotations")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableEnableAnnotationsWithComment(TestHost testHost) + { + var code = @"#nullable enable annotations //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("enable"), + PPKeyword("annotations"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableDisable(TestHost testHost) + { + var code = @"#nullable disable"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("disable")); + } + + [Theory, CombinatorialData] + public async Task PP_NullableDisableWithComment(TestHost testHost) + { + var code = @"#nullable disable //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("nullable"), + PPKeyword("disable"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaChecksum1(TestHost testHost) + { + await TestAsync( @"#pragma checksum stuff", - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("checksum"), - PPText("stuff")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaChecksum2(TestHost testHost) - { - await TestAsync( - """ - #pragma checksum "file.txt" "{00000000-0000-0000-0000-000000000000}" "2453" - """, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("checksum"), - String(""" - "file.txt" - """), - String(""" - "{00000000-0000-0000-0000-000000000000}" - """), - String(""" - "2453" - """)); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaChecksum3(TestHost testHost) - { - await TestAsync( + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("checksum"), + PPText("stuff")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaChecksum2(TestHost testHost) + { + await TestAsync( + """ + #pragma checksum "file.txt" "{00000000-0000-0000-0000-000000000000}" "2453" + """, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("checksum"), + String(""" + "file.txt" + """), + String(""" + "{00000000-0000-0000-0000-000000000000}" + """), + String(""" + "2453" + """)); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaChecksum3(TestHost testHost) + { + await TestAsync( @"#pragma checksum ""file.txt"" ""{00000000-0000-0000-0000-000000000000}"" ""2453"" // Goo", - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("checksum"), - String(""" - "file.txt" - """), - String(""" - "{00000000-0000-0000-0000-000000000000}" - """), - String(""" - "2453" - """), - Comment("// Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningDisableOne(TestHost testHost) - { - var code = @"#pragma warning disable 100"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("disable"), - Number("100")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningDisableOneWithComment(TestHost testHost) - { - var code = @"#pragma warning disable 100 //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("disable"), - Number("100"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30783")] - public async Task PP_PragmaWarningDisableAllWithComment(TestHost testHost) - { - var code = @"#pragma warning disable //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("disable"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningRestoreOne(TestHost testHost) - { - var code = @"#pragma warning restore 100"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("restore"), - Number("100")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningRestoreOneWithComment(TestHost testHost) - { - var code = @"#pragma warning restore 100 //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("restore"), - Number("100"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30783")] - public async Task PP_PragmaWarningRestoreAllWithComment(TestHost testHost) - { - var code = @"#pragma warning restore //Goo"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("restore"), - Comment("//Goo")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningDisableTwo(TestHost testHost) - { - var code = @"#pragma warning disable 100, 101"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("disable"), - Number("100"), - Punctuation.Comma, - Number("101")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningRestoreTwo(TestHost testHost) - { - var code = @"#pragma warning restore 100, 101"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("restore"), - Number("100"), - Punctuation.Comma, - Number("101")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningDisableThree(TestHost testHost) - { - var code = @"#pragma warning disable 100, 101, 102"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("disable"), - Number("100"), - Punctuation.Comma, - Number("101"), - Punctuation.Comma, - Number("102")); - } - - [Theory, CombinatorialData] - public async Task PP_PragmaWarningRestoreThree(TestHost testHost) - { - var code = @"#pragma warning restore 100, 101, 102"; - - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("pragma"), - PPKeyword("warning"), - PPKeyword("restore"), - Number("100"), - Punctuation.Comma, - Number("101"), - Punctuation.Comma, - Number("102")); - } - - [Theory, CombinatorialData] - public async Task DiscardInOutDeclaration(TestHost testHost) - { - await TestInMethodAsync( - code: @"M2(out var _);", - testHost: testHost, - expected: Classifications(Identifier("M2"), Punctuation.OpenParen, Keyword("out"), Identifier("var"), - Keyword("_"), Punctuation.CloseParen, Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task DiscardInCasePattern(TestHost testHost) - { - await TestInMethodAsync( - code: @"switch (1) { case int _: }", - testHost: testHost, - expected: Classifications(ControlKeyword("switch"), Punctuation.OpenParen, Number("1"), Punctuation.CloseParen, - Punctuation.OpenCurly, ControlKeyword("case"), Keyword("int"), Keyword("_"), Punctuation.Colon, Punctuation.CloseCurly)); - } - - [Theory, CombinatorialData] - public async Task DiscardInDeconstruction(TestHost testHost) - { - await TestInMethodAsync( - code: @"var (x, _) = (1, 2);", - testHost: testHost, - expected: Classifications(Identifier("var"), Punctuation.OpenParen, Local("x"), Punctuation.Comma, - Keyword("_"), Punctuation.CloseParen, Operators.Equals, Punctuation.OpenParen, Number("1"), - Punctuation.Comma, Number("2"), Punctuation.CloseParen, Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task DiscardInDeconstruction2(TestHost testHost) - { - await TestInMethodAsync( - code: @"(var _, var _) = (1, 2);", - testHost: testHost, - expected: Classifications(Punctuation.OpenParen, Identifier("var"), Keyword("_"), Punctuation.Comma, - Identifier("var"), Keyword("_"), Punctuation.CloseParen, Operators.Equals, Punctuation.OpenParen, - Number("1"), Punctuation.Comma, Number("2"), Punctuation.CloseParen, Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task ShortDiscardInDeconstruction(TestHost testHost) - { - await TestInMethodAsync( - code: @"int x; (_, x) = (1, 2);", - testHost: testHost, - expected: Classifications(Keyword("int"), Local("x"), Punctuation.Semicolon, Punctuation.OpenParen, - Identifier("_"), Punctuation.Comma, Identifier("x"), Punctuation.CloseParen, Operators.Equals, - Punctuation.OpenParen, Number("1"), Punctuation.Comma, Number("2"), Punctuation.CloseParen, - Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task ShortDiscardInOutDeclaration(TestHost testHost) - { - await TestInMethodAsync( - code: @"M2(out _);", - testHost: testHost, - expected: Classifications(Identifier("M2"), Punctuation.OpenParen, Keyword("out"), Identifier("_"), Punctuation.CloseParen, - Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task ShortDiscardInAssignment(TestHost testHost) - { - await TestInMethodAsync( - code: @"_ = 1;", - testHost: testHost, - expected: Classifications(Identifier("_"), Operators.Equals, Number("1"), Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task UnderscoreInLambda(TestHost testHost) - { - await TestInMethodAsync( - code: @"x = (_) => 1;", - testHost: testHost, - expected: Classifications(Identifier("x"), Operators.Equals, Punctuation.OpenParen, Parameter("_"), Punctuation.CloseParen, - Operators.EqualsGreaterThan, Number("1"), Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task DiscardInLambda(TestHost testHost) - { - await TestInMethodAsync( - code: @"x = (_, _) => 1;", - testHost: testHost, - expected: Classifications(Identifier("x"), Operators.Equals, Punctuation.OpenParen, Parameter("_"), Punctuation.Comma, Parameter("_"), Punctuation.CloseParen, - Operators.EqualsGreaterThan, Number("1"), Punctuation.Semicolon)); - } - - [Theory, CombinatorialData] - public async Task UnderscoreInAssignment(TestHost testHost) - { - await TestInMethodAsync(code: @"int _; _ = 1;", - testHost: testHost, - expected: Classifications(Keyword("int"), Local("_"), Punctuation.Semicolon, Identifier("_"), Operators.Equals, - Number("1"), Punctuation.Semicolon)); - } + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("checksum"), + String(""" + "file.txt" + """), + String(""" + "{00000000-0000-0000-0000-000000000000}" + """), + String(""" + "2453" + """), + Comment("// Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningDisableOne(TestHost testHost) + { + var code = @"#pragma warning disable 100"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("disable"), + Number("100")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningDisableOneWithComment(TestHost testHost) + { + var code = @"#pragma warning disable 100 //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("disable"), + Number("100"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30783")] + public async Task PP_PragmaWarningDisableAllWithComment(TestHost testHost) + { + var code = @"#pragma warning disable //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("disable"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningRestoreOne(TestHost testHost) + { + var code = @"#pragma warning restore 100"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("restore"), + Number("100")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningRestoreOneWithComment(TestHost testHost) + { + var code = @"#pragma warning restore 100 //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("restore"), + Number("100"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30783")] + public async Task PP_PragmaWarningRestoreAllWithComment(TestHost testHost) + { + var code = @"#pragma warning restore //Goo"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("restore"), + Comment("//Goo")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningDisableTwo(TestHost testHost) + { + var code = @"#pragma warning disable 100, 101"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("disable"), + Number("100"), + Punctuation.Comma, + Number("101")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningRestoreTwo(TestHost testHost) + { + var code = @"#pragma warning restore 100, 101"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("restore"), + Number("100"), + Punctuation.Comma, + Number("101")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningDisableThree(TestHost testHost) + { + var code = @"#pragma warning disable 100, 101, 102"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("disable"), + Number("100"), + Punctuation.Comma, + Number("101"), + Punctuation.Comma, + Number("102")); + } + + [Theory, CombinatorialData] + public async Task PP_PragmaWarningRestoreThree(TestHost testHost) + { + var code = @"#pragma warning restore 100, 101, 102"; + + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("pragma"), + PPKeyword("warning"), + PPKeyword("restore"), + Number("100"), + Punctuation.Comma, + Number("101"), + Punctuation.Comma, + Number("102")); + } + + [Theory, CombinatorialData] + public async Task DiscardInOutDeclaration(TestHost testHost) + { + await TestInMethodAsync( + code: @"M2(out var _);", + testHost: testHost, +expected: Classifications(Identifier("M2"), Punctuation.OpenParen, Keyword("out"), Identifier("var"), + Keyword("_"), Punctuation.CloseParen, Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task DiscardInCasePattern(TestHost testHost) + { + await TestInMethodAsync( + code: @"switch (1) { case int _: }", + testHost: testHost, +expected: Classifications(ControlKeyword("switch"), Punctuation.OpenParen, Number("1"), Punctuation.CloseParen, + Punctuation.OpenCurly, ControlKeyword("case"), Keyword("int"), Keyword("_"), Punctuation.Colon, Punctuation.CloseCurly)); + } + + [Theory, CombinatorialData] + public async Task DiscardInDeconstruction(TestHost testHost) + { + await TestInMethodAsync( + code: @"var (x, _) = (1, 2);", + testHost: testHost, +expected: Classifications(Identifier("var"), Punctuation.OpenParen, Local("x"), Punctuation.Comma, + Keyword("_"), Punctuation.CloseParen, Operators.Equals, Punctuation.OpenParen, Number("1"), + Punctuation.Comma, Number("2"), Punctuation.CloseParen, Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task DiscardInDeconstruction2(TestHost testHost) + { + await TestInMethodAsync( + code: @"(var _, var _) = (1, 2);", + testHost: testHost, +expected: Classifications(Punctuation.OpenParen, Identifier("var"), Keyword("_"), Punctuation.Comma, + Identifier("var"), Keyword("_"), Punctuation.CloseParen, Operators.Equals, Punctuation.OpenParen, + Number("1"), Punctuation.Comma, Number("2"), Punctuation.CloseParen, Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task ShortDiscardInDeconstruction(TestHost testHost) + { + await TestInMethodAsync( + code: @"int x; (_, x) = (1, 2);", + testHost: testHost, +expected: Classifications(Keyword("int"), Local("x"), Punctuation.Semicolon, Punctuation.OpenParen, + Identifier("_"), Punctuation.Comma, Identifier("x"), Punctuation.CloseParen, Operators.Equals, + Punctuation.OpenParen, Number("1"), Punctuation.Comma, Number("2"), Punctuation.CloseParen, + Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task ShortDiscardInOutDeclaration(TestHost testHost) + { + await TestInMethodAsync( + code: @"M2(out _);", + testHost: testHost, +expected: Classifications(Identifier("M2"), Punctuation.OpenParen, Keyword("out"), Identifier("_"), Punctuation.CloseParen, + Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task ShortDiscardInAssignment(TestHost testHost) + { + await TestInMethodAsync( + code: @"_ = 1;", + testHost: testHost, +expected: Classifications(Identifier("_"), Operators.Equals, Number("1"), Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task UnderscoreInLambda(TestHost testHost) + { + await TestInMethodAsync( + code: @"x = (_) => 1;", + testHost: testHost, +expected: Classifications(Identifier("x"), Operators.Equals, Punctuation.OpenParen, Parameter("_"), Punctuation.CloseParen, + Operators.EqualsGreaterThan, Number("1"), Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task DiscardInLambda(TestHost testHost) + { + await TestInMethodAsync( + code: @"x = (_, _) => 1;", + testHost: testHost, +expected: Classifications(Identifier("x"), Operators.Equals, Punctuation.OpenParen, Parameter("_"), Punctuation.Comma, Parameter("_"), Punctuation.CloseParen, + Operators.EqualsGreaterThan, Number("1"), Punctuation.Semicolon)); + } + + [Theory, CombinatorialData] + public async Task UnderscoreInAssignment(TestHost testHost) + { + await TestInMethodAsync(code: @"int _; _ = 1;", + testHost: testHost, +expected: Classifications(Keyword("int"), Local("_"), Punctuation.Semicolon, Identifier("_"), Operators.Equals, + Number("1"), Punctuation.Semicolon)); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs b/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs index 5007f46d0d7dc..fdd7586c87f48 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs @@ -11,7 +11,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Test.Utilities; @@ -20,133 +19,132 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +[UseExportProvider] +[Trait(Traits.Feature, Traits.Features.Classification)] +public class SyntacticTaggerTests { - [UseExportProvider] - [Trait(Traits.Feature, Traits.Features.Classification)] - public class SyntacticTaggerTests + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1032665")] + public async Task TestTagsChangedForPortionThatChanged() { - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1032665")] - public async Task TestTagsChangedForPortionThatChanged() - { - var code = - """ - class Program2 - { - string x = @"/// $$ - /// "; - } - """; - using var workspace = EditorTestWorkspace.CreateCSharp(code); - var document = workspace.Documents.First(); - var subjectBuffer = document.GetTextBuffer(); - - var checkpoint = new Checkpoint(); - - var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer( - new SyntacticClassificationTaggerProvider( - workspace.GetService(), - typeMap: null, - workspace.GetService(), - AsynchronousOperationListenerProvider.NullProvider), - subjectBuffer, - diffTimeout: TimeSpan.MaxValue); - - // Capture the expected value before the await, in case it changes. - var expectedLength = subjectBuffer.CurrentSnapshot.Length; - int? actualVersionNumber = null; - int? actualLength = null; - var callstacks = new List(); - tagComputer.TagsChanged += (s, e) => + var code = + """ + class Program2 { - actualVersionNumber = e.Span.Snapshot.Version.VersionNumber; - actualLength = e.Span.Length; - callstacks.Add(new StackTrace().ToString()); - checkpoint.Release(); - }; - - await checkpoint.Task; - Assert.Equal(0, actualVersionNumber); - Assert.Equal(expectedLength, actualLength); - Assert.Equal(1, callstacks.Count); - - checkpoint = new Checkpoint(); - - // Now apply an edit that require us to reclassify more that just the current line - var snapshot = subjectBuffer.Insert(document.CursorPosition.Value, """ - " - """); - expectedLength = snapshot.Length; - - // NOTE: TagsChanged is raised on the UI thread, so there is no race between - // assigning expected here and verifying in the event handler, because the - // event handler can't run until we await. - await checkpoint.Task; - Assert.Equal(1, actualVersionNumber); - Assert.Equal(37, actualLength); - Assert.Equal(2, callstacks.Count); - } - - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1032665")] - public async Task TestTagsChangedAfterDelete() + string x = @"/// $$ + /// "; + } + """; + using var workspace = EditorTestWorkspace.CreateCSharp(code); + var document = workspace.Documents.First(); + var subjectBuffer = document.GetTextBuffer(); + + var checkpoint = new Checkpoint(); + + var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer( + new SyntacticClassificationTaggerProvider( + workspace.GetService(), + typeMap: null, + workspace.GetService(), + AsynchronousOperationListenerProvider.NullProvider), + subjectBuffer, + diffTimeout: TimeSpan.MaxValue); + + // Capture the expected value before the await, in case it changes. + var expectedLength = subjectBuffer.CurrentSnapshot.Length; + int? actualVersionNumber = null; + int? actualLength = null; + var callstacks = new List(); + tagComputer.TagsChanged += (s, e) => { - var code = + actualVersionNumber = e.Span.Snapshot.Version.VersionNumber; + actualLength = e.Span.Length; + callstacks.Add(new StackTrace().ToString()); + checkpoint.Release(); + }; + + await checkpoint.Task; + Assert.Equal(0, actualVersionNumber); + Assert.Equal(expectedLength, actualLength); + Assert.Equal(1, callstacks.Count); + + checkpoint = new Checkpoint(); + + // Now apply an edit that require us to reclassify more that just the current line + var snapshot = subjectBuffer.Insert(document.CursorPosition.Value, """ + " + """); + expectedLength = snapshot.Length; + + // NOTE: TagsChanged is raised on the UI thread, so there is no race between + // assigning expected here and verifying in the event handler, because the + // event handler can't run until we await. + await checkpoint.Task; + Assert.Equal(1, actualVersionNumber); + Assert.Equal(37, actualLength); + Assert.Equal(2, callstacks.Count); + } + + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1032665")] + public async Task TestTagsChangedAfterDelete() + { + var code = @"class Goo"; - using var workspace = EditorTestWorkspace.CreateCSharp(code); - var document = workspace.Documents.First(); - var subjectBuffer = document.GetTextBuffer(); - - var checkpoint = new Checkpoint(); - - var typeMap = workspace.ExportProvider.GetExportedValue(); - - var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer( - new SyntacticClassificationTaggerProvider( - workspace.GetService(), - typeMap, - workspace.GetService(), - AsynchronousOperationListenerProvider.NullProvider), - subjectBuffer, - diffTimeout: TimeSpan.MaxValue); - - // Capture the expected value before the await, in case it changes. - var expectedLength = subjectBuffer.CurrentSnapshot.Length; - int? actualVersionNumber = null; - int? actualLength = null; - var callstacks = new List(); - tagComputer.TagsChanged += (s, e) => - { - actualVersionNumber = e.Span.Snapshot.Version.VersionNumber; - actualLength = e.Span.Length; - callstacks.Add(new StackTrace().ToString()); - checkpoint.Release(); - }; - - await checkpoint.Task; - Assert.Equal(0, actualVersionNumber); - Assert.Equal(expectedLength, actualLength); - Assert.Equal(1, callstacks.Count); - - checkpoint = new Checkpoint(); - - // Now delete the last character. - var snapshot = subjectBuffer.Delete(new Span(subjectBuffer.CurrentSnapshot.Length - 1, 1)); - - // Try to get the tags prior to TagsChanged firing. This will force us to use the previous data we've - // cached to produce the new results. We don't actually care about the tags, so we just pass an empty - // buffer for them to go into. - tagComputer.AddTags(new NormalizedSnapshotSpanCollection(subjectBuffer.CurrentSnapshot.GetFullSpan()), tags: []); - - expectedLength = snapshot.Length; - - // NOTE: TagsChanged is raised on the UI thread, so there is no race between - // assigning expected here and verifying in the event handler, because the - // event handler can't run until we await. - await checkpoint.Task; - - Assert.Equal(1, actualVersionNumber); - Assert.Equal(2, actualLength); - Assert.Equal(2, callstacks.Count); - } + using var workspace = EditorTestWorkspace.CreateCSharp(code); + var document = workspace.Documents.First(); + var subjectBuffer = document.GetTextBuffer(); + + var checkpoint = new Checkpoint(); + + var typeMap = workspace.ExportProvider.GetExportedValue(); + + var tagComputer = new SyntacticClassificationTaggerProvider.TagComputer( + new SyntacticClassificationTaggerProvider( + workspace.GetService(), + typeMap, + workspace.GetService(), + AsynchronousOperationListenerProvider.NullProvider), + subjectBuffer, + diffTimeout: TimeSpan.MaxValue); + + // Capture the expected value before the await, in case it changes. + var expectedLength = subjectBuffer.CurrentSnapshot.Length; + int? actualVersionNumber = null; + int? actualLength = null; + var callstacks = new List(); + tagComputer.TagsChanged += (s, e) => + { + actualVersionNumber = e.Span.Snapshot.Version.VersionNumber; + actualLength = e.Span.Length; + callstacks.Add(new StackTrace().ToString()); + checkpoint.Release(); + }; + + await checkpoint.Task; + Assert.Equal(0, actualVersionNumber); + Assert.Equal(expectedLength, actualLength); + Assert.Equal(1, callstacks.Count); + + checkpoint = new Checkpoint(); + + // Now delete the last character. + var snapshot = subjectBuffer.Delete(new Span(subjectBuffer.CurrentSnapshot.Length - 1, 1)); + + // Try to get the tags prior to TagsChanged firing. This will force us to use the previous data we've + // cached to produce the new results. We don't actually care about the tags, so we just pass an empty + // buffer for them to go into. + tagComputer.AddTags(new NormalizedSnapshotSpanCollection(subjectBuffer.CurrentSnapshot.GetFullSpan()), tags: []); + + expectedLength = snapshot.Length; + + // NOTE: TagsChanged is raised on the UI thread, so there is no race between + // assigning expected here and verifying in the event handler, because the + // event handler can't run until we await. + await checkpoint.Task; + + Assert.Equal(1, actualVersionNumber); + Assert.Equal(2, actualLength); + Assert.Equal(2, callstacks.Count); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs index 49882a1d009c9..bd39495cad153 100644 --- a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs @@ -2,7 +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. -using System; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -10,7 +9,6 @@ using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Classification; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Remote.Testing; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -25,2260 +23,2260 @@ using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +[Trait(Traits.Feature, Traits.Features.Classification)] +public partial class TotalClassifierTests : AbstractCSharpClassifierTests { - [Trait(Traits.Feature, Traits.Features.Classification)] - public partial class TotalClassifierTests : AbstractCSharpClassifierTests + protected override async Task> GetClassificationSpansAsync(string code, ImmutableArray spans, ParseOptions? options, TestHost testHost) { - protected override async Task> GetClassificationSpansAsync(string code, ImmutableArray spans, ParseOptions? options, TestHost testHost) - { - using var workspace = CreateWorkspace(code, options, testHost); - var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id); + using var workspace = CreateWorkspace(code, options, testHost); + var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id); - return await GetAllClassificationsAsync(document, spans); - } + return await GetAllClassificationsAsync(document, spans); + } - [Theory, CombinatorialData] - public async Task VarAsUsingAliasForNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task VarAsUsingAliasForNamespace(TestHost testHost) + { + await TestAsync( @"using var = System;", - testHost, - Keyword("using"), - Namespace("var"), - Operators.Equals, - Namespace("System"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/547068")] - public async Task Bug17819(TestHost testHost) - { - await TestAsync( - """ - _ _() - { - } - /// where where : partial - { - static dynamic dynamic() - { - return dynamic(); - } - } - """; - await TestAsync(code, - testHost, - Keyword("partial"), - Keyword("class"), - Class("partial"), - Punctuation.OpenAngle, - TypeParameter("where"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("where"), - Punctuation.Colon, - Class("partial"), - Punctuation.OpenAngle, - TypeParameter("where"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Keyword("static"), - Keyword("dynamic"), - Method("dynamic"), - Static("dynamic"), - Punctuation.OpenAngle, - TypeParameter("partial"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Method("dynamic"), - Static("dynamic"), - Punctuation.OpenAngle, - Keyword("dynamic"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543123")] - public async Task VarInForeach(TestHost testHost) - { - await TestInMethodAsync(@"foreach (var v in args) { }", - testHost, - ControlKeyword("foreach"), - Punctuation.OpenParen, - Keyword("var"), - Local("v"), - ControlKeyword("in"), - Identifier("args"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task ValueInSetterAndAnonymousTypePropertyName(TestHost testHost) - { - await TestAsync( - """ - class C - { - int P - { - set - { - var t = new { value = value }; - } - } - } - """, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("int"), - Property("P"), - Punctuation.OpenCurly, - Keyword("set"), - Punctuation.OpenCurly, - Keyword("var"), - Local("t"), - Operators.Equals, - Keyword("new"), - Punctuation.OpenCurly, - Property("value"), - Operators.Equals, - Keyword("value"), - Punctuation.CloseCurly, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestValueInEvent(TestHost testHost) - { - await TestInClassAsync( - """ - event int Bar - { - add - { - this.value = value; - } + testHost, + Keyword("using"), + Namespace("IO"), + Operators.Equals, + Keyword("global"), + Operators.ColonColon, + Namespace("System"), + Operators.Dot, + Namespace("IO"), + Punctuation.Semicolon); + } - remove - { - this.value = value; - } - } - """, - testHost, - Keyword("event"), - Keyword("int"), - Event("Bar"), - Punctuation.OpenCurly, - Keyword("add"), - Punctuation.OpenCurly, - Keyword("this"), - Operators.Dot, - Identifier("value"), - Operators.Equals, - Keyword("value"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - - Keyword("remove"), - Punctuation.OpenCurly, - Keyword("this"), - Operators.Dot, - Identifier("value"), - Operators.Equals, - Keyword("value"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestValueInProperty(TestHost testHost) - { - await TestInClassAsync( - """ - int Goo - { - get - { - this.value = value; - } + [Theory, CombinatorialData] + public async Task PartialDynamicWhere(TestHost testHost) + { + var code = """ + partial class partial where where : partial + { + static dynamic dynamic() + { + return dynamic(); + } + } + """; + await TestAsync(code, + testHost, + Keyword("partial"), + Keyword("class"), + Class("partial"), + Punctuation.OpenAngle, + TypeParameter("where"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("where"), + Punctuation.Colon, + Class("partial"), + Punctuation.OpenAngle, + TypeParameter("where"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Keyword("static"), + Keyword("dynamic"), + Method("dynamic"), + Static("dynamic"), + Punctuation.OpenAngle, + TypeParameter("partial"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("return"), + Method("dynamic"), + Static("dynamic"), + Punctuation.OpenAngle, + Keyword("dynamic"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - set - { - this.value = value; - } - } - """, - testHost, - Keyword("int"), - Property("Goo"), - Punctuation.OpenCurly, - Keyword("get"), - Punctuation.OpenCurly, - Keyword("this"), - Operators.Dot, - Identifier("value"), - Operators.Equals, - Identifier("value"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - - Keyword("set"), - Punctuation.OpenCurly, - Keyword("this"), - Operators.Dot, - Identifier("value"), - Operators.Equals, - Keyword("value"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task ValueFieldInSetterAccessedThroughThis(TestHost testHost) - { - await TestInClassAsync( - """ + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543123")] + public async Task VarInForeach(TestHost testHost) + { + await TestInMethodAsync(@"foreach (var v in args) { }", + testHost, + ControlKeyword("foreach"), + Punctuation.OpenParen, + Keyword("var"), + Local("v"), + ControlKeyword("in"), + Identifier("args"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task ValueInSetterAndAnonymousTypePropertyName(TestHost testHost) + { + await TestAsync( + """ + class C + { int P { set { - this.value = value; + var t = new { value = value }; } } - """, - testHost, - Keyword("int"), - Property("P"), - Punctuation.OpenCurly, - Keyword("set"), - Punctuation.OpenCurly, - Keyword("this"), - Operators.Dot, - Identifier("value"), - Operators.Equals, - Keyword("value"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task NewOfInterface(TestHost testHost) - { - await TestInMethodAsync( + } + """, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("int"), + Property("P"), + Punctuation.OpenCurly, + Keyword("set"), + Punctuation.OpenCurly, + Keyword("var"), + Local("t"), + Operators.Equals, + Keyword("new"), + Punctuation.OpenCurly, + Property("value"), + Operators.Equals, + Keyword("value"), + Punctuation.CloseCurly, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestValueInEvent(TestHost testHost) + { + await TestInClassAsync( + """ + event int Bar + { + add + { + this.value = value; + } + + remove + { + this.value = value; + } + } + """, + testHost, + Keyword("event"), + Keyword("int"), + Event("Bar"), + Punctuation.OpenCurly, + Keyword("add"), + Punctuation.OpenCurly, + Keyword("this"), + Operators.Dot, + Identifier("value"), + Operators.Equals, + Keyword("value"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + + Keyword("remove"), + Punctuation.OpenCurly, + Keyword("this"), + Operators.Dot, + Identifier("value"), + Operators.Equals, + Keyword("value"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestValueInProperty(TestHost testHost) + { + await TestInClassAsync( + """ + int Goo + { + get + { + this.value = value; + } + + set + { + this.value = value; + } + } + """, + testHost, + Keyword("int"), + Property("Goo"), + Punctuation.OpenCurly, + Keyword("get"), + Punctuation.OpenCurly, + Keyword("this"), + Operators.Dot, + Identifier("value"), + Operators.Equals, + Identifier("value"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + + Keyword("set"), + Punctuation.OpenCurly, + Keyword("this"), + Operators.Dot, + Identifier("value"), + Operators.Equals, + Keyword("value"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task ValueFieldInSetterAccessedThroughThis(TestHost testHost) + { + await TestInClassAsync( + """ + int P + { + set + { + this.value = value; + } + } + """, + testHost, + Keyword("int"), + Property("P"), + Punctuation.OpenCurly, + Keyword("set"), + Punctuation.OpenCurly, + Keyword("this"), + Operators.Dot, + Identifier("value"), + Operators.Equals, + Keyword("value"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task NewOfInterface(TestHost testHost) + { + await TestInMethodAsync( @"object o = new System.IDisposable();", - testHost, - Keyword("object"), - Local("o"), - Operators.Equals, - Keyword("new"), - Namespace("System"), - Operators.Dot, - Interface("IDisposable"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545611")] - [CombinatorialData] - public async Task TestVarConstructor(TestHost testHost) - { - await TestAsync( - """ - class var - { - void Main() - { - new var(); - } - } - """, - testHost, - Keyword("class"), - Class("var"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Main"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("new"), - Class("var"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545609")] - [CombinatorialData] - public async Task TestVarTypeParameter(TestHost testHost) - { - await TestAsync( - """ - class X - { - void Goo() - { - var x; - } - } - """, - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Goo"), - Punctuation.OpenAngle, - TypeParameter("var"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("x"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545610")] - [CombinatorialData] - public async Task TestVarAttribute1(TestHost testHost) - { - await TestAsync( - """ - using System; + testHost, + Keyword("object"), + Local("o"), + Operators.Equals, + Keyword("new"), + Namespace("System"), + Operators.Dot, + Interface("IDisposable"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon); + } - [var] - class var : Attribute - { - } - """, - testHost, - Keyword("using"), - Namespace("System"), - Punctuation.Semicolon, - Punctuation.OpenBracket, - Class("var"), - Punctuation.CloseBracket, - Keyword("class"), - Class("var"), - Punctuation.Colon, - Class("Attribute"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545610")] - [CombinatorialData] - public async Task TestVarAttribute2(TestHost testHost) - { - await TestAsync( - """ - using System; + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545611")] + [CombinatorialData] + public async Task TestVarConstructor(TestHost testHost) + { + await TestAsync( + """ + class var + { + void Main() + { + new var(); + } + } + """, + testHost, + Keyword("class"), + Class("var"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Main"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("new"), + Class("var"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - [var] - class varAttribute : Attribute - { - } - """, - testHost, - Keyword("using"), - Namespace("System"), - Punctuation.Semicolon, - Punctuation.OpenBracket, - Class("var"), - Punctuation.CloseBracket, - Keyword("class"), - Class("varAttribute"), - Punctuation.Colon, - Class("Attribute"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546170")] - [CombinatorialData] - public async Task TestStandaloneTypeName(TestHost testHost) - { - await TestAsync( - """ - using System; + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545609")] + [CombinatorialData] + public async Task TestVarTypeParameter(TestHost testHost) + { + await TestAsync( + """ + class X + { + void Goo() + { + var x; + } + } + """, + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Goo"), + Punctuation.OpenAngle, + TypeParameter("var"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("x"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - class C - { - static void Main() - { - var tree = Console - } - } - """, - testHost, - Keyword("using"), - Namespace("System"), - Punctuation.Semicolon, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("static"), - Keyword("void"), - Method("Main"), - Static("Main"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("tree"), - Operators.Equals, - Class("Console"), - Static("Console"), - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546403")] - [CombinatorialData] - public async Task TestNamespaceClassAmbiguities(TestHost testHost) - { - await TestAsync( - """ - class C - { - } + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545610")] + [CombinatorialData] + public async Task TestVarAttribute1(TestHost testHost) + { + await TestAsync( + """ + using System; - namespace C - { - } - """, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("namespace"), - Namespace("C"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task NameAttributeValue(TestHost testHost) - { - await TestAsync( - """ - class Program - { - /// - void Goo(int x) - { - } - } - """, - testHost, - Keyword("class"), - Class("Program"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("param"), - XmlDoc.AttributeName("name"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(""" - " - """), - Parameter("x"), - XmlDoc.AttributeQuotes(""" - " - """), - XmlDoc.Delimiter("/>"), - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task Cref1(TestHost testHost) - { - await TestAsync( - """ - /// - class Program - { - void Goo() - { - } - } - """, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("see"), - XmlDoc.AttributeName("cref"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(""" - " - """), - Class("Program"), - Punctuation.OpenCurly, - TypeParameter("T"), - Punctuation.CloseCurly, - XmlDoc.AttributeQuotes(""" - " - """), - XmlDoc.Delimiter("/>"), - Keyword("class"), - Class("Program"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task CrefNamespaceIsNotClass(TestHost testHost) - { - await TestAsync( - """ - /// - namespace N + [var] + class var : Attribute + { + } + """, + testHost, + Keyword("using"), + Namespace("System"), + Punctuation.Semicolon, + Punctuation.OpenBracket, + Class("var"), + Punctuation.CloseBracket, + Keyword("class"), + Class("var"), + Punctuation.Colon, + Class("Attribute"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545610")] + [CombinatorialData] + public async Task TestVarAttribute2(TestHost testHost) + { + await TestAsync( + """ + using System; + + [var] + class varAttribute : Attribute + { + } + """, + testHost, + Keyword("using"), + Namespace("System"), + Punctuation.Semicolon, + Punctuation.OpenBracket, + Class("var"), + Punctuation.CloseBracket, + Keyword("class"), + Class("varAttribute"), + Punctuation.Colon, + Class("Attribute"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546170")] + [CombinatorialData] + public async Task TestStandaloneTypeName(TestHost testHost) + { + await TestAsync( + """ + using System; + + class C + { + static void Main() + { + var tree = Console + } + } + """, + testHost, + Keyword("using"), + Namespace("System"), + Punctuation.Semicolon, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("static"), + Keyword("void"), + Method("Main"), + Static("Main"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("var"), + Local("tree"), + Operators.Equals, + Class("Console"), + Static("Console"), + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546403")] + [CombinatorialData] + public async Task TestNamespaceClassAmbiguities(TestHost testHost) + { + await TestAsync( + """ + class C + { + } + + namespace C + { + } + """, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("namespace"), + Namespace("C"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task NameAttributeValue(TestHost testHost) + { + await TestAsync( + """ + class Program + { + /// + void Goo(int x) + { + } + } + """, + testHost, + Keyword("class"), + Class("Program"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("param"), + XmlDoc.AttributeName("name"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(""" + " + """), + Parameter("x"), + XmlDoc.AttributeQuotes(""" + " + """), + XmlDoc.Delimiter("/>"), + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task Cref1(TestHost testHost) + { + await TestAsync( + """ + /// + class Program + { + void Goo() + { + } + } + """, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("see"), + XmlDoc.AttributeName("cref"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(""" + " + """), + Class("Program"), + Punctuation.OpenCurly, + TypeParameter("T"), + Punctuation.CloseCurly, + XmlDoc.AttributeQuotes(""" + " + """), + XmlDoc.Delimiter("/>"), + Keyword("class"), + Class("Program"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task CrefNamespaceIsNotClass(TestHost testHost) + { + await TestAsync( + """ + /// + namespace N + { + class Program { - class Program - { - } } - """, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("see"), - XmlDoc.AttributeName("cref"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(""" - " - """), - Namespace("N"), - XmlDoc.AttributeQuotes(""" - " - """), - XmlDoc.Delimiter("/>"), - Keyword("namespace"), - Namespace("N"), - Punctuation.OpenCurly, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task InterfacePropertyWithSameNameShouldBePreferredToType(TestHost testHost) - { - await TestAsync( - """ - interface IGoo - { - int IGoo { get; set; } + } + """, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("see"), + XmlDoc.AttributeName("cref"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(""" + " + """), + Namespace("N"), + XmlDoc.AttributeQuotes(""" + " + """), + XmlDoc.Delimiter("/>"), + Keyword("namespace"), + Namespace("N"), + Punctuation.OpenCurly, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - void Bar(int x = IGoo); - } - """, - testHost, - Keyword("interface"), - Interface("IGoo"), - Punctuation.OpenCurly, - Keyword("int"), - Property("IGoo"), - Punctuation.OpenCurly, - Keyword("get"), - Punctuation.Semicolon, - Keyword("set"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("void"), - Method("Bar"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Operators.Equals, - Property("IGoo"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/633")] - public async Task XmlDocCref(TestHost testHost) - { - await TestAsync( - """ - /// - /// - /// - class MyClass + [Theory, CombinatorialData] + public async Task InterfacePropertyWithSameNameShouldBePreferredToType(TestHost testHost) + { + await TestAsync( + """ + interface IGoo + { + int IGoo { get; set; } + + void Bar(int x = IGoo); + } + """, + testHost, + Keyword("interface"), + Interface("IGoo"), + Punctuation.OpenCurly, + Keyword("int"), + Property("IGoo"), + Punctuation.OpenCurly, + Keyword("get"), + Punctuation.Semicolon, + Keyword("set"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("void"), + Method("Bar"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Operators.Equals, + Property("IGoo"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/633")] + public async Task XmlDocCref(TestHost testHost) + { + await TestAsync( + """ + /// + /// + /// + class MyClass + { + public MyClass(int x) + { + } + } + """, + testHost, + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("summary"), + XmlDoc.Delimiter(">"), + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter("<"), + XmlDoc.Name("see"), + XmlDoc.AttributeName("cref"), + XmlDoc.Delimiter("="), + XmlDoc.AttributeQuotes(""" + " + """), + Class("MyClass"), + Operators.Dot, + Class("MyClass"), + Punctuation.OpenParen, + Keyword("int"), + Punctuation.CloseParen, + XmlDoc.AttributeQuotes(""" + " + """), + XmlDoc.Delimiter("/>"), + XmlDoc.Delimiter("///"), + XmlDoc.Text(" "), + XmlDoc.Delimiter(""), + Keyword("class"), + Class("MyClass"), + Punctuation.OpenCurly, + Keyword("public"), + Class("MyClass"), + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestGenericTypeWithNoArity(TestHost testHost) + { + await TestAsync( + """ + using System.Collections.Generic; + + class Program : IReadOnlyCollection + { + } + """, + testHost, + Keyword("using"), + Namespace("System"), + Operators.Dot, + Namespace("Collections"), + Operators.Dot, + Namespace("Generic"), + Punctuation.Semicolon, + Keyword("class"), + Class("Program"), + Punctuation.Colon, + Interface("IReadOnlyCollection"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestGenericTypeWithWrongArity(TestHost testHost) + { + await TestAsync( + """ + using System.Collections.Generic; + + class Program : IReadOnlyCollection + { + } + """, + testHost, + Keyword("using"), + Namespace("System"), + Operators.Dot, + Namespace("Collections"), + Operators.Dot, + Namespace("Generic"), + Punctuation.Semicolon, + Keyword("class"), + Class("Program"), + Punctuation.Colon, + Interface("IReadOnlyCollection"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.Comma, + Keyword("string"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestExtensionMethodDeclaration(TestHost testHost) + { + await TestAsync( + """ + static class ExtMethod + { + public static void TestMethod(this C c) + { + } + } + """, + testHost, + Keyword("static"), + Keyword("class"), + Class("ExtMethod"), + Static("ExtMethod"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + ExtensionMethod("TestMethod"), + Static("TestMethod"), + Punctuation.OpenParen, + Keyword("this"), + Identifier("C"), + Parameter("c"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestExtensionMethodUsage(TestHost testHost) + { + await TestAsync( + """ + static class ExtMethod + { + public static void TestMethod(this C c) { - public MyClass(int x) - { - } } - """, - testHost, - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("summary"), - XmlDoc.Delimiter(">"), - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter("<"), - XmlDoc.Name("see"), - XmlDoc.AttributeName("cref"), - XmlDoc.Delimiter("="), - XmlDoc.AttributeQuotes(""" - " - """), - Class("MyClass"), - Operators.Dot, - Class("MyClass"), - Punctuation.OpenParen, - Keyword("int"), - Punctuation.CloseParen, - XmlDoc.AttributeQuotes(""" - " - """), - XmlDoc.Delimiter("/>"), - XmlDoc.Delimiter("///"), - XmlDoc.Text(" "), - XmlDoc.Delimiter(""), - Keyword("class"), - Class("MyClass"), - Punctuation.OpenCurly, - Keyword("public"), - Class("MyClass"), - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestGenericTypeWithNoArity(TestHost testHost) - { - await TestAsync( - """ - using System.Collections.Generic; + } + + class C + { + void Test() + { + ExtMethod.TestMethod(new C()); + new C().TestMethod(); + } + } + """, + testHost, + ParseOptions(Options.Regular), + Keyword("static"), + Keyword("class"), + Class("ExtMethod"), + Static("ExtMethod"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("static"), + Keyword("void"), + ExtensionMethod("TestMethod"), + Static("TestMethod"), + Punctuation.OpenParen, + Keyword("this"), + Class("C"), + Parameter("c"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Test"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Class("ExtMethod"), + Static("ExtMethod"), + Operators.Dot, + Method("TestMethod"), + Static("TestMethod"), + Punctuation.OpenParen, + Keyword("new"), + Class("C"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("new"), + Class("C"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Operators.Dot, + ExtensionMethod("TestMethod"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestConstLocals(TestHost testHost) + { + await TestInMethodAsync( + """ + const int Number = 42; + var x = Number; + """, + testHost, + Keyword("const"), + Keyword("int"), + Constant("Number"), + Static("Number"), + Operators.Equals, + Number("42"), + Punctuation.Semicolon, + Keyword("var"), + Local("x"), + Operators.Equals, + Constant("Number"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_InsideMethod(TestHost testHost) + { + await TestInMethodAsync(""" + var unmanaged = 0; + unmanaged++; + """, + testHost, + Keyword("var"), + Local("unmanaged"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + Local("unmanaged"), + Operators.PlusPlus, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_Keyword(TestHost testHost) + { + await TestAsync( + "class X where T : unmanaged { }", + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + class X where T : unmanaged { } + """, + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { + interface unmanaged {} + } + class X where T : unmanaged { } + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void M() where T : unmanaged { } + } + """, + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + class X + { + void M() where T : unmanaged { } + } + """, + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { + interface unmanaged {} + } + class X + { + void M() where T : unmanaged { } + } + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - class Program : IReadOnlyCollection - { - } - """, - testHost, - Keyword("using"), - Namespace("System"), - Operators.Dot, - Namespace("Collections"), - Operators.Dot, - Namespace("Generic"), - Punctuation.Semicolon, - Keyword("class"), - Class("Program"), - Punctuation.Colon, - Interface("IReadOnlyCollection"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestGenericTypeWithWrongArity(TestHost testHost) - { - await TestAsync( - """ - using System.Collections.Generic; + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_Keyword(TestHost testHost) + { + await TestAsync( + "delegate void D() where T : unmanaged;", + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.Semicolon); + } - class Program : IReadOnlyCollection - { - } - """, - testHost, - Keyword("using"), - Namespace("System"), - Operators.Dot, - Namespace("Collections"), - Operators.Dot, - Namespace("Generic"), - Punctuation.Semicolon, - Keyword("class"), - Class("Program"), - Punctuation.Colon, - Interface("IReadOnlyCollection"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.Comma, - Keyword("string"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestExtensionMethodDeclaration(TestHost testHost) - { - await TestAsync( - """ - static class ExtMethod - { - public static void TestMethod(this C c) - { - } - } - """, - testHost, - Keyword("static"), - Keyword("class"), - Class("ExtMethod"), - Static("ExtMethod"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - ExtensionMethod("TestMethod"), - Static("TestMethod"), - Punctuation.OpenParen, - Keyword("this"), - Identifier("C"), - Parameter("c"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestExtensionMethodUsage(TestHost testHost) - { - await TestAsync( - """ - static class ExtMethod - { - public static void TestMethod(this C c) - { - } - } + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + delegate void D() where T : unmanaged; + """, + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.Semicolon); + } - class C - { - void Test() - { - ExtMethod.TestMethod(new C()); - new C().TestMethod(); - } - } - """, - testHost, - ParseOptions(Options.Regular), - Keyword("static"), - Keyword("class"), - Class("ExtMethod"), - Static("ExtMethod"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Keyword("void"), - ExtensionMethod("TestMethod"), - Static("TestMethod"), - Punctuation.OpenParen, - Keyword("this"), - Class("C"), - Parameter("c"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Test"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Class("ExtMethod"), - Static("ExtMethod"), - Operators.Dot, - Method("TestMethod"), - Static("TestMethod"), - Punctuation.OpenParen, - Keyword("new"), - Class("C"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("new"), - Class("C"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Operators.Dot, - ExtensionMethod("TestMethod"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestConstLocals(TestHost testHost) - { - await TestInMethodAsync( - """ - const int Number = 42; - var x = Number; - """, - testHost, - Keyword("const"), - Keyword("int"), - Constant("Number"), - Static("Number"), - Operators.Equals, - Number("42"), - Punctuation.Semicolon, - Keyword("var"), - Local("x"), - Operators.Equals, - Constant("Number"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_InsideMethod(TestHost testHost) - { - await TestInMethodAsync(""" - var unmanaged = 0; - unmanaged++; - """, - testHost, - Keyword("var"), - Local("unmanaged"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - Local("unmanaged"), - Operators.PlusPlus, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_Keyword(TestHost testHost) - { - await TestAsync( - "class X where T : unmanaged { }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_ExistingInterface(TestHost testHost) - { - await TestAsync(""" - interface unmanaged {} - class X where T : unmanaged { } - """, - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - class X where T : unmanaged { } - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void M() where T : unmanaged { } - } - """, - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface unmanaged {} - class X + } + delegate void D() where T : unmanaged; + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { void M() where T : unmanaged { } } - """, - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - class X + } + """, + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface unmanaged {} + class X + { + void N() { void M() where T : unmanaged { } } - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_Keyword(TestHost testHost) - { - await TestAsync( - "delegate void D() where T : unmanaged;", - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_ExistingInterface(TestHost testHost) - { - await TestAsync(""" - interface unmanaged {} - delegate void D() where T : unmanaged; - """, - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - delegate void D() where T : unmanaged; - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void N() - { - void M() where T : unmanaged { } - } - } - """, - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + } + """, + testHost, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface unmanaged {} - class X - { - void N() - { - void M() where T : unmanaged { } - } - } - """, - testHost, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestUnmanagedConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface unmanaged {} - } - class X + } + class X + { + void N() { - void N() - { - void M() where T : unmanaged { } - } + void M() where T : unmanaged { } } - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("unmanaged"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] - [CombinatorialData] - public async Task TestOperatorOverloading(TestHost testHost) - { - await TestAsync(""" - class C + } + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("unmanaged"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/29492")] + [CombinatorialData] + public async Task TestOperatorOverloading(TestHost testHost) + { + await TestAsync(""" + class C + { + void M() { - void M() - { - var a = 1 + 1; - var b = new True() + new True(); - } + var a = 1 + 1; + var b = new True() + new True(); } - class True + } + class True + { + public static True operator +(True a, True b) { - public static True operator +(True a, True b) - { - return new True(); - } + return new True(); } - """, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("var"), - Local("a"), - Operators.Equals, - Number("1"), - Operators.Plus, - Number("1"), - Punctuation.Semicolon, - Keyword("var"), - Local("b"), - Operators.Equals, - Keyword("new"), - Class("True"), - Punctuation.OpenParen, - Punctuation.CloseParen, - OverloadedOperators.Plus, - Keyword("new"), - Class("True"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("True"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("static"), - Class("True"), - Keyword("operator"), - Operators.Plus, - Punctuation.OpenParen, - Class("True"), - Parameter("a"), - Punctuation.Comma, - Class("True"), - Parameter("b"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Keyword("new"), - Class("True"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_InsideMethod(TestHost testHost) - { - await TestInMethodAsync(""" - var notnull = 0; - notnull++; - """, - testHost, - Keyword("var"), - Local("notnull"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - Local("notnull"), - Operators.PlusPlus, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_Keyword(TestHost testHost) - { - await TestAsync( - "class X where T : notnull { }", - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + } + """, +testHost, +Keyword("class"), +Class("C"), +Punctuation.OpenCurly, +Keyword("void"), +Method("M"), +Punctuation.OpenParen, +Punctuation.CloseParen, +Punctuation.OpenCurly, +Keyword("var"), +Local("a"), +Operators.Equals, +Number("1"), +Operators.Plus, +Number("1"), +Punctuation.Semicolon, +Keyword("var"), +Local("b"), +Operators.Equals, +Keyword("new"), +Class("True"), +Punctuation.OpenParen, +Punctuation.CloseParen, +OverloadedOperators.Plus, +Keyword("new"), +Class("True"), +Punctuation.OpenParen, +Punctuation.CloseParen, +Punctuation.Semicolon, +Punctuation.CloseCurly, +Punctuation.CloseCurly, +Keyword("class"), +Class("True"), +Punctuation.OpenCurly, +Keyword("public"), +Keyword("static"), +Class("True"), +Keyword("operator"), +Operators.Plus, +Punctuation.OpenParen, +Class("True"), +Parameter("a"), +Punctuation.Comma, +Class("True"), +Parameter("b"), +Punctuation.CloseParen, +Punctuation.OpenCurly, +ControlKeyword("return"), +Keyword("new"), +Class("True"), +Punctuation.OpenParen, +Punctuation.CloseParen, +Punctuation.Semicolon, +Punctuation.CloseCurly, +Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_InsideMethod(TestHost testHost) + { + await TestInMethodAsync(""" + var notnull = 0; + notnull++; + """, + testHost, + Keyword("var"), + Local("notnull"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + Local("notnull"), + Operators.PlusPlus, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_Keyword(TestHost testHost) + { + await TestAsync( + "class X where T : notnull { }", + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + class X where T : notnull { } + """, + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface notnull {} - class X where T : notnull { } - """, - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Type_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - class X where T : notnull { } - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void M() where T : notnull { } - } - """, - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + } + class X where T : notnull { } + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void M() where T : notnull { } + } + """, + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + class X + { + void M() where T : notnull { } + } + """, + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { + interface notnull {} + } + class X + { + void M() where T : notnull { } + } + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_Keyword(TestHost testHost) + { + await TestAsync( + "delegate void D() where T : notnull;", + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + delegate void D() where T : notnull; + """, + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface notnull {} - class X + } + delegate void D() where T : notnull; + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("delegate"), + Keyword("void"), + Delegate("D"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_Keyword(TestHost testHost) + { + await TestAsync(""" + class X + { + void N() { void M() where T : notnull { } } - """, - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Method_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - class X + } + """, + testHost, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_ExistingInterface(TestHost testHost) + { + await TestAsync(""" + interface notnull {} + class X + { + void N() { void M() where T : notnull { } } - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_Keyword(TestHost testHost) - { - await TestAsync( - "delegate void D() where T : notnull;", - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_ExistingInterface(TestHost testHost) - { - await TestAsync(""" - interface notnull {} - delegate void D() where T : notnull; - """, - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_Delegate_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - delegate void D() where T : notnull; - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("delegate"), - Keyword("void"), - Delegate("D"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_Keyword(TestHost testHost) - { - await TestAsync(""" - class X - { - void N() - { - void M() where T : notnull { } - } - } - """, - testHost, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_ExistingInterface(TestHost testHost) - { - await TestAsync(""" + } + """, + testHost, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestNotNullConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) + { + await TestAsync(""" + namespace OtherScope + { interface notnull {} - class X - { - void N() - { - void M() where T : notnull { } - } - } - """, - testHost, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestNotNullConstraint_LocalFunction_ExistingInterfaceButOutOfScope(TestHost testHost) - { - await TestAsync(""" - namespace OtherScope - { - interface notnull {} - } - class X + } + class X + { + void N() { - void N() - { - void M() where T : notnull { } - } + void M() where T : notnull { } } - """, - testHost, - Keyword("namespace"), - Namespace("OtherScope"), - Punctuation.OpenCurly, - Keyword("interface"), - Interface("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("X"), - Punctuation.OpenCurly, - Keyword("void"), - Method("N"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("void"), - Method("M"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("notnull"), - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/10174")] - [CombinatorialData] - public async Task VarInPropertyPattern(TestHost testHost) - { - await TestAsync( - """ - using System; + } + """, + testHost, + Keyword("namespace"), + Namespace("OtherScope"), + Punctuation.OpenCurly, + Keyword("interface"), + Interface("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("X"), + Punctuation.OpenCurly, + Keyword("void"), + Method("N"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("void"), + Method("M"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("notnull"), + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } - class Person { public string Name; } + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/10174")] + [CombinatorialData] + public async Task VarInPropertyPattern(TestHost testHost) + { + await TestAsync( + """ + using System; - class Program + class Person { public string Name; } + + class Program + { + void Goo(object o) { - void Goo(object o) + if (o is Person { Name: var n }) { - if (o is Person { Name: var n }) - { - Console.WriteLine(n); - } + Console.WriteLine(n); } } - """, - testHost, - Keyword("using"), - Namespace("System"), - Punctuation.Semicolon, - Keyword("class"), - Class("Person"), - Punctuation.OpenCurly, - Keyword("public"), - Keyword("string"), - Field("Name"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("class"), - Class("Program"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("if"), - Punctuation.OpenParen, - Parameter("o"), - Keyword("is"), - Class("Person"), - Punctuation.OpenCurly, - Field("Name"), - Punctuation.Colon, - Keyword("var"), - Local("n"), - Punctuation.CloseCurly, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Class("Console"), - Static("Console"), - Operators.Dot, - Method("WriteLine"), - Static("WriteLine"), - Punctuation.OpenParen, - Local("n"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] - [CombinatorialData] - public async Task NotPattern(TestHost testHost) - { - await TestAsync( - """ - class Person + } + """, + testHost, + Keyword("using"), + Namespace("System"), + Punctuation.Semicolon, + Keyword("class"), + Class("Person"), + Punctuation.OpenCurly, + Keyword("public"), + Keyword("string"), + Field("Name"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("class"), + Class("Program"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("if"), + Punctuation.OpenParen, + Parameter("o"), + Keyword("is"), + Class("Person"), + Punctuation.OpenCurly, + Field("Name"), + Punctuation.Colon, + Keyword("var"), + Local("n"), + Punctuation.CloseCurly, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Class("Console"), + Static("Console"), + Operators.Dot, + Method("WriteLine"), + Static("WriteLine"), + Punctuation.OpenParen, + Local("n"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] + [CombinatorialData] + public async Task NotPattern(TestHost testHost) + { + await TestAsync( + """ + class Person + { + void Goo(object o) { - void Goo(object o) + if (o is not Person p) { - if (o is not Person p) - { - } } } - """, - testHost, - Keyword("class"), - Class("Person"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("if"), - Punctuation.OpenParen, - Parameter("o"), - Keyword("is"), - Keyword("not"), - Class("Person"), - Local("p"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] - [CombinatorialData] - public async Task OrPattern(TestHost testHost) - { - await TestAsync( - """ - class Person + } + """, + testHost, + Keyword("class"), + Class("Person"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("if"), + Punctuation.OpenParen, + Parameter("o"), + Keyword("is"), + Keyword("not"), + Class("Person"), + Local("p"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] + [CombinatorialData] + public async Task OrPattern(TestHost testHost) + { + await TestAsync( + """ + class Person + { + void Goo(object o) { - void Goo(object o) + if (o is Person or int) { - if (o is Person or int) - { - } } } - """, - testHost, - Keyword("class"), - Class("Person"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("if"), - Punctuation.OpenParen, - Parameter("o"), - Keyword("is"), - Class("Person"), - Keyword("or"), - Keyword("int"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/59484")] - [CombinatorialData] - public async Task TestPatternVariables(TestHost testHost) - { - await TestAsync( - """ - void M(object o) { - _ = o is [var (x, y), {} z] list; - } - """, - testHost, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("_"), - Operators.Equals, - Parameter("o"), - Keyword("is"), - Punctuation.OpenBracket, - Keyword("var"), - Punctuation.OpenParen, - Local("x"), - Punctuation.Comma, - Local("y"), - Punctuation.CloseParen, - Punctuation.Comma, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Local("z"), - Punctuation.CloseBracket, - Local("list"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] - [CombinatorialData] - public async Task RelationalPattern(TestHost testHost) - { - await TestAsync( - """ - class Person + } + """, + testHost, + Keyword("class"), + Class("Person"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("if"), + Punctuation.OpenParen, + Parameter("o"), + Keyword("is"), + Class("Person"), + Keyword("or"), + Keyword("int"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/59484")] + [CombinatorialData] + public async Task TestPatternVariables(TestHost testHost) + { + await TestAsync( + """ + void M(object o) { + _ = o is [var (x, y), {} z] list; + } + """, + testHost, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("_"), + Operators.Equals, + Parameter("o"), + Keyword("is"), + Punctuation.OpenBracket, + Keyword("var"), + Punctuation.OpenParen, + Local("x"), + Punctuation.Comma, + Local("y"), + Punctuation.CloseParen, + Punctuation.Comma, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Local("z"), + Punctuation.CloseBracket, + Local("list"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/42368")] + [CombinatorialData] + public async Task RelationalPattern(TestHost testHost) + { + await TestAsync( + """ + class Person + { + void Goo(object o) { - void Goo(object o) + if (o is >= 0) { - if (o is >= 0) - { - } } } - """, - testHost, - Keyword("class"), - Class("Person"), - Punctuation.OpenCurly, - Keyword("void"), - Method("Goo"), - Punctuation.OpenParen, - Keyword("object"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("if"), - Punctuation.OpenParen, - Parameter("o"), - Keyword("is"), - Operators.GreaterThanEquals, - NumericLiteral("0"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task BasicFileScopedNamespaceClassification(TestHost testHost) - { - await TestAsync( - """ - namespace NS; - - class C { } - """, - testHost, - Keyword("namespace"), - Namespace("NS"), - Punctuation.Semicolon, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestStringEscape(TestHost testHost) - { - await TestInMethodAsync(@"var goo = $@""{{{12:X}}}"";", - testHost, - Keyword("var"), - Local("goo"), - Operators.Equals, - Verbatim(""" - $@" - """), - Escape("{{"), - Punctuation.OpenCurly, - Number("12"), - Punctuation.Colon, - String("X"), - Punctuation.CloseCurly, - Escape("}}"), - Verbatim(""" - " - """), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/55313")] - public async Task TestStaticConstructorClass(TestHost testHost) - { - await TestAsync( - """ - class C - { - static C() { } - } - """, - testHost, + } + """, + testHost, + Keyword("class"), + Class("Person"), + Punctuation.OpenCurly, + Keyword("void"), + Method("Goo"), + Punctuation.OpenParen, + Keyword("object"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("if"), + Punctuation.OpenParen, + Parameter("o"), + Keyword("is"), + Operators.GreaterThanEquals, + NumericLiteral("0"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task BasicFileScopedNamespaceClassification(TestHost testHost) + { + await TestAsync( + """ + namespace NS; + + class C { } + """, + testHost, + Keyword("namespace"), + Namespace("NS"), + Punctuation.Semicolon, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestStringEscape(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $@""{{{12:X}}}"";", + testHost, + Keyword("var"), + Local("goo"), + Operators.Equals, + Verbatim(""" + $@" + """), + Escape("{{"), + Punctuation.OpenCurly, + Number("12"), + Punctuation.Colon, + String("X"), + Punctuation.CloseCurly, + Escape("}}"), + Verbatim(""" + " + """), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/55313")] + public async Task TestStaticConstructorClass(TestHost testHost) + { + await TestAsync( + """ + class C + { + static C() { } + } + """, + testHost, Keyword("class"), Class("C"), Punctuation.OpenCurly, @@ -2290,20 +2288,20 @@ static C() { } Punctuation.OpenCurly, Punctuation.CloseCurly, Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/55313")] - public async Task TestStaticConstructorInterface(TestHost testHost) - { - await TestAsync( - """ - interface C - { - static C() { } - } - """, - testHost, + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/55313")] + public async Task TestStaticConstructorInterface(TestHost testHost) + { + await TestAsync( + """ + interface C + { + static C() { } + } + """, + testHost, Keyword("interface"), Interface("C"), Punctuation.OpenCurly, @@ -2315,20 +2313,20 @@ static C() { } Punctuation.OpenCurly, Punctuation.CloseCurly, Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/59569")] - public async Task TestArgsInTopLevel(TestHost testHost) - { - await TestAsync( - """ - [|foreach (var arg in args) - { - }|] - """, - testHost, - parseOptions: null, + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/59569")] + public async Task TestArgsInTopLevel(TestHost testHost) + { + await TestAsync( + """ + [|foreach (var arg in args) + { + }|] + """, + testHost, + parseOptions: null, ControlKeyword("foreach"), Punctuation.OpenParen, Keyword("var"), @@ -2338,26 +2336,26 @@ await TestAsync( Punctuation.CloseParen, Punctuation.OpenCurly, Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/59569")] - public async Task TestArgsInNormalProgram(TestHost testHost) - { - await TestAsync( - """ - class Program + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/59569")] + public async Task TestArgsInNormalProgram(TestHost testHost) + { + await TestAsync( + """ + class Program + { + static void Main(string[] args) { - static void Main(string[] args) + [|foreach (var arg in args) { - [|foreach (var arg in args) - { - }|] - } + }|] } - """, - testHost, - parseOptions: null, + } + """, + testHost, + parseOptions: null, ControlKeyword("foreach"), Punctuation.OpenParen, Keyword("var"), @@ -2367,67 +2365,67 @@ static void Main(string[] args) Punctuation.CloseParen, Punctuation.OpenCurly, Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncInIncompleteMember(TestHost testHost) - { - await TestAsync( - """ - class Test - { - public async - } - """, - testHost, - parseOptions: null, + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncInIncompleteMember(TestHost testHost) + { + await TestAsync( + """ + class Test + { + public async + } + """, + testHost, + parseOptions: null, Keyword("class"), Class("Test"), Punctuation.OpenCurly, Keyword("public"), Keyword("async"), Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncInIncompleteMemberWhenAsyncTypeIsDefined(TestHost testHost) - { - await TestAsync( - """ - [|class Test - { - public async - }|] + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncInIncompleteMemberWhenAsyncTypeIsDefined(TestHost testHost) + { + await TestAsync( + """ + [|class Test + { + public async + }|] - class async - { - } - """, - testHost, - parseOptions: null, + class async + { + } + """, + testHost, + parseOptions: null, Keyword("class"), Class("Test"), Punctuation.OpenCurly, Keyword("public"), Class("async"), Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncInPotentialLocalFunctionDeclaration(TestHost testHost) - { - await TestAsync( - """ - void M() - { - async - } - """, - testHost, - parseOptions: null, + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncInPotentialLocalFunctionDeclaration(TestHost testHost) + { + await TestAsync( + """ + void M() + { + async + } + """, + testHost, + parseOptions: null, Keyword("void"), Method("M"), Punctuation.OpenParen, @@ -2435,25 +2433,25 @@ void M() Punctuation.OpenCurly, Keyword("async"), Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncInPotentialLocalFunctionDeclarationWhenAsyncTypeIsDefined(TestHost testHost) - { - await TestAsync( - """ - [|void M() - { - async - }|] + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncInPotentialLocalFunctionDeclarationWhenAsyncTypeIsDefined(TestHost testHost) + { + await TestAsync( + """ + [|void M() + { + async + }|] - class async - { - } - """, - testHost, - parseOptions: null, + class async + { + } + """, + testHost, + parseOptions: null, Keyword("void"), Method("M"), Punctuation.OpenParen, @@ -2461,65 +2459,65 @@ class async Punctuation.OpenCurly, Class("async"), Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsLocalMemberType_NoAsyncInScope(TestHost testHost) - { - await TestAsync( - """ - class Test + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsLocalMemberType_NoAsyncInScope(TestHost testHost) + { + await TestAsync( + """ + class Test + { + void M() { - void M() - { - [|async a;|] - } + [|async a;|] } - """, - testHost, - parseOptions: null, + } + """, + testHost, + parseOptions: null, Keyword("async"), Local("a"), Punctuation.Semicolon); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsLocalMemberType_AsyncInScope(TestHost testHost) - { - await TestAsync( - """ - class async { } + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsLocalMemberType_AsyncInScope(TestHost testHost) + { + await TestAsync( + """ + class async { } - class Test + class Test + { + void M() { - void M() - { - [|async a;|] - } + [|async a;|] } - """, - testHost, - parseOptions: null, + } + """, + testHost, + parseOptions: null, Class("async"), Local("a"), Punctuation.Semicolon); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsPropertyType_NoAsyncInScope(TestHost testHost) - { - await TestAsync( - """ - class Test - { - [|public async Prop { get; set; }|] - } - """, - testHost, - parseOptions: null, + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsPropertyType_NoAsyncInScope(TestHost testHost) + { + await TestAsync( + """ + class Test + { + [|public async Prop { get; set; }|] + } + """, + testHost, + parseOptions: null, Keyword("public"), Keyword("async"), Property("Prop"), @@ -2529,23 +2527,23 @@ class Test Keyword("set"), Punctuation.Semicolon, Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsPropertyType_AsyncInScope(TestHost testHost) - { - await TestAsync( - """ - class async { } + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsPropertyType_AsyncInScope(TestHost testHost) + { + await TestAsync( + """ + class async { } - class Test - { - [|public async Prop { get; set; }|] - } - """, - testHost, - parseOptions: null, + class Test + { + [|public async Prop { get; set; }|] + } + """, + testHost, + parseOptions: null, Keyword("public"), Class("async"), Property("Prop"), @@ -2555,687 +2553,686 @@ class Test Keyword("set"), Punctuation.Semicolon, Punctuation.CloseCurly); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsMethodReturnType_NoAsyncInScope(TestHost testHost) - { - await TestAsync( - """ - class Test - { - [|public async M()|] {} - } - """, - testHost, - parseOptions: null, + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsMethodReturnType_NoAsyncInScope(TestHost testHost) + { + await TestAsync( + """ + class Test + { + [|public async M()|] {} + } + """, + testHost, + parseOptions: null, Keyword("public"), Keyword("async"), Method("M"), Punctuation.OpenParen, Punctuation.CloseParen); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsMethodReturnType_AsyncInScope(TestHost testHost) - { - await TestAsync( - """ - class async { } + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsMethodReturnType_AsyncInScope(TestHost testHost) + { + await TestAsync( + """ + class async { } - class Test - { - [|public async M()|] {} - } - """, - testHost, - parseOptions: null, + class Test + { + [|public async M()|] {} + } + """, + testHost, + parseOptions: null, Keyword("public"), Class("async"), Method("M"), Punctuation.OpenParen, Punctuation.CloseParen); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncAsAccessingName(TestHost testHost) - { - await TestAsync( - """ - class Test + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncAsAccessingName(TestHost testHost) + { + await TestAsync( + """ + class Test + { + void M() { - void M() - { - var a = [|C.async;|] - } + var a = [|C.async;|] } + } - class C - { - public static int async; - } - """, - testHost, - parseOptions: null, + class C + { + public static int async; + } + """, + testHost, + parseOptions: null, Class("C"), Operators.Dot, Field("async"), Static("async"), Punctuation.Semicolon); - } + } - [Theory, CombinatorialData] - [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] - public async Task TestAsyncInIncompleteDelegateOrLambda(TestHost testHost) - { - await TestAsync( - """ - using System; - class Test + [Theory, CombinatorialData] + [WorkItem(60399, "https://github.com/dotnet/roslyn/issues/60339")] + public async Task TestAsyncInIncompleteDelegateOrLambda(TestHost testHost) + { + await TestAsync( + """ + using System; + class Test + { + void M() { - void M() - { - [|Action a = async |] - } + [|Action a = async |] } - """, - testHost, - parseOptions: null, + } + """, + testHost, + parseOptions: null, Delegate("Action"), Local("a"), Operators.Equals, Keyword("async")); - } - - [Theory, CombinatorialData] - public async Task TestPartialInIncompleteMember1(TestHost testHost) - { - await TestAsync(""" - class C - { - [|partial|] - } - """, - testHost, - Keyword("partial")); - } - - [Theory, CombinatorialData] - public async Task TestPartialInIncompleteMember2(TestHost testHost) - { - await TestAsync(""" - class C - { - [|public partial|] - } - """, - testHost, - Keyword("public"), - Keyword("partial")); - } - - [Theory, CombinatorialData] - public async Task TestPartialInIncompleteMember1_PartialTypeIsDefined(TestHost testHost) - { - await TestAsync(""" - class partial - { - } + } - class C - { - [|partial|] - } - """, - testHost, - Class("partial")); - } + [Theory, CombinatorialData] + public async Task TestPartialInIncompleteMember1(TestHost testHost) + { + await TestAsync(""" + class C + { + [|partial|] + } + """, + testHost, + Keyword("partial")); + } - [Theory, CombinatorialData] - public async Task TestPartialInIncompleteMember2_PartialTypeIsDefined(TestHost testHost) - { - await TestAsync(""" - class partial - { - } + [Theory, CombinatorialData] + public async Task TestPartialInIncompleteMember2(TestHost testHost) + { + await TestAsync(""" + class C + { + [|public partial|] + } + """, + testHost, + Keyword("public"), + Keyword("partial")); + } - class C - { - [|public partial|] - } - """, - testHost, - Keyword("public"), - Class("partial")); - } - - [Theory, CombinatorialData] - public async Task TestTopLevelPartial1(TestHost testHost) - { - await TestAsync(""" - partial - """, - testHost, - Keyword("partial")); - } - - [Theory, CombinatorialData] - public async Task TestTopLevelPartial2(TestHost testHost) - { - await TestAsync(""" - public partial - """, - testHost, - Keyword("public"), - Keyword("partial")); - } - - [Theory, CombinatorialData] - public async Task TestTopLevelPartial1_PartialTypeIsDefined(TestHost testHost) - { - await TestAsync(""" - class partial - { - } + [Theory, CombinatorialData] + public async Task TestPartialInIncompleteMember1_PartialTypeIsDefined(TestHost testHost) + { + await TestAsync(""" + class partial + { + } + class C + { [|partial|] - """, - testHost, - Class("partial")); - } + } + """, + testHost, + Class("partial")); + } - [Theory, CombinatorialData] - public async Task TestTopLevelPartial2_PartialTypeIsDefined(TestHost testHost) - { - await TestAsync(""" - class partial - { - } + [Theory, CombinatorialData] + public async Task TestPartialInIncompleteMember2_PartialTypeIsDefined(TestHost testHost) + { + await TestAsync(""" + class partial + { + } + class C + { [|public partial|] - """, - testHost, - Keyword("public"), - Class("partial")); - } - - /// - /// - [Theory, CombinatorialData] - public async Task LocalFunctionDeclarationAndUse(TestHost testHost) - { - await TestAsync( - """ - using System; + } + """, + testHost, + Keyword("public"), + Class("partial")); + } - class C - { - void M(Action action) - { - [|localFunction(); - staticLocalFunction(); + [Theory, CombinatorialData] + public async Task TestTopLevelPartial1(TestHost testHost) + { + await TestAsync(""" + partial + """, + testHost, + Keyword("partial")); + } - M(localFunction); - M(staticLocalFunction); + [Theory, CombinatorialData] + public async Task TestTopLevelPartial2(TestHost testHost) + { + await TestAsync(""" + public partial + """, + testHost, + Keyword("public"), + Keyword("partial")); + } - void localFunction() { } - static void staticLocalFunction() { }|] - } - } + [Theory, CombinatorialData] + public async Task TestTopLevelPartial1_PartialTypeIsDefined(TestHost testHost) + { + await TestAsync(""" + class partial + { + } - """, - testHost, - Method("localFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Method("staticLocalFunction"), - Static("staticLocalFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Method("M"), - Punctuation.OpenParen, - Method("localFunction"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Method("M"), - Punctuation.OpenParen, - Method("staticLocalFunction"), - Static("staticLocalFunction"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("void"), - Method("localFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("static"), - Keyword("void"), - Method("staticLocalFunction"), - Static("staticLocalFunction"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task TestScopedVar(TestHost testHost) - { - await TestAsync(""" - static void method(scoped in S s) - { - scoped var rs1 = s; - } + [|partial|] + """, + testHost, + Class("partial")); + } - file readonly ref struct S { } - """, testHost, - Keyword("static"), - Keyword("void"), - Method("method"), - Static("method"), - Punctuation.OpenParen, - Keyword("scoped"), - Keyword("in"), - Struct("S"), - Parameter("s"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("scoped"), - Keyword("var"), - Local("rs1"), - Operators.Equals, - Parameter("s"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Keyword("file"), - Keyword("readonly"), - Keyword("ref"), - Keyword("struct"), - Struct("S"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task Lambda_DefaultParameterValue(TestHost testHost) - { - await TestAsync( - """ - class C + [Theory, CombinatorialData] + public async Task TestTopLevelPartial2_PartialTypeIsDefined(TestHost testHost) + { + await TestAsync(""" + class partial + { + } + + [|public partial|] + """, + testHost, + Keyword("public"), + Class("partial")); + } + + /// + /// + [Theory, CombinatorialData] + public async Task LocalFunctionDeclarationAndUse(TestHost testHost) + { + await TestAsync( + """ + using System; + + class C + { + void M(Action action) + { + [|localFunction(); + staticLocalFunction(); + + M(localFunction); + M(staticLocalFunction); + + void localFunction() { } + static void staticLocalFunction() { }|] + } + } + + """, + testHost, + Method("localFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Method("staticLocalFunction"), + Static("staticLocalFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Method("M"), + Punctuation.OpenParen, + Method("localFunction"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Method("M"), + Punctuation.OpenParen, + Method("staticLocalFunction"), + Static("staticLocalFunction"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("void"), + Method("localFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("static"), + Keyword("void"), + Method("staticLocalFunction"), + Static("staticLocalFunction"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task TestScopedVar(TestHost testHost) + { + await TestAsync(""" + static void method(scoped in S s) + { + scoped var rs1 = s; + } + + file readonly ref struct S { } + """, testHost, + Keyword("static"), + Keyword("void"), + Method("method"), + Static("method"), + Punctuation.OpenParen, + Keyword("scoped"), + Keyword("in"), + Struct("S"), + Parameter("s"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("scoped"), + Keyword("var"), + Local("rs1"), + Operators.Equals, + Parameter("s"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Keyword("file"), + Keyword("readonly"), + Keyword("ref"), + Keyword("struct"), + Struct("S"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task Lambda_DefaultParameterValue(TestHost testHost) + { + await TestAsync( + """ + class C + { + const int N = 10; + + void M() { - const int N = 10; + var lam = [|(int x = N) => x|]; + } + } + + """, + testHost, + Punctuation.OpenParen, + Keyword("int"), + Parameter("x"), + Operators.Equals, + Constant("N"), + Static("N"), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Parameter("x")); + } - void M() - { - var lam = [|(int x = N) => x|]; - } - } + [Theory, CombinatorialData] + public async Task UsingAliasToType1(TestHost testHost) + { + await TestAsync( + """ + using X = int; + """, + testHost, + Keyword("using"), + Struct("X"), + Operators.Equals, + Keyword("int"), + Punctuation.Semicolon); + } - """, - testHost, - Punctuation.OpenParen, - Keyword("int"), - Parameter("x"), - Operators.Equals, - Constant("N"), - Static("N"), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Parameter("x")); - } - - [Theory, CombinatorialData] - public async Task UsingAliasToType1(TestHost testHost) - { - await TestAsync( - """ - using X = int; - """, - testHost, - Keyword("using"), - Struct("X"), - Operators.Equals, - Keyword("int"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task UsingAliasToType2(TestHost testHost) - { - await TestAsync( - """ - using X = int[]; - """, - testHost, - Keyword("using"), - Identifier("X"), - Operators.Equals, - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task UsingAliasToType3(TestHost testHost) - { - await TestAsync( - """ - using unsafe X = int*; - """, - testHost, - Keyword("using"), - Keyword("unsafe"), - Identifier("X"), - Operators.Equals, - Keyword("int"), - Operators.Asterisk, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task UsingAliasToType4(TestHost testHost) - { - await TestAsync( - """ - using unsafe X = delegate*; - """, - testHost, - Keyword("using"), - Keyword("unsafe"), - Identifier("X"), - Operators.Equals, - Keyword("delegate"), - Operators.Asterisk, - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.Comma, - Keyword("int"), - Punctuation.CloseAngle, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task UsingAliasToType5(TestHost testHost) - { - await TestAsync( - """ - using X = (int x, string b); - """, - testHost, - Keyword("using"), - Struct("X"), - Operators.Equals, - Punctuation.OpenParen, - Keyword("int"), - Identifier("x"), - Punctuation.Comma, - Keyword("string"), - Identifier("b"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/70107")] - public async Task TestFunctionPointer1(TestHost testHost) - { - await TestAsync( - """ - delegate* unmanaged[Fastcall, Stdcall, Thiscall] fp; - """, - testHost, - parseOptions: null, - Keyword("delegate"), - Operators.Asterisk, - Keyword("unmanaged"), - Punctuation.OpenBracket, - Class("Fastcall"), - Punctuation.Comma, - Class("Stdcall"), - Punctuation.Comma, - Class("Thiscall"), - Punctuation.CloseBracket, - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Local("fp"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/70107")] - public async Task TestFunctionPointer2(TestHost testHost) - { - await TestAsync( - """ - delegate* unmanaged[Member] fp; - """, - testHost, - parseOptions: null, - Keyword("delegate"), - Operators.Asterisk, - Keyword("unmanaged"), - Punctuation.OpenBracket, - Identifier("Member"), - Punctuation.CloseBracket, - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Local("fp"), - Punctuation.Semicolon); - } - - [WpfFact] - public async Task TestTotalClassifier() - { - using var workspace = EditorTestWorkspace.CreateCSharp("""" - using System.Text.RegularExpressions; + [Theory, CombinatorialData] + public async Task UsingAliasToType2(TestHost testHost) + { + await TestAsync( + """ + using X = int[]; + """, + testHost, + Keyword("using"), + Identifier("X"), + Operators.Equals, + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task UsingAliasToType3(TestHost testHost) + { + await TestAsync( + """ + using unsafe X = int*; + """, + testHost, + Keyword("using"), + Keyword("unsafe"), + Identifier("X"), + Operators.Equals, + Keyword("int"), + Operators.Asterisk, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task UsingAliasToType4(TestHost testHost) + { + await TestAsync( + """ + using unsafe X = delegate*; + """, + testHost, + Keyword("using"), + Keyword("unsafe"), + Identifier("X"), + Operators.Equals, + Keyword("delegate"), + Operators.Asterisk, + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.Comma, + Keyword("int"), + Punctuation.CloseAngle, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task UsingAliasToType5(TestHost testHost) + { + await TestAsync( + """ + using X = (int x, string b); + """, + testHost, + Keyword("using"), + Struct("X"), + Operators.Equals, + Punctuation.OpenParen, + Keyword("int"), + Identifier("x"), + Punctuation.Comma, + Keyword("string"), + Identifier("b"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/70107")] + public async Task TestFunctionPointer1(TestHost testHost) + { + await TestAsync( + """ + delegate* unmanaged[Fastcall, Stdcall, Thiscall] fp; + """, + testHost, + parseOptions: null, + Keyword("delegate"), + Operators.Asterisk, + Keyword("unmanaged"), + Punctuation.OpenBracket, + Class("Fastcall"), + Punctuation.Comma, + Class("Stdcall"), + Punctuation.Comma, + Class("Thiscall"), + Punctuation.CloseBracket, + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Local("fp"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/70107")] + public async Task TestFunctionPointer2(TestHost testHost) + { + await TestAsync( + """ + delegate* unmanaged[Member] fp; + """, + testHost, + parseOptions: null, + Keyword("delegate"), + Operators.Asterisk, + Keyword("unmanaged"), + Punctuation.OpenBracket, + Identifier("Member"), + Punctuation.CloseBracket, + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Local("fp"), + Punctuation.Semicolon); + } + + [WpfFact] + public async Task TestTotalClassifier() + { + using var workspace = EditorTestWorkspace.CreateCSharp("""" + using System.Text.RegularExpressions; - class C + class C + { + // class D { } + void M() { - // class D { } - void M() - { - new Regex("(a)"); - var s1 = "s1"; - var s2 = $"s2"; - var s3 = @"s3"; - var s4 = """ + new Regex("(a)"); + var s1 = "s1"; + var s2 = $"s2"; + var s3 = @"s3"; + var s4 = """ + s4 + """; + } + } + """"); + var document = workspace.Documents.First(); + + var listenerProvider = workspace.ExportProvider.GetExportedValue(); + var globalOptions = workspace.ExportProvider.GetExportedValue(); + + var provider = new TotalClassificationTaggerProvider( + workspace.GetService(), + workspace.GetService(), + globalOptions, + visibilityTracker: null, + listenerProvider); + + var buffer = document.GetTextBuffer(); + using var tagger = provider.CreateTagger(document.GetTextView(), buffer); + + var waiter = listenerProvider.GetWaiter(FeatureAttribute.Classification); + await waiter.ExpeditedWaitAsync(); + + var allCode = buffer.CurrentSnapshot.GetText(); + var tags = tagger!.GetTags(new NormalizedSnapshotSpanCollection(buffer.CurrentSnapshot.GetFullSpan())); + + var actualOrdered = tags.OrderBy((t1, t2) => t1.Span.Span.Start - t2.Span.Span.Start); + + var actualFormatted = actualOrdered.Select(a => new FormattedClassification(allCode.Substring(a.Span.Span.Start, a.Span.Span.Length), a.Tag.ClassificationType.Classification)); + + AssertEx.Equal(new[] + { + Keyword("using"), + Namespace("System"), + Operators.Dot, + Namespace("Text"), + Operators.Dot, + Namespace("RegularExpressions"), + Punctuation.Semicolon, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Comment("// class D { }"), + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("new"), + Class("Regex"), + Punctuation.OpenParen, + String("\""), + Regex.Grouping("("), + Regex.Text("a"), + Regex.Grouping(")"), + String("\""), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("var"), + Local("s1"), + Operators.Equals, + String("\"s1\""), + Punctuation.Semicolon, + Keyword("var"), + Local("s2"), + Operators.Equals, + String("$\""), + String("s2"), + String("\""), + Punctuation.Semicolon, + Keyword("var"), + Local("s3"), + Operators.Equals, + Verbatim("@\"s3\""), + Punctuation.Semicolon, + Keyword("var"), + Local("s4"), + Operators.Equals, + String("""" + """ s4 - """; - } - } - """"); - var document = workspace.Documents.First(); - - var listenerProvider = workspace.ExportProvider.GetExportedValue(); - var globalOptions = workspace.ExportProvider.GetExportedValue(); - - var provider = new TotalClassificationTaggerProvider( - workspace.GetService(), - workspace.GetService(), - globalOptions, - visibilityTracker: null, - listenerProvider); - - var buffer = document.GetTextBuffer(); - using var tagger = provider.CreateTagger(document.GetTextView(), buffer); - - var waiter = listenerProvider.GetWaiter(FeatureAttribute.Classification); - await waiter.ExpeditedWaitAsync(); - - var allCode = buffer.CurrentSnapshot.GetText(); - var tags = tagger!.GetTags(new NormalizedSnapshotSpanCollection(buffer.CurrentSnapshot.GetFullSpan())); - - var actualOrdered = tags.OrderBy((t1, t2) => t1.Span.Span.Start - t2.Span.Span.Start); - - var actualFormatted = actualOrdered.Select(a => new FormattedClassification(allCode.Substring(a.Span.Span.Start, a.Span.Span.Length), a.Tag.ClassificationType.Classification)); - - AssertEx.Equal(new[] - { - Keyword("using"), - Namespace("System"), - Operators.Dot, - Namespace("Text"), - Operators.Dot, - Namespace("RegularExpressions"), - Punctuation.Semicolon, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Comment("// class D { }"), - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("new"), - Class("Regex"), - Punctuation.OpenParen, - String("\""), - Regex.Grouping("("), - Regex.Text("a"), - Regex.Grouping(")"), - String("\""), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("var"), - Local("s1"), - Operators.Equals, - String("\"s1\""), - Punctuation.Semicolon, - Keyword("var"), - Local("s2"), - Operators.Equals, - String("$\""), - String("s2"), - String("\""), - Punctuation.Semicolon, - Keyword("var"), - Local("s3"), - Operators.Equals, - Verbatim("@\"s3\""), - Punctuation.Semicolon, - Keyword("var"), - Local("s4"), - Operators.Equals, - String("""" - """ - s4 - """ - """"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - }, actualFormatted); - } - - [WpfFact] - public void TestCopyPasteClassifier() - { - using var workspace = EditorTestWorkspace.CreateCSharp("""" - using System.Text.RegularExpressions; + """ + """"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + }, actualFormatted); + } - class C + [WpfFact] + public void TestCopyPasteClassifier() + { + using var workspace = EditorTestWorkspace.CreateCSharp("""" + using System.Text.RegularExpressions; + + class C + { + // class D { } + void M() { - // class D { } - void M() - { - new Regex("(a)"); - var s1 = "s1"; - var s2 = $"s2"; - var s3 = @"s3"; - var s4 = """ + new Regex("(a)"); + var s1 = "s1"; + var s2 = $"s2"; + var s3 = @"s3"; + var s4 = """ + s4 + """; + } + } + """"); + var document = workspace.Documents.First(); + + var listenerProvider = workspace.ExportProvider.GetExportedValue(); + var globalOptions = workspace.ExportProvider.GetExportedValue(); + + var provider = new CopyPasteAndPrintingClassificationBufferTaggerProvider( + workspace.GetService(), + workspace.GetService(), + listenerProvider, + globalOptions); + + var buffer = document.GetTextBuffer(); + using var tagger = provider.CreateTagger(buffer); + + var allCode = buffer.CurrentSnapshot.GetText(); + var tags = tagger!.GetAllTags(new NormalizedSnapshotSpanCollection(buffer.CurrentSnapshot.GetFullSpan()), CancellationToken.None); + + var actualOrdered = tags.OrderBy((t1, t2) => t1.Span.Span.Start - t2.Span.Span.Start); + + var actualFormatted = actualOrdered.Select(a => new FormattedClassification(allCode.Substring(a.Span.Span.Start, a.Span.Span.Length), a.Tag.ClassificationType.Classification)); + + AssertEx.Equal(new[] + { + Keyword("using"), + Namespace("System"), + Operators.Dot, + Namespace("Text"), + Operators.Dot, + Namespace("RegularExpressions"), + Punctuation.Semicolon, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Comment("// class D { }"), + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Keyword("new"), + Class("Regex"), + Punctuation.OpenParen, + String("\""), + Regex.Grouping("("), + Regex.Text("a"), + Regex.Grouping(")"), + String("\""), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("var"), + Local("s1"), + Operators.Equals, + String("\"s1\""), + Punctuation.Semicolon, + Keyword("var"), + Local("s2"), + Operators.Equals, + String("$\""), + String("s2"), + String("\""), + Punctuation.Semicolon, + Keyword("var"), + Local("s3"), + Operators.Equals, + Verbatim("@\"s3\""), + Punctuation.Semicolon, + Keyword("var"), + Local("s4"), + Operators.Equals, + String("""" + """ s4 - """; - } - } - """"); - var document = workspace.Documents.First(); - - var listenerProvider = workspace.ExportProvider.GetExportedValue(); - var globalOptions = workspace.ExportProvider.GetExportedValue(); - - var provider = new CopyPasteAndPrintingClassificationBufferTaggerProvider( - workspace.GetService(), - workspace.GetService(), - listenerProvider, - globalOptions); - - var buffer = document.GetTextBuffer(); - using var tagger = provider.CreateTagger(buffer); - - var allCode = buffer.CurrentSnapshot.GetText(); - var tags = tagger!.GetAllTags(new NormalizedSnapshotSpanCollection(buffer.CurrentSnapshot.GetFullSpan()), CancellationToken.None); - - var actualOrdered = tags.OrderBy((t1, t2) => t1.Span.Span.Start - t2.Span.Span.Start); - - var actualFormatted = actualOrdered.Select(a => new FormattedClassification(allCode.Substring(a.Span.Span.Start, a.Span.Span.Length), a.Tag.ClassificationType.Classification)); - - AssertEx.Equal(new[] - { - Keyword("using"), - Namespace("System"), - Operators.Dot, - Namespace("Text"), - Operators.Dot, - Namespace("RegularExpressions"), - Punctuation.Semicolon, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Comment("// class D { }"), - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Keyword("new"), - Class("Regex"), - Punctuation.OpenParen, - String("\""), - Regex.Grouping("("), - Regex.Text("a"), - Regex.Grouping(")"), - String("\""), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("var"), - Local("s1"), - Operators.Equals, - String("\"s1\""), - Punctuation.Semicolon, - Keyword("var"), - Local("s2"), - Operators.Equals, - String("$\""), - String("s2"), - String("\""), - Punctuation.Semicolon, - Keyword("var"), - Local("s3"), - Operators.Equals, - Verbatim("@\"s3\""), - Punctuation.Semicolon, - Keyword("var"), - Local("s4"), - Operators.Equals, - String("""" - """ - s4 - """ - """"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.CloseCurly, - }, actualFormatted); - } + """ + """"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.CloseCurly, + }, actualFormatted); } } diff --git a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests_Dynamic.cs b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests_Dynamic.cs index 2db25fc29802e..7fb9e09e55684 100644 --- a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests_Dynamic.cs +++ b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests_Dynamic.cs @@ -4,1144 +4,1142 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Remote.Testing; -using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using static Microsoft.CodeAnalysis.Editor.UnitTests.Classification.FormattedClassifications; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification; + +public partial class TotalClassifierTests { - public partial class TotalClassifierTests + [Theory, CombinatorialData] + public async Task DynamicAsParamTypeAndDefault(TestHost testHost) + { + await TestInClassAsync(@"void M(dynamic d = default(dynamic", + testHost, + Keyword("void"), + Method("M"), + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("d"), + Operators.Equals, + Keyword("default"), + Punctuation.OpenParen, + Keyword("dynamic")); + } + + [Theory, CombinatorialData] + public async Task DynamicExplicitConversion(TestHost testHost) { - [Theory, CombinatorialData] - public async Task DynamicAsParamTypeAndDefault(TestHost testHost) - { - await TestInClassAsync(@"void M(dynamic d = default(dynamic", - testHost, - Keyword("void"), - Method("M"), - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("d"), - Operators.Equals, - Keyword("default"), - Punctuation.OpenParen, - Keyword("dynamic")); - } - - [Theory, CombinatorialData] - public async Task DynamicExplicitConversion(TestHost testHost) - { - await TestInMethodAsync( + await TestInMethodAsync( @"dynamic d = (dynamic)a;", - testHost, - Keyword("dynamic"), - Local("d"), - Operators.Equals, - Punctuation.OpenParen, - Keyword("dynamic"), - Punctuation.CloseParen, - Identifier("a"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicMethodCall(TestHost testHost) - { - await TestInMethodAsync(@"dynamic.Equals(1, 1);", - testHost, - Identifier("dynamic"), - Operators.Dot, - Identifier("Equals"), - Punctuation.OpenParen, - Number("1"), - Punctuation.Comma, - Number("1"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicNullable(TestHost testHost) - { - await TestInMethodAsync(@"dynamic? a", - testHost, - Keyword("dynamic"), - Operators.QuestionMark, - Local("a")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsUsingAliasForClass(TestHost testHost) - { - await TestAsync( + testHost, + Keyword("dynamic"), + Local("d"), + Operators.Equals, + Punctuation.OpenParen, + Keyword("dynamic"), + Punctuation.CloseParen, + Identifier("a"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicMethodCall(TestHost testHost) + { + await TestInMethodAsync(@"dynamic.Equals(1, 1);", + testHost, + Identifier("dynamic"), + Operators.Dot, + Identifier("Equals"), + Punctuation.OpenParen, + Number("1"), + Punctuation.Comma, + Number("1"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicNullable(TestHost testHost) + { + await TestInMethodAsync(@"dynamic? a", + testHost, + Keyword("dynamic"), + Operators.QuestionMark, + Local("a")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsUsingAliasForClass(TestHost testHost) + { + await TestAsync( @"using dynamic = System.EventArgs;", - testHost, - Keyword("using"), - Class("dynamic"), - Operators.Equals, - Namespace("System"), - Operators.Dot, - Class("EventArgs"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsUsingAliasForDelegate(TestHost testHost) - { - await TestAsync( + testHost, + Keyword("using"), + Class("dynamic"), + Operators.Equals, + Namespace("System"), + Operators.Dot, + Class("EventArgs"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsUsingAliasForDelegate(TestHost testHost) + { + await TestAsync( @"using dynamic = System.Action;", - testHost, - Keyword("using"), - Delegate("dynamic"), - Operators.Equals, - Namespace("System"), - Operators.Dot, - Delegate("Action"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsUsingAliasForStruct(TestHost testHost) - { - await TestAsync( + testHost, + Keyword("using"), + Delegate("dynamic"), + Operators.Equals, + Namespace("System"), + Operators.Dot, + Delegate("Action"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsUsingAliasForStruct(TestHost testHost) + { + await TestAsync( @"using dynamic = System.DateTime;", - testHost, - Keyword("using"), - Struct("dynamic"), - Operators.Equals, - Namespace("System"), - Operators.Dot, - Struct("DateTime"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsUsingAliasForEnum(TestHost testHost) - { - await TestAsync( + testHost, + Keyword("using"), + Struct("dynamic"), + Operators.Equals, + Namespace("System"), + Operators.Dot, + Struct("DateTime"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsUsingAliasForEnum(TestHost testHost) + { + await TestAsync( @"using dynamic = System.DayOfWeek;", - testHost, - Keyword("using"), - Enum("dynamic"), - Operators.Equals, - Namespace("System"), - Operators.Dot, - Enum("DayOfWeek"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsUsingAliasForInterface(TestHost testHost) - { - await TestAsync( + testHost, + Keyword("using"), + Enum("dynamic"), + Operators.Equals, + Namespace("System"), + Operators.Dot, + Enum("DayOfWeek"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsUsingAliasForInterface(TestHost testHost) + { + await TestAsync( @"using dynamic = System.IDisposable;", - testHost, - Keyword("using"), - Interface("dynamic"), - Operators.Equals, - Namespace("System"), - Operators.Dot, - Interface("IDisposable"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsExternAlias(TestHost testHost) - { - await TestAsync( - """ - extern alias dynamic; - - class C - { - dynamic::Goo a; - } - """, - testHost, - Keyword("extern"), - Keyword("alias"), - Namespace("dynamic"), - Punctuation.Semicolon, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Namespace("dynamic"), - Operators.ColonColon, - Identifier("Goo"), - Field("a"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsDelegateType(TestHost testHost) - { - await TestAsync(@"delegate void dynamic()", - testHost, - Keyword("delegate"), - Keyword("void"), - Delegate("dynamic"), - Punctuation.OpenParen, - Punctuation.CloseParen); - } - - [Theory, CombinatorialData] - public async Task DynamicAsDelegateReturnTypeAndParam(TestHost testHost) - { - await TestAsync(@"delegate dynamic MyDelegate (dynamic d)", - testHost, - Keyword("delegate"), - Keyword("dynamic"), - Delegate("MyDelegate"), - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("d"), - Punctuation.CloseParen); - } - - [Theory, CombinatorialData] - public async Task DynamicAsDelegateLocalVariable(TestHost testHost) - { - await TestInMethodAsync( - """ - Func f = delegate - { - int dynamic = 10; - return dynamic.ToString(); - }; - """, - testHost, - Identifier("Func"), - Punctuation.OpenAngle, - Keyword("string"), - Punctuation.CloseAngle, - Local("f"), - Operators.Equals, - Keyword("delegate"), - Punctuation.OpenCurly, - Keyword("int"), - Local("dynamic"), - Operators.Equals, - Number("10"), - Punctuation.Semicolon, - ControlKeyword("return"), - Local("dynamic"), - Operators.Dot, - Method("ToString"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsGenericTypeName(TestHost testHost) - { - await TestAsync( - """ - partial class dynamic - { - } + testHost, + Keyword("using"), + Interface("dynamic"), + Operators.Equals, + Namespace("System"), + Operators.Dot, + Interface("IDisposable"), + Punctuation.Semicolon); + } - class C - { - dynamic d; - } - """, - testHost, - Keyword("partial"), - Keyword("class"), - Class("dynamic"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Keyword("class"), - Class("C"), - Punctuation.OpenCurly, - Class("dynamic"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Field("d"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsGenericField(TestHost testHost) - { - await TestAsync( - """ - class A - { - T dynamic; - } - """, - testHost, - Keyword("class"), - Class("A"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Punctuation.OpenCurly, - TypeParameter("T"), - Field("dynamic"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsIndexerTypeAndParameter(TestHost testHost) - { - await TestInClassAsync(@"dynamic this[dynamic i]", - testHost, - Keyword("dynamic"), - Keyword("this"), - Punctuation.OpenBracket, - Keyword("dynamic"), - Parameter("i"), - Punctuation.CloseBracket); - } - - [Theory, CombinatorialData] - public async Task DynamicAsOperatorTypeAndParameter(TestHost testHost) - { - await TestInClassAsync(@"static dynamic operator +(dynamic d1)", - testHost, - Keyword("static"), - Keyword("dynamic"), - Keyword("operator"), - Operators.Plus, - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("d1"), - Punctuation.CloseParen); - } - - [Theory, CombinatorialData] - public async Task DynamicAsOperatorName(TestHost testHost) - { - await TestInClassAsync(@"static explicit operator dynamic(dynamic s)", - testHost, - Keyword("static"), - Keyword("explicit"), - Keyword("operator"), - Keyword("dynamic"), - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("s"), - Punctuation.CloseParen); - } - - [Theory, CombinatorialData] - public async Task DynamicAsPropertyTypeAndName(TestHost testHost) - { - await TestInClassAsync(@"dynamic dynamic { get; set; }", - testHost, - Keyword("dynamic"), - Property("dynamic"), - Punctuation.OpenCurly, - Keyword("get"), - Punctuation.Semicolon, - Keyword("set"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsEventName(TestHost testHost) - { - await TestInClassAsync(@"event Action dynamic", - testHost, - Keyword("event"), - Identifier("Action"), - Event("dynamic")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsLinqLocalVariable(TestHost testHost) - { - await TestInMethodAsync(@"var v = from dynamic in names", - testHost, - Keyword("var"), - Local("v"), - Operators.Equals, - Keyword("from"), - Identifier("dynamic"), - Keyword("in"), - Identifier("names")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsAnonymousTypePropertyName(TestHost testHost) - { - await TestInMethodAsync( - """ - var v = from dynamic in names - select new { dynamic = dynamic }; - """, - testHost, - Keyword("var"), - Local("v"), - Operators.Equals, - Keyword("from"), - Identifier("dynamic"), - Keyword("in"), - Identifier("names"), - Keyword("select"), - Keyword("new"), - Punctuation.OpenCurly, - Property("dynamic"), - Operators.Equals, - Identifier("dynamic"), - Punctuation.CloseCurly, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsArgumentToLambdaExpression(TestHost testHost) - { - await TestInMethodAsync( + [Theory, CombinatorialData] + public async Task DynamicAsExternAlias(TestHost testHost) + { + await TestAsync( + """ + extern alias dynamic; + + class C + { + dynamic::Goo a; + } + """, + testHost, + Keyword("extern"), + Keyword("alias"), + Namespace("dynamic"), + Punctuation.Semicolon, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Namespace("dynamic"), + Operators.ColonColon, + Identifier("Goo"), + Field("a"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsDelegateType(TestHost testHost) + { + await TestAsync(@"delegate void dynamic()", + testHost, + Keyword("delegate"), + Keyword("void"), + Delegate("dynamic"), + Punctuation.OpenParen, + Punctuation.CloseParen); + } + + [Theory, CombinatorialData] + public async Task DynamicAsDelegateReturnTypeAndParam(TestHost testHost) + { + await TestAsync(@"delegate dynamic MyDelegate (dynamic d)", + testHost, + Keyword("delegate"), + Keyword("dynamic"), + Delegate("MyDelegate"), + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("d"), + Punctuation.CloseParen); + } + + [Theory, CombinatorialData] + public async Task DynamicAsDelegateLocalVariable(TestHost testHost) + { + await TestInMethodAsync( + """ + Func f = delegate + { + int dynamic = 10; + return dynamic.ToString(); + }; + """, + testHost, + Identifier("Func"), + Punctuation.OpenAngle, + Keyword("string"), + Punctuation.CloseAngle, + Local("f"), + Operators.Equals, + Keyword("delegate"), + Punctuation.OpenCurly, + Keyword("int"), + Local("dynamic"), + Operators.Equals, + Number("10"), + Punctuation.Semicolon, + ControlKeyword("return"), + Local("dynamic"), + Operators.Dot, + Method("ToString"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsGenericTypeName(TestHost testHost) + { + await TestAsync( + """ + partial class dynamic + { + } + + class C + { + dynamic d; + } + """, + testHost, + Keyword("partial"), + Keyword("class"), + Class("dynamic"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Keyword("class"), + Class("C"), + Punctuation.OpenCurly, + Class("dynamic"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Field("d"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsGenericField(TestHost testHost) + { + await TestAsync( + """ + class A + { + T dynamic; + } + """, + testHost, + Keyword("class"), + Class("A"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Punctuation.OpenCurly, + TypeParameter("T"), + Field("dynamic"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsIndexerTypeAndParameter(TestHost testHost) + { + await TestInClassAsync(@"dynamic this[dynamic i]", + testHost, + Keyword("dynamic"), + Keyword("this"), + Punctuation.OpenBracket, + Keyword("dynamic"), + Parameter("i"), + Punctuation.CloseBracket); + } + + [Theory, CombinatorialData] + public async Task DynamicAsOperatorTypeAndParameter(TestHost testHost) + { + await TestInClassAsync(@"static dynamic operator +(dynamic d1)", + testHost, + Keyword("static"), + Keyword("dynamic"), + Keyword("operator"), + Operators.Plus, + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("d1"), + Punctuation.CloseParen); + } + + [Theory, CombinatorialData] + public async Task DynamicAsOperatorName(TestHost testHost) + { + await TestInClassAsync(@"static explicit operator dynamic(dynamic s)", + testHost, + Keyword("static"), + Keyword("explicit"), + Keyword("operator"), + Keyword("dynamic"), + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("s"), + Punctuation.CloseParen); + } + + [Theory, CombinatorialData] + public async Task DynamicAsPropertyTypeAndName(TestHost testHost) + { + await TestInClassAsync(@"dynamic dynamic { get; set; }", + testHost, + Keyword("dynamic"), + Property("dynamic"), + Punctuation.OpenCurly, + Keyword("get"), + Punctuation.Semicolon, + Keyword("set"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsEventName(TestHost testHost) + { + await TestInClassAsync(@"event Action dynamic", + testHost, + Keyword("event"), + Identifier("Action"), + Event("dynamic")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsLinqLocalVariable(TestHost testHost) + { + await TestInMethodAsync(@"var v = from dynamic in names", + testHost, + Keyword("var"), + Local("v"), + Operators.Equals, + Keyword("from"), + Identifier("dynamic"), + Keyword("in"), + Identifier("names")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsAnonymousTypePropertyName(TestHost testHost) + { + await TestInMethodAsync( + """ + var v = from dynamic in names + select new { dynamic = dynamic }; + """, + testHost, + Keyword("var"), + Local("v"), + Operators.Equals, + Keyword("from"), + Identifier("dynamic"), + Keyword("in"), + Identifier("names"), + Keyword("select"), + Keyword("new"), + Punctuation.OpenCurly, + Property("dynamic"), + Operators.Equals, + Identifier("dynamic"), + Punctuation.CloseCurly, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsArgumentToLambdaExpression(TestHost testHost) + { + await TestInMethodAsync( @"var p = names.Select(dynamic => dynamic.Length);", - testHost, - Keyword("var"), - Local("p"), - Operators.Equals, - Identifier("names"), - Operators.Dot, - Identifier("Select"), - Punctuation.OpenParen, - Parameter("dynamic"), - Operators.EqualsGreaterThan, - Parameter("dynamic"), - Operators.Dot, - Identifier("Length"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsAnonymousMethodLocalVariable(TestHost testHost) - { - await TestInMethodAsync( - """ - D f = delegate - { - string dynamic = "a"; - return dynamic.Length; - }; - """, - testHost, - Identifier("D"), - Local("f"), - Operators.Equals, - Keyword("delegate"), - Punctuation.OpenCurly, - Keyword("string"), - Local("dynamic"), - Operators.Equals, - String(""" - "a" - """), - Punctuation.Semicolon, - ControlKeyword("return"), - Local("dynamic"), - Operators.Dot, - Property("Length"), - Punctuation.Semicolon, - Punctuation.CloseCurly, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsMethodName(TestHost testHost) - { - await TestInClassAsync( - """ - dynamic dynamic() - { - } - """, - testHost, - Keyword("dynamic"), - Method("dynamic"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsStaticMethodTypeAndParams(TestHost testHost) - { - await TestInClassAsync( - """ - static dynamic dynamic(params dynamic[] dynamic) - { - } - """, - testHost, - Keyword("static"), - Keyword("dynamic"), - Method("dynamic"), - Static("dynamic"), - Punctuation.OpenParen, - Keyword("params"), - Keyword("dynamic"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("dynamic"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicArraysInMethodSignature(TestHost testHost) - { - await TestInClassAsync( - """ - dynamic[] M(dynamic[] p, params dynamic[] pa) - { - } - """, - testHost, - Keyword("dynamic"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Method("M"), - Punctuation.OpenParen, - Keyword("dynamic"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("p"), - Punctuation.Comma, - Keyword("params"), - Keyword("dynamic"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Parameter("pa"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicInPartialMethods(TestHost testHost) - { - await TestInClassAsync( - """ - partial void F(dynamic d); - - partial void F(dynamic d) - { - } - """, - testHost, - Keyword("partial"), - Keyword("void"), - Method("F"), - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("d"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Keyword("partial"), - Keyword("void"), - Method("F"), - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("d"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicRefAndOutParameters(TestHost testHost) - { - await TestInClassAsync( - """ - void F(ref dynamic r, out dynamic o) - { - } - """, - testHost, - Keyword("void"), - Method("F"), - Punctuation.OpenParen, - Keyword("ref"), - Keyword("dynamic"), - Parameter("r"), - Punctuation.Comma, - Keyword("out"), - Keyword("dynamic"), - Parameter("o"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicInExtensionMethod(TestHost testHost) - { - await TestInClassAsync( - """ - dynamic F(this dynamic self, dynamic p) - { - } - """, - testHost, - Keyword("dynamic"), - ExtensionMethod("F"), - Punctuation.OpenParen, - Keyword("this"), - Keyword("dynamic"), - Parameter("self"), - Punctuation.Comma, - Keyword("dynamic"), - Parameter("p"), - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsBaseClass(TestHost testHost) - { - await TestAsync( - """ - class C : dynamic - { - } - """, - testHost, - Keyword("class"), - Class("C"), - Punctuation.Colon, - Keyword("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsGenericConstraint(TestHost testHost) - { - await TestAsync( - """ - class C where T : dynamic - { - } - """, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenAngle, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("T"), - Punctuation.Colon, - Keyword("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicSizeOf(TestHost testHost) - { - await TestInClassAsync( - """ - unsafe int M() - { - return sizeof(dynamic); - } - """, - testHost, - Keyword("unsafe"), - Keyword("int"), - Method("M"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - ControlKeyword("return"), - Keyword("sizeof"), - Punctuation.OpenParen, - Keyword("dynamic"), - Punctuation.CloseParen, - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicTypeOf(TestHost testHost) - { - await TestInMethodAsync(@"typeof(dynamic)", - testHost, - Keyword("typeof"), - Punctuation.OpenParen, - Keyword("dynamic"), - Punctuation.CloseParen); - } - - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] - [CombinatorialData] - public async Task DynamicAsArrayName(bool script, TestHost testHost) - { - var code = - """ - int[] dynamic = { - 1 - }; - """; - - var parseOptions = script ? Options.Script : null; - - await TestAsync( - code, - code, - testHost, - parseOptions, - Keyword("int"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - script ? Field("dynamic") : Local("dynamic"), - Operators.Equals, - Punctuation.OpenCurly, - Number("1"), - Punctuation.CloseCurly, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicInForeach(TestHost testHost) - { - await TestInMethodAsync(@"foreach (dynamic dynamic in dynamic", - testHost, - ControlKeyword("foreach"), - Punctuation.OpenParen, - Keyword("dynamic"), - Local("dynamic"), - ControlKeyword("in"), - Identifier("dynamic")); - } - - [Theory, CombinatorialData] - public async Task DynamicInUsing(TestHost testHost) - { - await TestInMethodAsync(@"using(dynamic d", - testHost, - Keyword("using"), - Punctuation.OpenParen, - Keyword("dynamic"), - Local("d")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsLocalVariableName(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Keyword("var"), + Local("p"), + Operators.Equals, + Identifier("names"), + Operators.Dot, + Identifier("Select"), + Punctuation.OpenParen, + Parameter("dynamic"), + Operators.EqualsGreaterThan, + Parameter("dynamic"), + Operators.Dot, + Identifier("Length"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsAnonymousMethodLocalVariable(TestHost testHost) + { + await TestInMethodAsync( + """ + D f = delegate + { + string dynamic = "a"; + return dynamic.Length; + }; + """, + testHost, + Identifier("D"), + Local("f"), + Operators.Equals, + Keyword("delegate"), + Punctuation.OpenCurly, + Keyword("string"), + Local("dynamic"), + Operators.Equals, + String(""" + "a" + """), + Punctuation.Semicolon, + ControlKeyword("return"), + Local("dynamic"), + Operators.Dot, + Property("Length"), + Punctuation.Semicolon, + Punctuation.CloseCurly, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsMethodName(TestHost testHost) + { + await TestInClassAsync( + """ + dynamic dynamic() + { + } + """, + testHost, + Keyword("dynamic"), + Method("dynamic"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsStaticMethodTypeAndParams(TestHost testHost) + { + await TestInClassAsync( + """ + static dynamic dynamic(params dynamic[] dynamic) + { + } + """, + testHost, + Keyword("static"), + Keyword("dynamic"), + Method("dynamic"), + Static("dynamic"), + Punctuation.OpenParen, + Keyword("params"), + Keyword("dynamic"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("dynamic"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicArraysInMethodSignature(TestHost testHost) + { + await TestInClassAsync( + """ + dynamic[] M(dynamic[] p, params dynamic[] pa) + { + } + """, + testHost, + Keyword("dynamic"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Method("M"), + Punctuation.OpenParen, + Keyword("dynamic"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("p"), + Punctuation.Comma, + Keyword("params"), + Keyword("dynamic"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Parameter("pa"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicInPartialMethods(TestHost testHost) + { + await TestInClassAsync( + """ + partial void F(dynamic d); + + partial void F(dynamic d) + { + } + """, + testHost, + Keyword("partial"), + Keyword("void"), + Method("F"), + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("d"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Keyword("partial"), + Keyword("void"), + Method("F"), + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("d"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicRefAndOutParameters(TestHost testHost) + { + await TestInClassAsync( + """ + void F(ref dynamic r, out dynamic o) + { + } + """, + testHost, + Keyword("void"), + Method("F"), + Punctuation.OpenParen, + Keyword("ref"), + Keyword("dynamic"), + Parameter("r"), + Punctuation.Comma, + Keyword("out"), + Keyword("dynamic"), + Parameter("o"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicInExtensionMethod(TestHost testHost) + { + await TestInClassAsync( + """ + dynamic F(this dynamic self, dynamic p) + { + } + """, + testHost, + Keyword("dynamic"), + ExtensionMethod("F"), + Punctuation.OpenParen, + Keyword("this"), + Keyword("dynamic"), + Parameter("self"), + Punctuation.Comma, + Keyword("dynamic"), + Parameter("p"), + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsBaseClass(TestHost testHost) + { + await TestAsync( + """ + class C : dynamic + { + } + """, + testHost, + Keyword("class"), + Class("C"), + Punctuation.Colon, + Keyword("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsGenericConstraint(TestHost testHost) + { + await TestAsync( + """ + class C where T : dynamic + { + } + """, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenAngle, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("T"), + Punctuation.Colon, + Keyword("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicSizeOf(TestHost testHost) + { + await TestInClassAsync( + """ + unsafe int M() + { + return sizeof(dynamic); + } + """, + testHost, + Keyword("unsafe"), + Keyword("int"), + Method("M"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + ControlKeyword("return"), + Keyword("sizeof"), + Punctuation.OpenParen, + Keyword("dynamic"), + Punctuation.CloseParen, + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicTypeOf(TestHost testHost) + { + await TestInMethodAsync(@"typeof(dynamic)", + testHost, + Keyword("typeof"), + Punctuation.OpenParen, + Keyword("dynamic"), + Punctuation.CloseParen); + } + + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/44423")] + [CombinatorialData] + public async Task DynamicAsArrayName(bool script, TestHost testHost) + { + var code = + """ + int[] dynamic = { + 1 + }; + """; + + var parseOptions = script ? Options.Script : null; + + await TestAsync( + code, + code, + testHost, + parseOptions, + Keyword("int"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + script ? Field("dynamic") : Local("dynamic"), + Operators.Equals, + Punctuation.OpenCurly, + Number("1"), + Punctuation.CloseCurly, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicInForeach(TestHost testHost) + { + await TestInMethodAsync(@"foreach (dynamic dynamic in dynamic", + testHost, + ControlKeyword("foreach"), + Punctuation.OpenParen, + Keyword("dynamic"), + Local("dynamic"), + ControlKeyword("in"), + Identifier("dynamic")); + } + + [Theory, CombinatorialData] + public async Task DynamicInUsing(TestHost testHost) + { + await TestInMethodAsync(@"using(dynamic d", + testHost, + Keyword("using"), + Punctuation.OpenParen, + Keyword("dynamic"), + Local("d")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsLocalVariableName(TestHost testHost) + { + await TestInMethodAsync( @"dynamic dynamic;", - testHost, - Keyword("dynamic"), - Local("dynamic"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsNamespaceName(TestHost testHost) - { - await TestAsync( - """ - namespace dynamic - { - } - """, - testHost, - Keyword("namespace"), - Namespace("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsClassName(TestHost testHost) - { - await TestAsync( - """ - class dynamic - { - } - """, - testHost, - Keyword("class"), - Class("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsConstructorDeclarationName(TestHost testHost) - { - await TestAsync( - """ - class dynamic + testHost, + Keyword("dynamic"), + Local("dynamic"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsNamespaceName(TestHost testHost) + { + await TestAsync( + """ + namespace dynamic + { + } + """, + testHost, + Keyword("namespace"), + Namespace("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsClassName(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + } + """, + testHost, + Keyword("class"), + Class("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsConstructorDeclarationName(TestHost testHost) + { + await TestAsync( + """ + class dynamic + { + dynamic() { - dynamic() - { - } } - """, - testHost, - Keyword("class"), - Class("dynamic"), - Punctuation.OpenCurly, - Class("dynamic"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.OpenCurly, - Punctuation.CloseCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsNamespaceAlias(TestHost testHost) - { - await TestInMethodAsync( + } + """, + testHost, + Keyword("class"), + Class("dynamic"), + Punctuation.OpenCurly, + Class("dynamic"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.OpenCurly, + Punctuation.CloseCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsNamespaceAlias(TestHost testHost) + { + await TestInMethodAsync( @"dynamic.FileInfo file;", - testHost, - Identifier("dynamic"), - Operators.Dot, - Identifier("FileInfo"), - Local("file"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsGotoLabel(TestHost testHost) - { - await TestInMethodAsync( - """ - dynamic: int i = 0; - goto dynamic; - """, - testHost, - Label("dynamic"), - Punctuation.Colon, - Keyword("int"), - Local("i"), - Operators.Equals, - Number("0"), - Punctuation.Semicolon, - ControlKeyword("goto"), - Label("dynamic"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsEnumField(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Identifier("dynamic"), + Operators.Dot, + Identifier("FileInfo"), + Local("file"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsGotoLabel(TestHost testHost) + { + await TestInMethodAsync( + """ + dynamic: int i = 0; + goto dynamic; + """, + testHost, + Label("dynamic"), + Punctuation.Colon, + Keyword("int"), + Local("i"), + Operators.Equals, + Number("0"), + Punctuation.Semicolon, + ControlKeyword("goto"), + Label("dynamic"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsEnumField(TestHost testHost) + { + await TestInMethodAsync( @"A a = A.dynamic;", - testHost, - Identifier("A"), - Local("a"), - Operators.Equals, - Identifier("A"), - Operators.Dot, - Identifier("dynamic"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsEnumFieldDefinition(TestHost testHost) - { - await TestAsync( - """ - enum A - { - dynamic - } - """, - testHost, - Keyword("enum"), - Enum("A"), - Punctuation.OpenCurly, - EnumMember("dynamic"), - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsEnumType(TestHost testHost) - { - await TestAsync( - """ - enum dynamic - { - } - """, - testHost, - Keyword("enum"), - Enum("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsGenericTypeParameter(TestHost testHost) - { - await TestAsync( - """ - class C where dynamic : T - { - dynamic d; - } - """, - testHost, - Keyword("class"), - Class("C"), - Punctuation.OpenAngle, - TypeParameter("dynamic"), - Punctuation.Comma, - TypeParameter("T"), - Punctuation.CloseAngle, - Keyword("where"), - TypeParameter("dynamic"), - Punctuation.Colon, - TypeParameter("T"), - Punctuation.OpenCurly, - TypeParameter("dynamic"), - Field("d"), - Punctuation.Semicolon, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsFieldType(TestHost testHost) - { - await TestInClassAsync(@"dynamic d", - testHost, - Keyword("dynamic"), - Field("d")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsStaticFieldType(TestHost testHost) - { - await TestInClassAsync(@"static dynamic d", - testHost, - Keyword("static"), - Keyword("dynamic"), - Field("d"), - Static("d")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsLocalVariableType(TestHost testHost) - { - await TestInMethodAsync(@"dynamic d", - testHost, - Keyword("dynamic"), - Local("d")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsArrayLocalVariableType(TestHost testHost) - { - await TestInMethodAsync(@"dynamic[] d", - testHost, - Keyword("dynamic"), - Punctuation.OpenBracket, - Punctuation.CloseBracket, - Local("d")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsLambdaParameterType(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Identifier("A"), + Local("a"), + Operators.Equals, + Identifier("A"), + Operators.Dot, + Identifier("dynamic"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsEnumFieldDefinition(TestHost testHost) + { + await TestAsync( + """ + enum A + { + dynamic + } + """, + testHost, + Keyword("enum"), + Enum("A"), + Punctuation.OpenCurly, + EnumMember("dynamic"), + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsEnumType(TestHost testHost) + { + await TestAsync( + """ + enum dynamic + { + } + """, + testHost, + Keyword("enum"), + Enum("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsGenericTypeParameter(TestHost testHost) + { + await TestAsync( + """ + class C where dynamic : T + { + dynamic d; + } + """, + testHost, + Keyword("class"), + Class("C"), + Punctuation.OpenAngle, + TypeParameter("dynamic"), + Punctuation.Comma, + TypeParameter("T"), + Punctuation.CloseAngle, + Keyword("where"), + TypeParameter("dynamic"), + Punctuation.Colon, + TypeParameter("T"), + Punctuation.OpenCurly, + TypeParameter("dynamic"), + Field("d"), + Punctuation.Semicolon, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsFieldType(TestHost testHost) + { + await TestInClassAsync(@"dynamic d", + testHost, + Keyword("dynamic"), + Field("d")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsStaticFieldType(TestHost testHost) + { + await TestInClassAsync(@"static dynamic d", + testHost, + Keyword("static"), + Keyword("dynamic"), + Field("d"), + Static("d")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsLocalVariableType(TestHost testHost) + { + await TestInMethodAsync(@"dynamic d", + testHost, + Keyword("dynamic"), + Local("d")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsArrayLocalVariableType(TestHost testHost) + { + await TestInMethodAsync(@"dynamic[] d", + testHost, + Keyword("dynamic"), + Punctuation.OpenBracket, + Punctuation.CloseBracket, + Local("d")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsLambdaParameterType(TestHost testHost) + { + await TestInMethodAsync( @"var q = a.Where((dynamic d) => d == dynamic);", - testHost, - Keyword("var"), - Local("q"), - Operators.Equals, - Identifier("a"), - Operators.Dot, - Identifier("Where"), - Punctuation.OpenParen, - Punctuation.OpenParen, - Keyword("dynamic"), - Parameter("d"), - Punctuation.CloseParen, - Operators.EqualsGreaterThan, - Parameter("d"), - Operators.EqualsEquals, - Identifier("dynamic"), - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicArray(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Keyword("var"), + Local("q"), + Operators.Equals, + Identifier("a"), + Operators.Dot, + Identifier("Where"), + Punctuation.OpenParen, + Punctuation.OpenParen, + Keyword("dynamic"), + Parameter("d"), + Punctuation.CloseParen, + Operators.EqualsGreaterThan, + Parameter("d"), + Operators.EqualsEquals, + Identifier("dynamic"), + Punctuation.CloseParen, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicArray(TestHost testHost) + { + await TestInMethodAsync( @"dynamic d = new dynamic[5];", - testHost, - Keyword("dynamic"), - Local("d"), - Operators.Equals, - Keyword("new"), - Keyword("dynamic"), - Punctuation.OpenBracket, - Number("5"), - Punctuation.CloseBracket, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicConstructor(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Keyword("dynamic"), + Local("d"), + Operators.Equals, + Keyword("new"), + Keyword("dynamic"), + Punctuation.OpenBracket, + Number("5"), + Punctuation.CloseBracket, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicConstructor(TestHost testHost) + { + await TestInMethodAsync( @"dynamic d = new dynamic();", - testHost, - Keyword("dynamic"), - Local("d"), - Operators.Equals, - Keyword("new"), - Keyword("dynamic"), - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAfterIs(TestHost testHost) - { - await TestInMethodAsync(@"if (a is dynamic)", - testHost, - ControlKeyword("if"), - Punctuation.OpenParen, - Identifier("a"), - Keyword("is"), - Keyword("dynamic"), - Punctuation.CloseParen); - } - - [Theory, CombinatorialData] - public async Task DynamicAfterAs(TestHost testHost) - { - await TestInMethodAsync(@"a = a as dynamic", - testHost, - Identifier("a"), - Operators.Equals, - Identifier("a"), - Keyword("as"), - Keyword("dynamic")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsGenericTypeArgument(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Keyword("dynamic"), + Local("d"), + Operators.Equals, + Keyword("new"), + Keyword("dynamic"), + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAfterIs(TestHost testHost) + { + await TestInMethodAsync(@"if (a is dynamic)", + testHost, + ControlKeyword("if"), + Punctuation.OpenParen, + Identifier("a"), + Keyword("is"), + Keyword("dynamic"), + Punctuation.CloseParen); + } + + [Theory, CombinatorialData] + public async Task DynamicAfterAs(TestHost testHost) + { + await TestInMethodAsync(@"a = a as dynamic", + testHost, + Identifier("a"), + Operators.Equals, + Identifier("a"), + Keyword("as"), + Keyword("dynamic")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsGenericTypeArgument(TestHost testHost) + { + await TestInMethodAsync( @"List l = new List();", - testHost, - Identifier("List"), - Punctuation.OpenAngle, - Keyword("dynamic"), - Punctuation.CloseAngle, - Local("l"), - Operators.Equals, - Keyword("new"), - Identifier("List"), - Punctuation.OpenAngle, - Keyword("dynamic"), - Punctuation.CloseAngle, - Punctuation.OpenParen, - Punctuation.CloseParen, - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsSecondGenericTypeArgument(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Identifier("List"), + Punctuation.OpenAngle, + Keyword("dynamic"), + Punctuation.CloseAngle, + Local("l"), + Operators.Equals, + Keyword("new"), + Identifier("List"), + Punctuation.OpenAngle, + Keyword("dynamic"), + Punctuation.CloseAngle, + Punctuation.OpenParen, + Punctuation.CloseParen, + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsSecondGenericTypeArgument(TestHost testHost) + { + await TestInMethodAsync( @"KVP kvp;", - testHost, - Identifier("KVP"), - Punctuation.OpenAngle, - Keyword("string"), - Punctuation.Comma, - Keyword("dynamic"), - Punctuation.CloseAngle, - Local("kvp"), - Punctuation.Semicolon); - } - - [Theory, CombinatorialData] - public async Task DynamicAsRegionLabel(TestHost testHost) - { - var code = - """ - #region dynamic - #endregion - """; - await TestAsync(code, - testHost, - PPKeyword("#"), - PPKeyword("region"), - PPText("dynamic"), - PPKeyword("#"), - PPKeyword("endregion")); - } - - [Theory, CombinatorialData] - public async Task DynamicAsInterfaceType(TestHost testHost) - { - await TestAsync( - """ - interface dynamic - { - } - """, - testHost, - Keyword("interface"), - Interface("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsStructType(TestHost testHost) - { - await TestAsync( - """ - struct dynamic - { - } - """, - testHost, - Keyword("struct"), - Struct("dynamic"), - Punctuation.OpenCurly, - Punctuation.CloseCurly); - } - - [Theory, CombinatorialData] - public async Task DynamicAsUndefinedGenericType(TestHost testHost) - { - await TestInMethodAsync( + testHost, + Identifier("KVP"), + Punctuation.OpenAngle, + Keyword("string"), + Punctuation.Comma, + Keyword("dynamic"), + Punctuation.CloseAngle, + Local("kvp"), + Punctuation.Semicolon); + } + + [Theory, CombinatorialData] + public async Task DynamicAsRegionLabel(TestHost testHost) + { + var code = + """ + #region dynamic + #endregion + """; + await TestAsync(code, + testHost, + PPKeyword("#"), + PPKeyword("region"), + PPText("dynamic"), + PPKeyword("#"), + PPKeyword("endregion")); + } + + [Theory, CombinatorialData] + public async Task DynamicAsInterfaceType(TestHost testHost) + { + await TestAsync( + """ + interface dynamic + { + } + """, + testHost, + Keyword("interface"), + Interface("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsStructType(TestHost testHost) + { + await TestAsync( + """ + struct dynamic + { + } + """, + testHost, + Keyword("struct"), + Struct("dynamic"), + Punctuation.OpenCurly, + Punctuation.CloseCurly); + } + + [Theory, CombinatorialData] + public async Task DynamicAsUndefinedGenericType(TestHost testHost) + { + await TestInMethodAsync( @"dynamic d;", - testHost, - Identifier("dynamic"), - Punctuation.OpenAngle, - Keyword("int"), - Punctuation.CloseAngle, - Local("d"), - Punctuation.Semicolon); - } + testHost, + Identifier("dynamic"), + Punctuation.OpenAngle, + Keyword("int"), + Punctuation.CloseAngle, + Local("d"), + Punctuation.Semicolon); } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AbstractCSharpCodeActionTest.cs b/src/EditorFeatures/CSharpTest/CodeActions/AbstractCSharpCodeActionTest.cs index 575133729134a..ea798b22286e9 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AbstractCSharpCodeActionTest.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AbstractCSharpCodeActionTest.cs @@ -4,16 +4,13 @@ #nullable disable -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; + +public abstract class AbstractCSharpCodeActionTest : AbstractCodeActionTest { - public abstract class AbstractCSharpCodeActionTest : AbstractCodeActionTest - { - protected override ParseOptions GetScriptOptions() => Options.Script; + protected override ParseOptions GetScriptOptions() => Options.Script; - protected internal override string GetLanguage() => LanguageNames.CSharp; - } + protected internal override string GetLanguage() => LanguageNames.CSharp; } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs index 3f5e231eef485..3dd7865eed439 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AbstractAddUsingTests.cs @@ -15,33 +15,32 @@ using Microsoft.CodeAnalysis.Remote.Testing; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; + +public abstract class AbstractAddUsingTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest { - public abstract class AbstractAddUsingTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + protected AbstractAddUsingTests(ITestOutputHelper logger = null) + : base(logger) { - protected AbstractAddUsingTests(ITestOutputHelper logger = null) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new CSharpAddImportCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new CSharpAddImportCodeFixProvider()); - private protected OptionsCollection SeparateGroups => Option(GenerationOptions.SeparateImportDirectiveGroups, true); + private protected OptionsCollection SeparateGroups => Option(GenerationOptions.SeparateImportDirectiveGroups, true); - internal async Task TestAsync( - string initialMarkup, - string expectedMarkup, - TestHost testHost, - int index = 0, - CodeActionPriority? priority = null, - OptionsCollection options = null) - { - await TestInRegularAndScript1Async( - initialMarkup, - expectedMarkup, - index, - parameters: new TestParameters(options: options, testHost: testHost, priority: priority)); - } + internal async Task TestAsync( + string initialMarkup, + string expectedMarkup, + TestHost testHost, + int index = 0, + CodeActionPriority? priority = null, + OptionsCollection options = null) + { + await TestInRegularAndScript1Async( + initialMarkup, + expectedMarkup, + index, + parameters: new TestParameters(options: options, testHost: testHost, priority: priority)); } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingNuGetTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingNuGetTests.cs index ea2191f721692..a38934a9956c8 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingNuGetTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingNuGetTests.cs @@ -13,10 +13,7 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.AddImport; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; -using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Packaging; -using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.SymbolSearch; using Microsoft.CodeAnalysis.Test.Utilities; using Moq; @@ -24,53 +21,53 @@ using Roslyn.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; + +using FixProviderData = Tuple; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] +public class AddUsingNuGetTests : AbstractAddUsingTests { - using FixProviderData = Tuple; + private static readonly ImmutableArray NugetPackageSources = + ImmutableArray.Create(new PackageSource(PackageSourceHelper.NugetOrgSourceName, "http://nuget.org/")); + + protected override void InitializeWorkspace(EditorTestWorkspace workspace, TestParameters parameters) + { + workspace.GlobalOptions.SetGlobalOption(SymbolSearchOptionsStorage.SearchNuGetPackages, LanguageNames.CSharp, true); + workspace.GlobalOptions.SetGlobalOption(SymbolSearchOptionsStorage.SearchReferenceAssemblies, LanguageNames.CSharp, true); + } - [Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] - public class AddUsingNuGetTests : AbstractAddUsingTests + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer( + Workspace workspace, TestParameters parameters) { - private static readonly ImmutableArray NugetPackageSources = - ImmutableArray.Create(new PackageSource(PackageSourceHelper.NugetOrgSourceName, "http://nuget.org/")); - - protected override void InitializeWorkspace(EditorTestWorkspace workspace, TestParameters parameters) - { - workspace.GlobalOptions.SetGlobalOption(SymbolSearchOptionsStorage.SearchNuGetPackages, LanguageNames.CSharp, true); - workspace.GlobalOptions.SetGlobalOption(SymbolSearchOptionsStorage.SearchReferenceAssemblies, LanguageNames.CSharp, true); - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer( - Workspace workspace, TestParameters parameters) - { - var data = (FixProviderData)parameters.fixProviderData; - return (null, new CSharpAddImportCodeFixProvider(data.Item1, data.Item2)); - } - - protected override ImmutableArray MassageActions(ImmutableArray actions) - => FlattenActions(actions); - - [Fact] - public async Task TestSearchPackageCustomFeedName() - { - var packageSources = ImmutableArray.Create(new PackageSource("My Custom Nuget Feed", "http://nuget.org/")); - - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(packageSources); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(Task.FromResult(true)); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); - - await TestInRegularAndScriptAsync( + var data = (FixProviderData)parameters.fixProviderData; + return (null, new CSharpAddImportCodeFixProvider(data.Item1, data.Item2)); + } + + protected override ImmutableArray MassageActions(ImmutableArray actions) + => FlattenActions(actions); + + [Fact] + public async Task TestSearchPackageCustomFeedName() + { + var packageSources = ImmutableArray.Create(new PackageSource("My Custom Nuget Feed", "http://nuget.org/")); + + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(packageSources); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(Task.FromResult(true)); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -81,29 +78,29 @@ class C { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - } - - [Fact] - public async Task TestSearchPackageFakeNugetFeed() - { - var packageSources = ImmutableArray.Create(new PackageSource("nuget.org", "http://fakenuget.org/")); - - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(packageSources); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(Task.FromResult(true)); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - "nuget.org", "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); - - await TestInRegularAndScriptAsync( + } + + [Fact] + public async Task TestSearchPackageFakeNugetFeed() + { + var packageSources = ImmutableArray.Create(new PackageSource("nuget.org", "http://fakenuget.org/")); + + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(packageSources); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(Task.FromResult(true)); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + "nuget.org", "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -114,27 +111,27 @@ class C { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - } - - [Fact] - public async Task TestSearchPackageSingleName() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(SpecializedTasks.True); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); - - await TestInRegularAndScriptAsync( + } + + [Fact] + public async Task TestSearchPackageSingleName() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(SpecializedTasks.True); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -145,27 +142,27 @@ class C { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - } - - [Fact] - public async Task TestSearchPackageMultipleNames() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(SpecializedTasks.True); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); - - await TestInRegularAndScriptAsync( + } + + [Fact] + public async Task TestSearchPackageMultipleNames() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(SpecializedTasks.True); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -176,52 +173,52 @@ class C { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - } - - [Fact] - public async Task TestMissingIfPackageAlreadyInstalled() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.IsInstalled(It.IsAny(), "NuGetPackage")) - .Returns(true); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); - - await TestMissingInRegularAndScriptAsync( + } + + [Fact] + public async Task TestMissingIfPackageAlreadyInstalled() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.IsInstalled(It.IsAny(), "NuGetPackage")) + .Returns(true); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); + + await TestMissingInRegularAndScriptAsync( @"class C { [|NuGetType|] n; }", new TestParameters(fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object))); - } - - [Fact] - public async Task TestOptionsOffered() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "2.0")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) - .Returns(ImmutableArray.Create("1.0", "2.0")); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); - - var data = new FixProviderData(installerServiceMock.Object, packageServiceMock.Object); - await TestSmartTagTextAsync( + } + + [Fact] + public async Task TestOptionsOffered() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "2.0")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) + .Returns(ImmutableArray.Create("1.0", "2.0")); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2"))); + + var data = new FixProviderData(installerServiceMock.Object, packageServiceMock.Object); + await TestSmartTagTextAsync( @"class C { [|NuGetType|] n; @@ -229,7 +226,7 @@ await TestSmartTagTextAsync( string.Format(FeaturesResources.Use_local_version_0, "1.0"), parameters: new TestParameters(fixProviderData: data)); - await TestSmartTagTextAsync( + await TestSmartTagTextAsync( @"class C { [|NuGetType|] n; @@ -237,34 +234,34 @@ await TestSmartTagTextAsync( string.Format(FeaturesResources.Use_local_version_0, "2.0"), parameters: new TestParameters(index: 1, fixProviderData: data)); - await TestSmartTagTextAsync( + await TestSmartTagTextAsync( @"class C { [|NuGetType|] n; }", FeaturesResources.Find_and_install_latest_version, parameters: new TestParameters(index: 2, fixProviderData: data)); - } - - [Fact] - public async Task TestInstallGetsCalledNoVersion() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", /*versionOpt*/ null, It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(SpecializedTasks.True); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( - PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); - - await TestInRegularAndScriptAsync( + } + + [Fact] + public async Task TestInstallGetsCalledNoVersion() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", /*versionOpt*/ null, It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(SpecializedTasks.True); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync( + PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -275,29 +272,29 @@ class C { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - installerServiceMock.Verify(); - } - - [Fact] - public async Task TestInstallGetsCalledWithVersion() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) - .Returns(ImmutableArray.Create("1.0")); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(SpecializedTasks.True); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); - - await TestInRegularAndScriptAsync( + installerServiceMock.Verify(); + } + + [Fact] + public async Task TestInstallGetsCalledWithVersion() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) + .Returns(ImmutableArray.Create("1.0")); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(SpecializedTasks.True); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -308,29 +305,29 @@ class C { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - installerServiceMock.Verify(); - } - - [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/14516")] - public async Task TestFailedInstallRollsBackFile() - { - var installerServiceMock = new Mock(MockBehavior.Strict); - installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); - installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); - installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) - .Returns(ImmutableArray.Create("1.0")); - installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(SpecializedTasks.False); - - var packageServiceMock = new Mock(MockBehavior.Strict); - packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) - .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); - packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) - .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); - - await TestInRegularAndScriptAsync( + installerServiceMock.Verify(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/14516")] + public async Task TestFailedInstallRollsBackFile() + { + var installerServiceMock = new Mock(MockBehavior.Strict); + installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); + installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), "NuGetPackage")).Returns(false); + installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(ImmutableArray.Empty); + installerServiceMock.Setup(i => i.TryGetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) + .Returns(ImmutableArray.Create("1.0")); + installerServiceMock.Setup(s => s.TryInstallPackageAsync(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny>(), It.IsAny())) + .Returns(SpecializedTasks.False); + + var packageServiceMock = new Mock(MockBehavior.Strict); + packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny())) + .Returns(() => ValueTaskFactory.FromResult(ImmutableArray.Empty)); + packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(PackageSourceHelper.NugetOrgSourceName, "NuGetType", 0, It.IsAny())) + .Returns(() => CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace"))); + + await TestInRegularAndScriptAsync( @"class C { [|NuGetType|] n; @@ -339,21 +336,20 @@ await TestInRegularAndScriptAsync( { NuGetType n; }", fixProviderData: new FixProviderData(installerServiceMock.Object, packageServiceMock.Object)); - installerServiceMock.Verify(); - } - - private static ValueTask> CreateSearchResult( - string packageName, string typeName, ImmutableArray containingNamespaceNames) - { - return CreateSearchResult(new PackageWithTypeResult( - packageName: packageName, rank: 0, typeName: typeName, - version: null, containingNamespaceNames: containingNamespaceNames)); - } - - private static ValueTask> CreateSearchResult(params PackageWithTypeResult[] results) - => new(ImmutableArray.Create(results)); - - private static ImmutableArray CreateNameParts(params string[] parts) - => parts.ToImmutableArray(); + installerServiceMock.Verify(); } + + private static ValueTask> CreateSearchResult( + string packageName, string typeName, ImmutableArray containingNamespaceNames) + { + return CreateSearchResult(new PackageWithTypeResult( + packageName: packageName, rank: 0, typeName: typeName, + version: null, containingNamespaceNames: containingNamespaceNames)); + } + + private static ValueTask> CreateSearchResult(params PackageWithTypeResult[] results) + => new(ImmutableArray.Create(results)); + + private static ImmutableArray CreateNameParts(params string[] parts) + => parts.ToImmutableArray(); } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs index c17cda9948689..d3032a0f779b3 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; @@ -19,20 +18,20 @@ using Xunit.Abstractions; using static Roslyn.Test.Utilities.TestMetadata; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] +public partial class AddUsingTests : AbstractAddUsingTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] - public partial class AddUsingTests : AbstractAddUsingTests + public AddUsingTests(ITestOutputHelper logger) + : base(logger) { - public AddUsingTests(ITestOutputHelper logger) - : base(logger) - { - } + } - [Theory, CombinatorialData] - public async Task TestTypeFromMultipleNamespaces1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestTypeFromMultipleNamespaces1(TestHost testHost) + { + await TestAsync( @"class Class { [|IDictionary|] Method() @@ -49,12 +48,12 @@ IDictionary Method() Goo(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestTypeFromMultipleNamespaces1_FileScopedNamespace_Outer(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestTypeFromMultipleNamespaces1_FileScopedNamespace_Outer(TestHost testHost) + { + await TestAsync( @" namespace N; @@ -77,12 +76,12 @@ IDictionary Method() Goo(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestTypeFromMultipleNamespaces1_FileScopedNamespace_Inner(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestTypeFromMultipleNamespaces1_FileScopedNamespace_Inner(TestHost testHost) + { + await TestAsync( @" namespace N; @@ -108,13 +107,13 @@ IDictionary Method() Goo(); } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/11241")] - public async Task TestAddImportWithCaseChange(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/11241")] + public async Task TestAddImportWithCaseChange(TestHost testHost) + { + await TestAsync( @"namespace N1 { public class TextBox @@ -137,12 +136,12 @@ public class TextBox class Class1 : TextBox { }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestTypeFromMultipleNamespaces2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestTypeFromMultipleNamespaces2(TestHost testHost) + { + await TestAsync( @"class Class { [|IDictionary|] Method() @@ -160,12 +159,12 @@ IDictionary Method() } }", testHost, index: 1); - } + } - [Theory, CombinatorialData] - public async Task TestGenericWithNoArgs(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenericWithNoArgs(TestHost testHost) + { + await TestAsync( @"class Class { [|List|] Method() @@ -182,12 +181,12 @@ List Method() Goo(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestGenericWithCorrectArgs(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenericWithCorrectArgs(TestHost testHost) + { + await TestAsync( @"class Class { [|List|] Method() @@ -204,12 +203,12 @@ List Method() Goo(); } }", testHost); - } + } - [Fact] - public async Task TestGenericWithWrongArgs1() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestGenericWithWrongArgs1() + { + await TestMissingInRegularAndScriptAsync( @"class Class { [|List|] Method() @@ -217,12 +216,12 @@ await TestMissingInRegularAndScriptAsync( Goo(); } }"); - } + } - [Fact] - public async Task TestGenericWithWrongArgs2() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestGenericWithWrongArgs2() + { + await TestMissingInRegularAndScriptAsync( @"class Class { [|List|] Method() @@ -230,12 +229,12 @@ await TestMissingInRegularAndScriptAsync( Goo(); } }"); - } + } - [Theory, CombinatorialData] - public async Task TestGenericInLocalDeclaration(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenericInLocalDeclaration(TestHost testHost) + { + await TestAsync( @"class Class { void Goo() @@ -252,12 +251,12 @@ void Goo() List a = new List(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestGenericItemType(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenericItemType(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class Class @@ -271,12 +270,12 @@ class Class { List l; }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestGenerateWithExistingUsings(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenerateWithExistingUsings(TestHost testHost) + { + await TestAsync( @"using System; class Class @@ -296,12 +295,12 @@ List Method() Goo(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestGenerateInNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenerateInNamespace(TestHost testHost) + { + await TestAsync( @"namespace N { class Class @@ -324,12 +323,12 @@ List Method() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestGenerateInNamespaceWithUsings(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenerateInNamespaceWithUsings(TestHost testHost) + { + await TestAsync( @"namespace N { using System; @@ -355,12 +354,12 @@ List Method() } } }", testHost); - } + } - [Fact] - public async Task TestExistingUsing_ActionCount() - { - await TestActionCountAsync( + [Fact] + public async Task TestExistingUsing_ActionCount() + { + await TestActionCountAsync( @"using System.Collections.Generic; class Class @@ -371,12 +370,12 @@ class Class } }", count: 1); - } + } - [Theory, CombinatorialData] - public async Task TestExistingUsing(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestExistingUsing(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class Class @@ -396,13 +395,13 @@ IDictionary Method() Goo(); } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] - public async Task TestAddUsingForGenericExtensionMethod(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] + public async Task TestAddUsingForGenericExtensionMethod(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class Class @@ -420,12 +419,12 @@ void Method(IList args) { args.Where() } }", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] - public async Task TestAddUsingForNormalExtensionMethod() - { - await TestAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] + public async Task TestAddUsingForNormalExtensionMethod() + { + await TestAsync( @"class Class { void Method(Class args) @@ -461,12 +460,12 @@ public static void Where(this Class c) } }", parseOptions: Options.Regular); - } + } - [Theory, CombinatorialData] - public async Task TestOnEnum(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestOnEnum(TestHost testHost) + { + await TestAsync( @"class Class { void Goo() @@ -503,12 +502,12 @@ enum Colors Blue } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestOnClassInheritance(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestOnClassInheritance(TestHost testHost) + { + await TestAsync( @"class Class : [|Class2|] { } @@ -531,12 +530,12 @@ class Class2 { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestOnImplementedInterface(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestOnImplementedInterface(TestHost testHost) + { + await TestAsync( @"class Class : [|IGoo|] { } @@ -559,12 +558,12 @@ interface IGoo { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAllInBaseList(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAllInBaseList(TestHost testHost) + { + await TestAsync( @"class Class : [|IGoo|], Class2 { } @@ -602,7 +601,7 @@ interface IGoo } }", testHost); - await TestAsync( + await TestAsync( @"using B; class Class : IGoo, [|Class2|] @@ -642,12 +641,12 @@ interface IGoo { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAttributeUnexpanded(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAttributeUnexpanded(TestHost testHost) + { + await TestAsync( @"[[|Obsolete|]] class Class { @@ -658,12 +657,12 @@ class Class class Class { }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAttributeExpanded(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAttributeExpanded(TestHost testHost) + { + await TestAsync( @"[[|ObsoleteAttribute|]] class Class { @@ -674,13 +673,13 @@ class Class class Class { }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538018")] - public async Task TestAfterNew(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538018")] + public async Task TestAfterNew(TestHost testHost) + { + await TestAsync( @"class Class { void Goo() @@ -699,12 +698,12 @@ void Goo() l = new List(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestArgumentsInMethodCall(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestArgumentsInMethodCall(TestHost testHost) + { + await TestAsync( @"class Class { void Test() @@ -721,12 +720,12 @@ void Test() Console.WriteLine(DateTime.Today); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestCallSiteArgs(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestCallSiteArgs(TestHost testHost) + { + await TestAsync( @"class Class { void Test([|DateTime|] dt) @@ -741,12 +740,12 @@ void Test(DateTime dt) { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestUsePartialClass(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestUsePartialClass(TestHost testHost) + { + await TestAsync( @"namespace A { public class Class @@ -777,12 +776,12 @@ public partial class PClass { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestGenericClassInNestedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestGenericClassInNestedNamespace(TestHost testHost) + { + await TestAsync( @"namespace A { namespace B @@ -819,13 +818,13 @@ class Class GenericClass c; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] - public async Task TestExtensionMethods(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] + public async Task TestExtensionMethods(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class Goo @@ -847,13 +846,13 @@ void Bar() values.Where(i => i > 1); } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] - public async Task TestQueryPatterns(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541730")] + public async Task TestQueryPatterns(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; class Goo @@ -879,13 +878,13 @@ where v > 1 select v + 10; } }", testHost); - } + } - // Tests for Insertion Order - [Theory, CombinatorialData] - public async Task TestSimplePresortedUsings1(TestHost testHost) - { - await TestAsync( + // Tests for Insertion Order + [Theory, CombinatorialData] + public async Task TestSimplePresortedUsings1(TestHost testHost) + { + await TestAsync( @"using B; using C; @@ -927,12 +926,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimplePresortedUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimplePresortedUsings2(TestHost testHost) + { + await TestAsync( @"using B; using C; @@ -974,12 +973,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleUnsortedUsings1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleUnsortedUsings1(TestHost testHost) + { + await TestAsync( @"using C; using B; @@ -1021,12 +1020,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleUnsortedUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleUnsortedUsings2(TestHost testHost) + { + await TestAsync( @"using D; using B; @@ -1068,12 +1067,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestMultiplePresortedUsings1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestMultiplePresortedUsings1(TestHost testHost) + { + await TestAsync( @"using B.X; using B.Y; @@ -1115,12 +1114,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestMultiplePresortedUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestMultiplePresortedUsings2(TestHost testHost) + { + await TestAsync( @"using B.X; using B.Y; @@ -1162,12 +1161,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestMultiplePresortedUsings3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestMultiplePresortedUsings3(TestHost testHost) + { + await TestAsync( @"using B.X; using B.Y; @@ -1215,12 +1214,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestMultipleUnsortedUsings1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestMultipleUnsortedUsings1(TestHost testHost) + { + await TestAsync( @"using B.Y; using B.X; @@ -1268,12 +1267,12 @@ public static void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestMultipleUnsortedUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestMultipleUnsortedUsings2(TestHost testHost) + { + await TestAsync( @"using B.Y; using B.X; @@ -1315,13 +1314,13 @@ public static void Bar() } } }", testHost); - } + } - // System on top cases - [Theory, CombinatorialData] - public async Task TestSimpleSystemSortedUsings1(TestHost testHost) - { - await TestAsync( + // System on top cases + [Theory, CombinatorialData] + public async Task TestSimpleSystemSortedUsings1(TestHost testHost) + { + await TestAsync( @"using System; using B; @@ -1364,12 +1363,12 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemSortedUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemSortedUsings2(TestHost testHost) + { + await TestAsync( @"using System; using System.Collections.Generic; using B; @@ -1414,12 +1413,12 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemSortedUsings3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemSortedUsings3(TestHost testHost) + { + await TestAsync( @"using A; using B; @@ -1442,12 +1441,12 @@ void Method() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemUnsortedUsings1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemUnsortedUsings1(TestHost testHost) + { + await TestAsync( @" using C; using B; @@ -1494,12 +1493,12 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemUnsortedUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemUnsortedUsings2(TestHost testHost) + { + await TestAsync( @"using System.Collections.Generic; using System; using B; @@ -1544,12 +1543,12 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemUnsortedUsings3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemUnsortedUsings3(TestHost testHost) + { + await TestAsync( @"using B; using A; @@ -1572,12 +1571,12 @@ void Method() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleBogusSystemUsings1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleBogusSystemUsings1(TestHost testHost) + { + await TestAsync( @"using A.System; class Class @@ -1598,12 +1597,12 @@ void Method() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleBogusSystemUsings2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleBogusSystemUsings2(TestHost testHost) + { + await TestAsync( @"using System.System; class Class @@ -1624,12 +1623,12 @@ void Method() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestUsingsWithComments(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestUsingsWithComments(TestHost testHost) + { + await TestAsync( @"using System./*...*/.Collections.Generic; class Class @@ -1650,13 +1649,13 @@ void Method() } }", testHost); - } + } - // System Not on top cases - [Theory, CombinatorialData] - public async Task TestSimpleSystemUnsortedUsings4(TestHost testHost) - { - await TestAsync( + // System Not on top cases + [Theory, CombinatorialData] + public async Task TestSimpleSystemUnsortedUsings4(TestHost testHost) + { + await TestAsync( @" using C; using System; @@ -1703,12 +1702,12 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemSortedUsings5(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemSortedUsings5(TestHost testHost) + { + await TestAsync( @"using B; using System; @@ -1751,12 +1750,12 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestSimpleSystemSortedUsings4(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestSimpleSystemSortedUsings4(TestHost testHost) + { + await TestAsync( @"using A; using B; @@ -1779,13 +1778,13 @@ void Method() } }", testHost, options: Option(GenerationOptions.PlaceSystemNamespaceFirst, false)); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538136")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538763")] - public async Task TestAddUsingForNamespace() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538136")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538763")] + public async Task TestAddUsingForNamespace() + { + await TestMissingInRegularAndScriptAsync( @"namespace A { class Class @@ -1803,47 +1802,47 @@ class Test } } }"); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538220")] - public async Task TestAddUsingForFieldWithFormatting(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538220")] + public async Task TestAddUsingForFieldWithFormatting(TestHost testHost) + { + await TestAsync( @"class C { [|DateTime|] t; }", @"using System; class C { DateTime t; }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539657")] - public async Task BugFix5688(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539657")] + public async Task BugFix5688(TestHost testHost) + { + await TestAsync( @"class Program { static void Main ( string [ ] args ) { [|Console|] . Out . NewLine = ""\r\n\r\n"" ; } } ", @"using System; class Program { static void Main ( string [ ] args ) { Console . Out . NewLine = ""\r\n\r\n"" ; } } ", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539853")] - public async Task BugFix5950() - { - await TestAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539853")] + public async Task BugFix5950() + { + await TestAsync( @"using System.Console; WriteLine([|Expression|].Constant(123));", @"using System.Console; using System.Linq.Expressions; WriteLine(Expression.Constant(123));", parseOptions: GetScriptOptions()); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540339")] - public async Task TestAddAfterDefineDirective1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540339")] + public async Task TestAddAfterDefineDirective1(TestHost testHost) + { + await TestAsync( @"#define goo using System.Collections.Generic; @@ -1869,13 +1868,13 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540339")] - public async Task TestAddAfterDefineDirective2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540339")] + public async Task TestAddAfterDefineDirective2(TestHost testHost) + { + await TestAsync( @"#define goo class Program @@ -1896,12 +1895,12 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddAfterDefineDirective3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddAfterDefineDirective3(TestHost testHost) + { + await TestAsync( @"#define goo /// Goo @@ -1924,12 +1923,12 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddAfterDefineDirective4(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddAfterDefineDirective4(TestHost testHost) + { + await TestAsync( @"#define goo // Goo @@ -1952,12 +1951,12 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddAfterExistingBanner(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddAfterExistingBanner(TestHost testHost) + { + await TestAsync( @"// Banner // Banner @@ -1980,12 +1979,12 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddAfterExternAlias1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddAfterExternAlias1(TestHost testHost) + { + await TestAsync( @"#define goo extern alias Goo; @@ -2010,12 +2009,12 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddAfterExternAlias2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddAfterExternAlias2(TestHost testHost) + { + await TestAsync( @"#define goo extern alias Goo; @@ -2043,17 +2042,17 @@ static void Main(string[] args) Console.WriteLine(); } }", testHost); - } + } - [Fact] - public async Task TestWithReferenceDirective() + [Fact] + public async Task TestWithReferenceDirective() + { + var resolver = new TestMetadataReferenceResolver(assemblyNames: new Dictionary() { - var resolver = new TestMetadataReferenceResolver(assemblyNames: new Dictionary() - { - { "exprs", AssemblyMetadata.CreateFromImage(ResourcesNet451.SystemCore).GetReference() } - }); + { "exprs", AssemblyMetadata.CreateFromImage(ResourcesNet451.SystemCore).GetReference() } + }); - await TestAsync( + await TestAsync( @"#r ""exprs"" [|Expression|]", @"#r ""exprs"" @@ -2062,23 +2061,23 @@ await TestAsync( Expression", GetScriptOptions(), TestOptions.ReleaseDll.WithMetadataReferenceResolver(resolver)); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542643")] - public async Task TestAssemblyAttribute(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542643")] + public async Task TestAssemblyAttribute(TestHost testHost) + { + await TestAsync( @"[assembly: [|InternalsVisibleTo|](""Project"")]", @"using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo(""Project"")]", testHost); - } + } - [Fact] - public async Task TestDoNotAddIntoHiddenRegion() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestDoNotAddIntoHiddenRegion() + { + await TestMissingInRegularAndScriptAsync( @"#line hidden using System.Collections.Generic; #line default @@ -2090,12 +2089,12 @@ void Main() [|DateTime|] d; } }"); - } + } - [Theory, CombinatorialData] - public async Task TestAddToVisibleRegion(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddToVisibleRegion(TestHost testHost) + { + await TestAsync( @"#line default using System.Collections.Generic; @@ -2125,12 +2124,12 @@ void Main() } } #line default", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545248")] - public async Task TestVenusGeneration1() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545248")] + public async Task TestVenusGeneration1() + { + await TestMissingInRegularAndScriptAsync( @"class C { void Goo() @@ -2142,32 +2141,32 @@ void Goo() #line hidden } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545774")] - public async Task TestAttribute_ActionCount() - { - var input = @"[ assembly : [|Guid|] ( ""9ed54f84-a89d-4fcd-a854-44251e925f09"" ) ] "; - await TestActionCountAsync(input, 2); - } + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545774")] + public async Task TestAttribute_ActionCount() + { + var input = @"[ assembly : [|Guid|] ( ""9ed54f84-a89d-4fcd-a854-44251e925f09"" ) ] "; + await TestActionCountAsync(input, 2); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545774")] - public async Task TestAttribute(TestHost testHost) - { - var input = @"[ assembly : [|Guid|] ( ""9ed54f84-a89d-4fcd-a854-44251e925f09"" ) ] "; + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545774")] + public async Task TestAttribute(TestHost testHost) + { + var input = @"[ assembly : [|Guid|] ( ""9ed54f84-a89d-4fcd-a854-44251e925f09"" ) ] "; - await TestAsync( + await TestAsync( input, @"using System.Runtime.InteropServices; [assembly : Guid ( ""9ed54f84-a89d-4fcd-a854-44251e925f09"" ) ] ", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546833")] - public async Task TestNotOnOverloadResolutionError() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546833")] + public async Task TestNotOnOverloadResolutionError() + { + await TestMissingInRegularAndScriptAsync( @"namespace ConsoleApplication1 { class Program @@ -2182,13 +2181,13 @@ class Test { } }"); - } + } - [Theory, CombinatorialData] - [WorkItem(17020, "DevDiv_Projects/Roslyn")] - public async Task TestAddUsingForGenericArgument(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem(17020, "DevDiv_Projects/Roslyn")] + public async Task TestAddUsingForGenericArgument(TestHost testHost) + { + await TestAsync( @"namespace ConsoleApplication10 { class Program @@ -2225,14 +2224,14 @@ public InArgument(T constValue) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/775448")] - public async Task ShouldTriggerOnCS0308(TestHost testHost) - { - // CS0308: The non-generic type 'A' cannot be used with type arguments - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/775448")] + public async Task ShouldTriggerOnCS0308(TestHost testHost) + { + // CS0308: The non-generic type 'A' cannot be used with type arguments + await TestAsync( @"using System.Collections; class Test @@ -2252,13 +2251,13 @@ static void Main(string[] args) IEnumerable f; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/838253")] - public async Task TestConflictedInaccessibleType(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/838253")] + public async Task TestConflictedInaccessibleType(TestHost testHost) + { + await TestAsync( @"using System.Diagnostics; namespace N @@ -2291,13 +2290,13 @@ static void Main(string[] args) Log } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/858085")] - public async Task TestConflictedAttributeName(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/858085")] + public async Task TestConflictedAttributeName(TestHost testHost) + { + await TestAsync( @"[[|Description|]] class Description { @@ -2308,13 +2307,13 @@ class Description class Description { }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/872908")] - public async Task TestConflictedGenericName(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/872908")] + public async Task TestConflictedGenericName(TestHost testHost) + { + await TestAsync( @"using Task = System.AccessViolationException; class X @@ -2328,12 +2327,12 @@ class X { Task x; }", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/913300")] - public async Task TestNoDuplicateReport_ActionCount() - { - await TestActionCountInAllFixesAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/913300")] + public async Task TestNoDuplicateReport_ActionCount() + { + await TestActionCountInAllFixesAsync( @"class C { void M(P p) @@ -2345,13 +2344,13 @@ static void Main(string[] args) { } }", count: 1); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/913300")] - public async Task TestNoDuplicateReport(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/913300")] + public async Task TestNoDuplicateReport(TestHost testHost) + { + await TestAsync( @"class C { void M(P p) @@ -2374,12 +2373,12 @@ static void Main(string[] args) { } }", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/938296")] - public async Task TestNullParentInNode() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/938296")] + public async Task TestNullParentInNode() + { + await TestMissingInRegularAndScriptAsync( @"using System.Collections.Generic; class MultiDictionary : Dictionary> @@ -2389,22 +2388,22 @@ void M() new HashSet([|Comparer|]); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/968303")] - public async Task TestMalformedUsingSection() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/968303")] + public async Task TestMalformedUsingSection() + { + await TestMissingInRegularAndScriptAsync( @"[ class Class { [|List<|] }"); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] - public async Task TestAddUsingsWithExternAlias(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] + public async Task TestAddUsingsWithExternAlias(TestHost testHost) + { + const string InitialWorkspace = @" @@ -2433,7 +2432,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @"extern alias P; + const string ExpectedDocumentText = @"extern alias P; using P::ProjectLib; @@ -2448,14 +2447,14 @@ static void Main(string[] args) } } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] - public async Task TestAddUsingsWithPreExistingExternAlias(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] + public async Task TestAddUsingsWithPreExistingExternAlias(TestHost testHost) + { + const string InitialWorkspace = @" @@ -2494,7 +2493,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @" + const string ExpectedDocumentText = @" extern alias P; using P::AnotherNS; @@ -2511,14 +2510,14 @@ static void Main(string[] args) } } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] - public async Task TestAddUsingsWithPreExistingExternAlias_FileScopedNamespace(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] + public async Task TestAddUsingsWithPreExistingExternAlias_FileScopedNamespace(TestHost testHost) + { + const string InitialWorkspace = @" @@ -2556,7 +2555,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @" + const string ExpectedDocumentText = @" extern alias P; using P::AnotherNS; @@ -2572,14 +2571,14 @@ static void Main(string[] args) } } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] - public async Task TestAddUsingsNoExtern(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] + public async Task TestAddUsingsNoExtern(TestHost testHost) + { + const string InitialWorkspace = @" @@ -2609,7 +2608,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @"extern alias P; + const string ExpectedDocumentText = @"extern alias P; using P::AnotherNS; namespace ExternAliases @@ -2623,14 +2622,14 @@ static void Main(string[] args) } } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] - public async Task TestAddUsingsNoExtern_FileScopedNamespace(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] + public async Task TestAddUsingsNoExtern_FileScopedNamespace(TestHost testHost) + { + const string InitialWorkspace = @" @@ -2658,7 +2657,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @"extern alias P; + const string ExpectedDocumentText = @"extern alias P; using P::AnotherNS; namespace ExternAliases; @@ -2671,14 +2670,14 @@ static void Main(string[] args) } } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] - public async Task TestAddUsingsNoExternFilterGlobalAlias(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/875899")] + public async Task TestAddUsingsNoExternFilterGlobalAlias(TestHost testHost) + { + await TestAsync( @"class Program { static void Main(string[] args) @@ -2695,18 +2694,18 @@ static void Main(string[] args) INotifyPropertyChanged.PropertyChanged } }", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] - public async Task TestAddUsingForCref() - { - var initialText = + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] + public async Task TestAddUsingForCref() + { + var initialText = @"/// /// This is just like , but this one is mine. /// interface MyNotifyPropertyChanged { }"; - var expectedText = + var expectedText = @"using System.ComponentModel; /// @@ -2714,21 +2713,21 @@ interface MyNotifyPropertyChanged { }"; /// interface MyNotifyPropertyChanged { }"; - var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); + var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); - await TestAsync(initialText, expectedText, parseOptions: options); - } + await TestAsync(initialText, expectedText, parseOptions: options); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] - public async Task TestAddUsingForCref2() - { - var initialText = + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] + public async Task TestAddUsingForCref2() + { + var initialText = @"/// /// This is just like , but this one is mine. /// interface MyNotifyPropertyChanged { }"; - var expectedText = + var expectedText = @"using System.ComponentModel; /// @@ -2736,15 +2735,15 @@ interface MyNotifyPropertyChanged { }"; /// interface MyNotifyPropertyChanged { }"; - var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); + var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); - await TestAsync(initialText, expectedText, parseOptions: options); - } + await TestAsync(initialText, expectedText, parseOptions: options); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] - public async Task TestAddUsingForCref3() - { - var initialText = + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] + public async Task TestAddUsingForCref3() + { + var initialText = @"namespace N1 { public class D { } @@ -2763,7 +2762,7 @@ public class MyClass2 { }"; - var expectedText = + var expectedText = @"using N1; namespace N1 @@ -2784,15 +2783,15 @@ public class MyClass2 { }"; - var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); + var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); - await TestAsync(initialText, expectedText, parseOptions: options); - } + await TestAsync(initialText, expectedText, parseOptions: options); + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] - public async Task TestAddUsingForCref4() - { - var initialText = + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/916368")] + public async Task TestAddUsingForCref4() + { + var initialText = @"namespace N1 { public class D { } @@ -2806,7 +2805,7 @@ public void Test(N1.D i) } }"; - var expectedText = + var expectedText = @"using N1; namespace N1 @@ -2822,16 +2821,16 @@ public void Test(N1.D i) } }"; - var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); + var options = new CSharpParseOptions(documentationMode: DocumentationMode.Diagnose); - await TestAsync(initialText, expectedText, parseOptions: options); - } + await TestAsync(initialText, expectedText, parseOptions: options); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] - public async Task TestAddStaticType(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] + public async Task TestAddStaticType(TestHost testHost) + { + var initialText = @"using System; public static class Outer @@ -2847,7 +2846,7 @@ public class MyAttribute : Attribute class Test {}"; - var expectedText = + var expectedText = @"using System; using static Outer; @@ -2864,14 +2863,14 @@ public class MyAttribute : Attribute class Test {}"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] - public async Task TestAddStaticType2(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] + public async Task TestAddStaticType2(TestHost testHost) + { + var initialText = @"using System; public static class Outer @@ -2889,7 +2888,7 @@ public class MyAttribute : Attribute class Test {}"; - var expectedText = + var expectedText = @"using System; using static Outer.Inner; @@ -2908,14 +2907,14 @@ public class MyAttribute : Attribute class Test {}"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] - public async Task TestAddStaticType3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] + public async Task TestAddStaticType3(TestHost testHost) + { + await TestAsync( @"using System; public static class Outer @@ -2951,13 +2950,13 @@ public class MyAttribute : Attribute class Test { }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] - public async Task TestAddStaticType4(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/773614")] + public async Task TestAddStaticType4(TestHost testHost) + { + var initialText = @"using System; using Outer; @@ -2976,7 +2975,7 @@ public class MyAttribute : Attribute class Test {}"; - var expectedText = + var expectedText = @"using System; using Outer; using static Outer.Inner; @@ -2996,14 +2995,14 @@ public class MyAttribute : Attribute class Test {}"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] - public async Task TestAddInsideUsingDirective1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] + public async Task TestAddInsideUsingDirective1(TestHost testHost) + { + await TestAsync( @"namespace ns { using B = [|Byte|]; @@ -3014,13 +3013,13 @@ namespace ns { using B = Byte; }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] - public async Task TestAddInsideUsingDirective2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] + public async Task TestAddInsideUsingDirective2(TestHost testHost) + { + await TestAsync( @"using System.Collections; namespace ns @@ -3034,13 +3033,13 @@ namespace ns { using B = Byte; }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] - public async Task TestAddInsideUsingDirective3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] + public async Task TestAddInsideUsingDirective3(TestHost testHost) + { + await TestAsync( @"namespace ns2 { namespace ns3 @@ -3071,13 +3070,13 @@ namespace ns4 } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] - public async Task TestAddInsideUsingDirective4(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] + public async Task TestAddInsideUsingDirective4(TestHost testHost) + { + await TestAsync( @"namespace ns2 { using System.Collections; @@ -3105,13 +3104,13 @@ namespace ns } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] - public async Task TestAddInsideUsingDirective5(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] + public async Task TestAddInsideUsingDirective5(TestHost testHost) + { + await TestAsync( @"using System.IO; namespace ns2 @@ -3145,20 +3144,20 @@ namespace ns } } }", testHost); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] - public async Task TestAddInsideUsingDirective6() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/991463")] + public async Task TestAddInsideUsingDirective6() + { + await TestMissingInRegularAndScriptAsync( @"using B = [|Byte|];"); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1064748")] - public async Task TestAddConditionalAccessExpression(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1064748")] + public async Task TestAddConditionalAccessExpression(TestHost testHost) + { + var initialText = @" @@ -3182,7 +3181,7 @@ public static class E "; - var expectedText = + var expectedText = @" using Extensions; @@ -3194,14 +3193,14 @@ void Main(C a) } } "; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1064748")] - public async Task TestAddConditionalAccessExpression2(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1064748")] + public async Task TestAddConditionalAccessExpression2(TestHost testHost) + { + var initialText = @" @@ -3231,7 +3230,7 @@ public static class D "; - var expectedText = + var expectedText = @" using Extensions; @@ -3249,14 +3248,14 @@ public class E } } "; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089138")] - public async Task TestAmbiguousUsingName(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1089138")] + public async Task TestAmbiguousUsingName(TestHost testHost) + { + await TestAsync( @"namespace ClassLibrary1 { using System; @@ -3312,12 +3311,12 @@ class SomeOtherFile { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingInDirective(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingInDirective(TestHost testHost) + { + await TestAsync( @"#define DEBUG #if DEBUG using System; @@ -3349,12 +3348,12 @@ static void Main(string[] args) var a = File.OpenRead(""""); } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingInDirective2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingInDirective2(TestHost testHost) + { + await TestAsync( @"#define DEBUG using System; using System.Collections.Generic; @@ -3375,12 +3374,12 @@ class Program { static void Main ( string [ ] args ) { var a = [|File|] . OpenRe using System.Text; #endif class Program { static void Main ( string [ ] args ) { var a = File . OpenRead ( """" ) ; } } ", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingInDirective3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingInDirective3(TestHost testHost) + { + await TestAsync( @"#define DEBUG using System; using System.Collections.Generic; @@ -3400,12 +3399,12 @@ class Program { static void Main ( string [ ] args ) { var a = [|File|] . OpenRe using System.Threading.Tasks; using System.IO; class Program { static void Main ( string [ ] args ) { var a = File . OpenRead ( """" ) ; } } ", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingInDirective4(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingInDirective4(TestHost testHost) + { + await TestAsync( @"#define DEBUG #if DEBUG using System; @@ -3425,12 +3424,12 @@ class Program { static void Main ( string [ ] args ) { var a = [|File|] . OpenRe using System.Threading.Tasks; using System.IO; class Program { static void Main ( string [ ] args ) { var a = File . OpenRead ( """" ) ; } } ", testHost); - } + } - [Fact] - public async Task TestInaccessibleExtensionMethod() - { - const string initial = @" + [Fact] + public async Task TestInaccessibleExtensionMethod() + { + const string initial = @" namespace N1 { public static class C @@ -3452,14 +3451,14 @@ static void Main(string[] args) } } }"; - await TestMissingInRegularAndScriptAsync(initial); - } + await TestMissingInRegularAndScriptAsync(initial); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1116011")] - public async Task TestAddUsingForProperty(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1116011")] + public async Task TestAddUsingForProperty(TestHost testHost) + { + await TestAsync( @"using System; using System.Collections.Generic; using System.Linq; @@ -3491,13 +3490,13 @@ public BindingFlags BindingFlags } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1116011")] - public async Task TestAddUsingForField(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1116011")] + public async Task TestAddUsingForField(TestHost testHost) + { + await TestAsync( @"using System; using System.Collections.Generic; using System.Linq; @@ -3545,14 +3544,14 @@ public class B public static readonly B Instance; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/1893")] - public async Task TestNameSimplification(TestHost testHost) - { - // Generated using directive must be simplified from "using A.B;" to "using B;" below. - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/1893")] + public async Task TestNameSimplification(TestHost testHost) + { + // Generated using directive must be simplified from "using A.B;" to "using B;" below. + await TestAsync( @"namespace A.B { class T1 @@ -3594,13 +3593,13 @@ void Test() } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/935")] - public async Task TestAddUsingWithOtherExtensionsInScope(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/935")] + public async Task TestAddUsingWithOtherExtensionsInScope(TestHost testHost) + { + await TestAsync( @"using System.Linq; using System.Collections; using X; @@ -3666,13 +3665,13 @@ static void Main() b.ExtMethod(0); } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/935")] - public async Task TestAddUsingWithOtherExtensionsInScope2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/935")] + public async Task TestAddUsingWithOtherExtensionsInScope2(TestHost testHost) + { + await TestAsync( @"using System.Linq; using System.Collections; using X; @@ -3738,13 +3737,13 @@ static void Main() b?.ExtMethod(0); } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/562")] - public async Task TestAddUsingWithOtherExtensionsInScope3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/562")] + public async Task TestAddUsingWithOtherExtensionsInScope3(TestHost testHost) + { + await TestAsync( @"using System.Linq; class C @@ -3774,13 +3773,13 @@ static class E public static int All(this int o) => 0; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/562")] - public async Task TestAddUsingWithOtherExtensionsInScope4(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/562")] + public async Task TestAddUsingWithOtherExtensionsInScope4(TestHost testHost) + { + await TestAsync( @"using System.Linq; class C @@ -3818,13 +3817,13 @@ static class E public static int? All(this int? o) => 0; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] - public async Task TestNestedNamespaceSimplified(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] + public async Task TestNestedNamespaceSimplified(TestHost testHost) + { + await TestAsync( @"namespace Microsoft.MyApp { using Win32; @@ -3850,13 +3849,13 @@ static void Main(string[] args) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] - public async Task TestNestedNamespaceSimplified2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] + public async Task TestNestedNamespaceSimplified2(TestHost testHost) + { + await TestAsync( @"namespace Microsoft.MyApp { using Zin32; @@ -3882,13 +3881,13 @@ static void Main(string[] args) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] - public async Task TestNestedNamespaceSimplified3(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] + public async Task TestNestedNamespaceSimplified3(TestHost testHost) + { + await TestAsync( @"namespace Microsoft.MyApp { using System; @@ -3916,13 +3915,13 @@ static void Main(string[] args) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] - public async Task TestNestedNamespaceSimplified4(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] + public async Task TestNestedNamespaceSimplified4(TestHost testHost) + { + await TestAsync( @"namespace Microsoft.MyApp { using System; @@ -3950,13 +3949,13 @@ static void Main(string[] args) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] - public async Task TestNestedNamespaceSimplified5(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] + public async Task TestNestedNamespaceSimplified5(TestHost testHost) + { + await TestAsync( @"namespace Microsoft.MyApp { #if true @@ -3988,13 +3987,13 @@ static void Main(string[] args) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] - public async Task TestNestedNamespaceSimplified6(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/3080")] + public async Task TestNestedNamespaceSimplified6(TestHost testHost) + { + await TestAsync( @"namespace Microsoft.MyApp { using System; @@ -4028,12 +4027,12 @@ static void Main(string[] args) } } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingOrdinalUppercase(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingOrdinalUppercase(TestHost testHost) + { + await TestAsync( @"namespace A { class A @@ -4084,12 +4083,12 @@ class B { } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingOrdinalLowercase(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingOrdinalLowercase(TestHost testHost) + { + await TestAsync( @"namespace A { class A @@ -4140,13 +4139,13 @@ class B { } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/7443")] - public async Task TestWithExistingIncompatibleExtension(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/7443")] + public async Task TestWithExistingIncompatibleExtension(TestHost testHost) + { + await TestAsync( @"using N; class C @@ -4188,13 +4187,13 @@ public static void Any(this string s) } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem(1744, @"https://github.com/dotnet/roslyn/issues/1744")] - public async Task TestIncompleteCatchBlockInLambda(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem(1744, @"https://github.com/dotnet/roslyn/issues/1744")] + public async Task TestIncompleteCatchBlockInLambda(TestHost testHost) + { + await TestAsync( @"class A { System.Action a = () => { @@ -4211,13 +4210,13 @@ class A { } catch (Exception", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] - public async Task TestAddInsideLambda(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] + public async Task TestAddInsideLambda(TestHost testHost) + { + var initialText = @"using System; static void Main(string[] args) @@ -4225,7 +4224,7 @@ static void Main(string[] args) Func f = () => { [|List|]. } }"; - var expectedText = + var expectedText = @"using System; using System.Collections.Generic; @@ -4233,14 +4232,14 @@ static void Main(string[] args) { Func f = () => { List. } }"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] - public async Task TestAddInsideLambda2(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] + public async Task TestAddInsideLambda2(TestHost testHost) + { + var initialText = @"using System; static void Main(string[] args) @@ -4248,7 +4247,7 @@ static void Main(string[] args) Func f = () => { [|List|] } }"; - var expectedText = + var expectedText = @"using System; using System.Collections.Generic; @@ -4256,14 +4255,14 @@ static void Main(string[] args) { Func f = () => { List } }"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] - public async Task TestAddInsideLambda3(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] + public async Task TestAddInsideLambda3(TestHost testHost) + { + var initialText = @"using System; static void Main(string[] args) @@ -4275,7 +4274,7 @@ static void Main(string[] args) }; }"; - var expectedText = + var expectedText = @"using System; using System.Collections.Generic; @@ -4287,14 +4286,14 @@ static void Main(string[] args) return a; }; }"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] - public async Task TestAddInsideLambda4(TestHost testHost) - { - var initialText = + [Theory, CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1033612")] + public async Task TestAddInsideLambda4(TestHost testHost) + { + var initialText = @"using System; static void Main(string[] args) @@ -4306,7 +4305,7 @@ static void Main(string[] args) }; }"; - var expectedText = + var expectedText = @"using System; using System.Collections.Generic; @@ -4318,15 +4317,15 @@ static void Main(string[] args) return a; }; }"; - await TestAsync(initialText, expectedText, testHost); - } + await TestAsync(initialText, expectedText, testHost); + } - [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/860648")] - [CombinatorialData] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/902014")] - public async Task TestIncompleteParenthesizedLambdaExpression(TestHost testHost) - { - await TestAsync( + [Theory, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/860648")] + [CombinatorialData] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/902014")] + public async Task TestIncompleteParenthesizedLambdaExpression(TestHost testHost) + { + await TestAsync( @"using System; class Test @@ -4350,13 +4349,13 @@ void Goo() string a; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/7461")] - public async Task TestExtensionWithIncompatibleInstance(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/7461")] + public async Task TestExtensionWithIncompatibleInstance(TestHost testHost) + { + await TestAsync( @"using System.IO; namespace Namespace1 @@ -4404,13 +4403,13 @@ void Bar() } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/5499")] - public async Task TestFormattingForNamespaceUsings(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/5499")] + public async Task TestFormattingForNamespaceUsings(TestHost testHost) + { + await TestAsync( @"namespace N { using System; @@ -4442,12 +4441,12 @@ void Main() } } }", testHost); - } + } - [Fact] - public async Task TestGenericAmbiguityInSameNamespace() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestGenericAmbiguityInSameNamespace() + { + await TestMissingInRegularAndScriptAsync( @"namespace NS { class C where T : [|C|].N @@ -4457,12 +4456,12 @@ public class N } } }"); - } + } - [Fact] - public async Task TestNotOnVar1() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestNotOnVar1() + { + await TestMissingInRegularAndScriptAsync( @"namespace N { class var { } @@ -4476,12 +4475,12 @@ void M() } } "); - } + } - [Fact] - public async Task TestNotOnVar2() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestNotOnVar2() + { + await TestMissingInRegularAndScriptAsync( @"namespace N { class Bar { } @@ -4495,13 +4494,13 @@ void M() } } "); - } + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=226826")] - public async Task TestAddUsingWithLeadingDocCommentInFrontOfUsing1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=226826")] + public async Task TestAddUsingWithLeadingDocCommentInFrontOfUsing1(TestHost testHost) + { + await TestAsync( @" /// Copyright 2016 - MyCompany /// All Rights Reserved @@ -4523,13 +4522,13 @@ class C : IEnumerable { } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=226826")] - public async Task TestAddUsingWithLeadingDocCommentInFrontOfUsing2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=226826")] + public async Task TestAddUsingWithLeadingDocCommentInFrontOfUsing2(TestHost testHost) + { + await TestAsync( @" /// Copyright 2016 - MyCompany /// All Rights Reserved @@ -4553,13 +4552,13 @@ class C DateTime d; } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=226826")] - public async Task TestAddUsingWithLeadingDocCommentInFrontOfClass1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems?id=226826")] + public async Task TestAddUsingWithLeadingDocCommentInFrontOfClass1(TestHost testHost) + { + await TestAsync( @" /// Copyright 2016 - MyCompany /// All Rights Reserved @@ -4578,12 +4577,12 @@ class C DateTime d; } ", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestPlaceUsingWithUsings_NotWithAliases(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestPlaceUsingWithUsings_NotWithAliases(TestHost testHost) + { + await TestAsync( @" using System; @@ -4615,13 +4614,13 @@ List Method() } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/15025")] - public async Task TestPreferSystemNamespaceFirst(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/15025")] + public async Task TestPreferSystemNamespaceFirst(TestHost testHost) + { + await TestAsync( @" namespace Microsoft { @@ -4660,13 +4659,13 @@ class Class SomeClass c; } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/15025")] - public async Task TestPreferSystemNamespaceFirst2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/15025")] + public async Task TestPreferSystemNamespaceFirst2(TestHost testHost) + { + await TestAsync( @" namespace Microsoft { @@ -4705,12 +4704,12 @@ class Class SomeClass c; } }", testHost, index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18275")] - public async Task TestContextualKeyword1() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18275")] + public async Task TestContextualKeyword1() + { + await TestMissingInRegularAndScriptAsync( @" namespace N { @@ -4726,13 +4725,13 @@ void M() [|nameof|] } }"); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/19218")] - public async Task TestChangeCaseWithUsingsInNestedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/19218")] + public async Task TestChangeCaseWithUsingsInNestedNamespace(TestHost testHost) + { + await TestAsync( @"namespace VS { interface IVsStatusbar @@ -4776,12 +4775,12 @@ void M() } } ", testHost); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19575")] - public async Task TestNoNonGenericsWithGenericCodeParsedAsExpression() - { - var code = @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19575")] + public async Task TestNoNonGenericsWithGenericCodeParsedAsExpression() + { + var code = @" class C { private void GetEvaluationRuleNames() @@ -4790,9 +4789,9 @@ private void GetEvaluationRuleNames() return ImmutableArray.CreateRange(); } }"; - await TestActionCountAsync(code, count: 1); + await TestActionCountAsync(code, count: 1); - await TestInRegularAndScriptAsync( + await TestInRegularAndScriptAsync( code, @" using System.Collections.Generic; @@ -4805,15 +4804,15 @@ private void GetEvaluationRuleNames() return ImmutableArray.CreateRange(); } }"); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/19796")] - public async Task TestWhenInRome1(TestHost testHost) - { - // System is set to be sorted first, but the actual file shows it at the end. - // Keep things sorted, but respect that 'System' is at the end. - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/19796")] + public async Task TestWhenInRome1(TestHost testHost) + { + // System is set to be sorted first, but the actual file shows it at the end. + // Keep things sorted, but respect that 'System' is at the end. + await TestAsync( @" using B; using System; @@ -4858,15 +4857,15 @@ public static void Bar() } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/19796")] - public async Task TestWhenInRome2(TestHost testHost) - { - // System is set to not be sorted first, but the actual file shows it sorted first. - // Keep things sorted, but respect that 'System' is at the beginning. - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/19796")] + public async Task TestWhenInRome2(TestHost testHost) + { + // System is set to not be sorted first, but the actual file shows it sorted first. + // Keep things sorted, but respect that 'System' is at the beginning. + await TestAsync( @" using System; using B; @@ -4910,12 +4909,12 @@ public static void Bar() } } }", testHost); - } + } - [Fact] - public async Task TestExactMatchNoGlyph() - { - await TestSmartTagGlyphTagsAsync( + [Fact] + public async Task TestExactMatchNoGlyph() + { + await TestSmartTagGlyphTagsAsync( @"namespace VS { interface Other @@ -4931,12 +4930,12 @@ void M() } } ", ImmutableArray.Empty); - } + } - [Fact] - public async Task TestFuzzyMatchGlyph() - { - await TestSmartTagGlyphTagsAsync( + [Fact] + public async Task TestFuzzyMatchGlyph() + { + await TestSmartTagGlyphTagsAsync( @"namespace VS { interface Other @@ -4952,13 +4951,13 @@ void M() } } ", WellKnownTagArrays.Namespace); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/29313")] - public async Task TestGetAwaiterExtensionMethod1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/29313")] + public async Task TestGetAwaiterExtensionMethod1(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -5032,13 +5031,13 @@ public void OnCompleted(Action continuation) { } } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/29313")] - public async Task TestGetAwaiterExtensionMethod2(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/29313")] + public async Task TestGetAwaiterExtensionMethod2(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -5112,13 +5111,13 @@ public void OnCompleted(Action continuation) { } } } }", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/745490")] - public async Task TestAddUsingForAwaitableReturningExtensionMethod(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/745490")] + public async Task TestAddUsingForAwaitableReturningExtensionMethod(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -5170,12 +5169,12 @@ static class Extensions public static Task Foo(this C instance) => null; } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingForExtensionGetEnumeratorReturningIEnumerator(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingForExtensionGetEnumeratorReturningIEnumerator(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -5220,12 +5219,12 @@ static class Extensions public static IEnumerator GetEnumerator(this C instance) => null; } }", testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingForExtensionGetEnumeratorReturningPatternEnumerator(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingForExtensionGetEnumeratorReturningPatternEnumerator(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -5280,12 +5279,12 @@ public class Enumerator public bool MoveNext(); } }", testHost); - } + } - [Fact] - public async Task TestMissingForExtensionInvalidGetEnumerator() - { - await TestMissingAsync( + [Fact] + public async Task TestMissingForExtensionInvalidGetEnumerator() + { + await TestMissingAsync( @" namespace A { @@ -5306,12 +5305,12 @@ static class Extensions public static bool GetEnumerator(this C instance) => null; } }"); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingForExtensionGetEnumeratorReturningPatternEnumeratorWrongAsync(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingForExtensionGetEnumeratorReturningPatternEnumeratorWrongAsync(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -5386,12 +5385,12 @@ public class Enumerator public bool MoveNext(); } }", testHost); - } + } - [Fact] - public async Task TestMissingForExtensionGetAsyncEnumeratorOnForeach() - { - await TestMissingAsync( + [Fact] + public async Task TestMissingForExtensionGetAsyncEnumeratorOnForeach() + { + await TestMissingAsync( @" namespace A { @@ -5413,12 +5412,12 @@ static class Extensions public static IAsyncEnumerator GetAsyncEnumerator(this C instance) => null; } }" + IAsyncEnumerable); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingForExtensionGetAsyncEnumeratorReturningIAsyncEnumerator(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingForExtensionGetAsyncEnumeratorReturningIAsyncEnumerator(TestHost testHost) + { + await TestAsync( @" using System.Threading.Tasks; namespace A @@ -5464,12 +5463,12 @@ static class Extensions public static IAsyncEnumerator GetAsyncEnumerator(this C instance) => null; } }" + IAsyncEnumerable, testHost); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingForExtensionGetAsyncEnumeratorReturningPatternEnumerator(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingForExtensionGetAsyncEnumeratorReturningPatternEnumerator(TestHost testHost) + { + await TestAsync( @" using System.Threading.Tasks; namespace A @@ -5525,12 +5524,12 @@ public class Enumerator public Task MoveNextAsync(); } }", testHost); - } + } - [Fact] - public async Task TestMissingForExtensionInvalidGetAsyncEnumerator() - { - await TestMissingAsync( + [Fact] + public async Task TestMissingForExtensionInvalidGetAsyncEnumerator() + { + await TestMissingAsync( @" using System.Threading.Tasks; @@ -5553,12 +5552,12 @@ static class Extensions public static bool GetAsyncEnumerator(this C instance) => null; } }"); - } + } - [Theory, CombinatorialData] - public async Task TestAddUsingForExtensionGetAsyncEnumeratorReturningPatternEnumeratorWrongAsync(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + public async Task TestAddUsingForExtensionGetAsyncEnumeratorReturningPatternEnumeratorWrongAsync(TestHost testHost) + { + await TestAsync( @" using System.Threading.Tasks; namespace A @@ -5636,12 +5635,12 @@ public sealed class Enumerator public int Current => throw null; } }", testHost); - } + } - [Fact] - public async Task TestMissingForExtensionGetEnumeratorOnAsyncForeach() - { - await TestMissingAsync( + [Fact] + public async Task TestMissingForExtensionGetEnumeratorOnAsyncForeach() + { + await TestMissingAsync( @" using System.Threading.Tasks; @@ -5665,13 +5664,13 @@ static class Extensions public static IEnumerator GetEnumerator(this C instance) => null; } }"); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithStaticUsingInNamespace_WhenNoExistingUsings(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithStaticUsingInNamespace_WhenNoExistingUsings(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5695,13 +5694,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithStaticUsingInInnerNestedNamespace_WhenNoExistingUsings(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithStaticUsingInInnerNestedNamespace_WhenNoExistingUsings(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5731,13 +5730,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithStaticUsingInOuterNestedNamespace_WhenNoExistingUsings(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithStaticUsingInOuterNestedNamespace_WhenNoExistingUsings(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5767,13 +5766,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithExistingUsingInCompilationUnit_WhenStaticUsingInNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithExistingUsingInCompilationUnit_WhenStaticUsingInNamespace(TestHost testHost) + { + await TestAsync( @" using System; @@ -5801,13 +5800,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithExistingUsing_WhenStaticUsingInInnerNestedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithExistingUsing_WhenStaticUsingInInnerNestedNamespace(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5841,13 +5840,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithExistingUsing_WhenStaticUsingInOuterNestedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithExistingUsing_WhenStaticUsingInOuterNestedNamespace(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5881,13 +5880,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithUsingAliasInNamespace_WhenNoExistingUsing(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithUsingAliasInNamespace_WhenNoExistingUsing(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5911,13 +5910,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithUsingAliasInInnerNestedNamespace_WhenNoExistingUsing(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithUsingAliasInInnerNestedNamespace_WhenNoExistingUsing(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5947,13 +5946,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithUsingAliasInOuterNestedNamespace_WhenNoExistingUsing(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithUsingAliasInOuterNestedNamespace_WhenNoExistingUsing(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -5983,13 +5982,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithExistingUsingInCompilationUnit_WhenUsingAliasInNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithExistingUsingInCompilationUnit_WhenUsingAliasInNamespace(TestHost testHost) + { + await TestAsync( @" using System; @@ -6017,13 +6016,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithExistingUsing_WhenUsingAliasInInnerNestedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithExistingUsing_WhenUsingAliasInInnerNestedNamespace(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -6057,13 +6056,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] - public async Task UsingPlacedWithExistingUsing_WhenUsingAliasInOuterNestedNamespace(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/30734")] + public async Task UsingPlacedWithExistingUsing_WhenUsingAliasInOuterNestedNamespace(TestHost testHost) + { + await TestAsync( @" namespace N { @@ -6097,13 +6096,13 @@ class C } } ", testHost); - } + } - [Theory, CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/25003")] - public async Task KeepUsingsGrouped1(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/25003")] + public async Task KeepUsingsGrouped1(TestHost testHost) + { + await TestAsync( @" using System; @@ -6139,12 +6138,12 @@ public class Goo { } }", testHost); - } + } - [Fact, WorkItem(1239, @"https://github.com/dotnet/roslyn/issues/1239")] - public async Task TestIncompleteLambda1() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem(1239, @"https://github.com/dotnet/roslyn/issues/1239")] + public async Task TestIncompleteLambda1() + { + await TestInRegularAndScriptAsync( @"using System.Linq; class C @@ -6162,12 +6161,12 @@ class C { """".Select(() => { new Byte"); - } + } - [Fact, WorkItem(1239, @"https://github.com/dotnet/roslyn/issues/1239")] - public async Task TestIncompleteLambda2() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem(1239, @"https://github.com/dotnet/roslyn/issues/1239")] + public async Task TestIncompleteLambda2() + { + await TestInRegularAndScriptAsync( @"using System.Linq; class C @@ -6185,13 +6184,13 @@ class C { """".Select(() => { new Byte() }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/902014")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/860648")] - public async Task TestIncompleteSimpleLambdaExpression() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/902014")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/860648")] + public async Task TestIncompleteSimpleLambdaExpression() + { + await TestInRegularAndScriptAsync( @"using System.Linq; class Program @@ -6213,13 +6212,13 @@ static void Main(string[] args) string a; } }"); - } + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] - public async Task TestAddUsingsEditorBrowsableNeverSameProject(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] + public async Task TestAddUsingsEditorBrowsableNeverSameProject(TestHost testHost) + { + const string InitialWorkspace = @" @@ -6244,7 +6243,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @" + const string ExpectedDocumentText = @" using ProjectLib; class Program @@ -6256,14 +6255,14 @@ static void Main(string[] args) } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] - public async Task TestAddUsingsEditorBrowsableNeverDifferentProject(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] + public async Task TestAddUsingsEditorBrowsableNeverDifferentProject(TestHost testHost) + { + const string InitialWorkspace = @" @@ -6288,14 +6287,14 @@ static void Main(string[] args) "; - await TestMissingAsync(InitialWorkspace, new TestParameters(testHost: testHost)); - } + await TestMissingAsync(InitialWorkspace, new TestParameters(testHost: testHost)); + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] - public async Task TestAddUsingsEditorBrowsableAdvancedDifferentProjectOptionOn(TestHost testHost) - { - const string InitialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] + public async Task TestAddUsingsEditorBrowsableAdvancedDifferentProjectOptionOn(TestHost testHost) + { + const string InitialWorkspace = @" @@ -6321,7 +6320,7 @@ static void Main(string[] args) "; - const string ExpectedDocumentText = @" + const string ExpectedDocumentText = @" using ProjectLib; class Program @@ -6332,14 +6331,14 @@ static void Main(string[] args) } } "; - await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); - } + await TestAsync(InitialWorkspace, ExpectedDocumentText, testHost); + } - [Theory, CombinatorialData] - [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] - public async Task TestAddUsingsEditorBrowsableAdvancedDifferentProjectOptionOff(TestHost testHost) - { - var initialWorkspace = @" + [Theory, CombinatorialData] + [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1266354")] + public async Task TestAddUsingsEditorBrowsableAdvancedDifferentProjectOptionOff(TestHost testHost) + { + var initialWorkspace = @" @@ -6365,217 +6364,211 @@ static void Main(string[] args) "; - await TestMissingAsync(initialWorkspace, new TestParameters( - globalOptions: Option(CompletionOptionsStorage.HideAdvancedMembers, true), - testHost: testHost)); - } + await TestMissingAsync(initialWorkspace, new TestParameters( + globalOptions: Option(CompletionOptionsStorage.HideAdvancedMembers, true), + testHost: testHost)); + } - /// - /// Note that this test verifies the current end of line sequence in using directives is preserved regardless of - /// whether this matches the end_of_line value in .editorconfig or not. - /// - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/62976")] - public async Task TestAddUsingPreservesNewlines1(TestHost testHost, [CombinatorialValues("\n", "\r\n")] string sourceNewLine, [CombinatorialValues("\n", "\r\n")] string configuredNewLine) - { - await TestInRegularAndScript1Async( - """ - namespace ANamespace - { - public class TheAType { } - } + /// + /// Note that this test verifies the current end of line sequence in using directives is preserved regardless of + /// whether this matches the end_of_line value in .editorconfig or not. + /// + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/62976")] + public async Task TestAddUsingPreservesNewlines1(TestHost testHost, [CombinatorialValues("\n", "\r\n")] string sourceNewLine, [CombinatorialValues("\n", "\r\n")] string configuredNewLine) + { + await TestInRegularAndScript1Async( + """ + namespace ANamespace + { + public class TheAType { } + } - namespace N + namespace N + { + class Class { - class Class - { - [|TheAType|] a; - } + [|TheAType|] a; } - """.ReplaceLineEndings(sourceNewLine), - """ - using ANamespace; + } + """.ReplaceLineEndings(sourceNewLine), + """ + using ANamespace; - namespace ANamespace - { - public class TheAType { } - } + namespace ANamespace + { + public class TheAType { } + } - namespace N + namespace N + { + class Class { - class Class - { - TheAType a; - } + TheAType a; } - """.ReplaceLineEndings(sourceNewLine), - index: 0, - parameters: new TestParameters(options: Option(FormattingOptions2.NewLine, configuredNewLine), testHost: testHost)); - } + } + """.ReplaceLineEndings(sourceNewLine), + index: 0, + parameters: new TestParameters(options: Option(FormattingOptions2.NewLine, configuredNewLine), testHost: testHost)); + } - /// - /// Note that this test verifies the current end of line sequence in using directives is preserved regardless of - /// whether this matches the end_of_line value in .editorconfig or not. - /// - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/62976")] - public async Task TestAddUsingPreservesNewlines2(TestHost testHost, [CombinatorialValues("\n", "\r\n")] string sourceNewLine, [CombinatorialValues("\n", "\r\n")] string configuredNewLine) - { - await TestInRegularAndScript1Async( - """ - using BNamespace; + /// + /// Note that this test verifies the current end of line sequence in using directives is preserved regardless of + /// whether this matches the end_of_line value in .editorconfig or not. + /// + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/62976")] + public async Task TestAddUsingPreservesNewlines2(TestHost testHost, [CombinatorialValues("\n", "\r\n")] string sourceNewLine, [CombinatorialValues("\n", "\r\n")] string configuredNewLine) + { + await TestInRegularAndScript1Async( + """ + using BNamespace; - namespace ANamespace - { - public class TheAType { } - } + namespace ANamespace + { + public class TheAType { } + } - namespace BNamespace - { - public class TheBType { } - } + namespace BNamespace + { + public class TheBType { } + } - namespace N + namespace N + { + class Class { - class Class - { - [|TheAType|] a; - TheBType b; - } + [|TheAType|] a; + TheBType b; } - """.ReplaceLineEndings(sourceNewLine), - """ - using ANamespace; - using BNamespace; + } + """.ReplaceLineEndings(sourceNewLine), + """ + using ANamespace; + using BNamespace; - namespace ANamespace - { - public class TheAType { } - } + namespace ANamespace + { + public class TheAType { } + } - namespace BNamespace - { - public class TheBType { } - } + namespace BNamespace + { + public class TheBType { } + } - namespace N + namespace N + { + class Class { - class Class - { - TheAType a; - TheBType b; - } + TheAType a; + TheBType b; } - """.ReplaceLineEndings(sourceNewLine), - index: 0, - parameters: new TestParameters(options: Option(FormattingOptions2.NewLine, configuredNewLine), testHost: testHost)); - } - - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/62976")] - public async Task TestAddUsingPreservesNewlines3(TestHost testHost, [CombinatorialValues("\n", "\r\n")] string sourceNewLine, [CombinatorialValues("\n", "\r\n")] string configuredNewLine) - { - await TestInRegularAndScript1Async( - """ - using ANamespace; + } + """.ReplaceLineEndings(sourceNewLine), + index: 0, + parameters: new TestParameters(options: Option(FormattingOptions2.NewLine, configuredNewLine), testHost: testHost)); + } - namespace ANamespace - { - public class TheAType { } - } + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/62976")] + public async Task TestAddUsingPreservesNewlines3(TestHost testHost, [CombinatorialValues("\n", "\r\n")] string sourceNewLine, [CombinatorialValues("\n", "\r\n")] string configuredNewLine) + { + await TestInRegularAndScript1Async( + """ + using ANamespace; - namespace BNamespace - { - public class TheBType { } - } + namespace ANamespace + { + public class TheAType { } + } - namespace N - { - class Class - { - TheAType a; - [|TheBType|] b; - } - } - """.ReplaceLineEndings(sourceNewLine), - """ - using ANamespace; - using BNamespace; + namespace BNamespace + { + public class TheBType { } + } - namespace ANamespace + namespace N + { + class Class { - public class TheAType { } + TheAType a; + [|TheBType|] b; } + } + """.ReplaceLineEndings(sourceNewLine), + """ + using ANamespace; + using BNamespace; - namespace BNamespace - { - public class TheBType { } - } + namespace ANamespace + { + public class TheAType { } + } - namespace N - { - class Class - { - TheAType a; - TheBType b; - } - } - """.ReplaceLineEndings(sourceNewLine), - index: 0, - parameters: new TestParameters(options: Option(FormattingOptions2.NewLine, configuredNewLine), testHost: testHost)); - } + namespace BNamespace + { + public class TheBType { } + } - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/24642")] - public async Task TestAddUsingWithMalformedGeneric(TestHost testHost) - { - await TestInRegularAndScript1Async( - """ + namespace N + { class Class { - [|List (new CSharpUnboundIdentifiersDiagnosticAnalyzer(), new CSharpAddImportCodeFixProvider()); + + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/829970")] + public async Task TestUnknownIdentifierGenericName() { - public AddUsingTestsWithAddImportDiagnosticProvider(ITestOutputHelper logger) - : base(logger) - { - } - - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (new CSharpUnboundIdentifiersDiagnosticAnalyzer(), new CSharpAddImportCodeFixProvider()); - - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/829970")] - public async Task TestUnknownIdentifierGenericName() - { - await TestInRegularAndScriptAsync( + await TestInRegularAndScriptAsync( @"class C { private [|List|] @@ -42,12 +42,12 @@ class C { private List }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/829970")] - public async Task TestUnknownIdentifierInAttributeSyntaxWithoutTarget() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/829970")] + public async Task TestUnknownIdentifierInAttributeSyntaxWithoutTarget() + { + await TestInRegularAndScriptAsync( @"class C { [[|Extension|]] @@ -58,22 +58,22 @@ class C { [Extension] }"); - } + } - [Fact] - public async Task TestOutsideOfMethodWithMalformedGenericParameters() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestOutsideOfMethodWithMalformedGenericParameters() + { + await TestMissingInRegularAndScriptAsync( @"using System; class Program { Func<[|FlowControl|] x }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/752640")] - public async Task TestUnknownIdentifierWithSyntaxError() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/752640")] + public async Task TestUnknownIdentifierWithSyntaxError() + { + await TestInRegularAndScriptAsync( @"class C { [|Directory|] private int i; @@ -84,12 +84,12 @@ class C { Directory private int i; }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/855748")] - public async Task TestGenericNameWithBrackets() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/855748")] + public async Task TestGenericNameWithBrackets() + { + await TestInRegularAndScriptAsync( @"class Class { [|List|] @@ -101,7 +101,7 @@ class Class List }"); - await TestInRegularAndScriptAsync( + await TestInRegularAndScriptAsync( @"class Class { [|List<>|] @@ -113,7 +113,7 @@ class Class List<> }"); - await TestInRegularAndScriptAsync( + await TestInRegularAndScriptAsync( @"class Class { List[|<>|] @@ -124,12 +124,12 @@ class Class { List<> }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/867496")] - public async Task TestMalformedGenericParameters() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/867496")] + public async Task TestMalformedGenericParameters() + { + await TestInRegularAndScriptAsync( @"class Class { [|List<|] }", @@ -139,16 +139,16 @@ class Class { List< }"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"class Class { [|List> } }"); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23667")] - public async Task TestMissingDiagnosticForNameOf() - { - await TestDiagnosticMissingAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23667")] + public async Task TestMissingDiagnosticForNameOf() + { + await TestDiagnosticMissingAsync( @"using System; class C @@ -201,6 +201,5 @@ class C #warning xxx }; }"); - } } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_ExtensionMethods.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_ExtensionMethods.cs index ce2ca8aeced1d..1a84b263ecfd2 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_ExtensionMethods.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_ExtensionMethods.cs @@ -6,18 +6,17 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Remote.Testing; -using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; + +public partial class AddUsingTests { - public partial class AddUsingTests + [Fact] + public async Task TestWhereExtension() { - [Fact] - public async Task TestWhereExtension() - { - await TestInRegularAndScriptAsync( + await TestInRegularAndScriptAsync( @"using System; using System.Collections.Generic; @@ -37,12 +36,12 @@ static void Main(string[] args) { var q = args.Where } }"); - } + } - [Fact] - public async Task TestSelectExtension() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestSelectExtension() + { + await TestInRegularAndScriptAsync( @"using System; using System.Collections.Generic; @@ -62,12 +61,12 @@ static void Main(string[] args) { var q = args.Select } }"); - } + } - [Fact] - public async Task TestGroupByExtension() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGroupByExtension() + { + await TestInRegularAndScriptAsync( @"using System; using System.Collections.Generic; @@ -87,12 +86,12 @@ static void Main(string[] args) { var q = args.GroupBy } }"); - } + } - [Fact] - public async Task TestJoinExtension() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestJoinExtension() + { + await TestInRegularAndScriptAsync( @"using System; using System.Collections.Generic; @@ -112,12 +111,12 @@ static void Main(string[] args) { var q = args.Join } }"); - } + } - [Fact] - public async Task RegressionFor8455() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task RegressionFor8455() + { + await TestMissingInRegularAndScriptAsync( @"class C { void M() @@ -125,12 +124,12 @@ void M() int dim = (int)Math.[|Min|](); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772321")] - public async Task TestExtensionWithThePresenceOfTheSameNameNonExtensionMethod() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772321")] + public async Task TestExtensionWithThePresenceOfTheSameNameNonExtensionMethod() + { + await TestInRegularAndScriptAsync( @"namespace NS1 { class Program @@ -187,13 +186,13 @@ public static void Goo(this NS1.C c, int x) } } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/920398")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772321")] - public async Task TestExtensionWithThePresenceOfTheSameNameNonExtensionPrivateMethod() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/920398")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772321")] + public async Task TestExtensionWithThePresenceOfTheSameNameNonExtensionPrivateMethod() + { + await TestInRegularAndScriptAsync( @"namespace NS1 { class Program @@ -250,13 +249,13 @@ public static void Goo(this NS1.C c, int x) } } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/920398")] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772321")] - public async Task TestExtensionWithThePresenceOfTheSameNameExtensionPrivateMethod() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/920398")] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/772321")] + public async Task TestExtensionWithThePresenceOfTheSameNameExtensionPrivateMethod() + { + await TestInRegularAndScriptAsync( @"using NS2; namespace NS1 @@ -330,12 +329,12 @@ public static void Goo(this NS1.C c, int x) } } }"); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod() + { + await TestAsync( @"using System; using System.Collections; @@ -380,12 +379,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod2() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod2() + { + await TestAsync( @"using System; using System.Collections; @@ -430,12 +429,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod3() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod3() + { + await TestAsync( @"using System; using System.Collections; @@ -480,12 +479,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod4() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod4() + { + await TestAsync( @"using System; using System.Collections; @@ -530,12 +529,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod5() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod5() + { + await TestAsync( @"using System; using System.Collections; @@ -580,12 +579,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod6() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod6() + { + await TestAsync( @"using System; using System.Collections; @@ -630,12 +629,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod7() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod7() + { + await TestAsync( @"using System; using System.Collections; @@ -680,12 +679,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod8() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod8() + { + await TestAsync( @"using System; using System.Collections; @@ -730,12 +729,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod9() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod9() + { + await TestAsync( @"using System; using System.Collections; @@ -780,12 +779,12 @@ public static void Add(this X x, int i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod10() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod10() + { + await TestAsync( @"using System; using System.Collections; @@ -850,12 +849,12 @@ public static void Add(this X x, object[] i) } }", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] - public async Task TestAddUsingForAddExtensionMethod11() - { - await TestAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/269")] + public async Task TestAddUsingForAddExtensionMethod11() + { + await TestAsync( @"using System; using System.Collections; @@ -921,12 +920,12 @@ public static void Add(this X x, object[] i) }", index: 1, parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3818")] - public async Task InExtensionMethodUnderConditionalAccessExpression() - { - var initialText = + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3818")] + public async Task InExtensionMethodUnderConditionalAccessExpression() + { + var initialText = @" @@ -957,7 +956,7 @@ public static string StringExtension(this string s) "; - var expectedText = + var expectedText = @" using Sample.Extensions; @@ -973,14 +972,14 @@ static void Main(string[] args) } } "; - await TestInRegularAndScriptAsync(initialText, expectedText); - } + await TestInRegularAndScriptAsync(initialText, expectedText); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3818")] - public async Task InExtensionMethodUnderMultipleConditionalAccessExpressions() - { - var initialText = - @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3818")] + public async Task InExtensionMethodUnderMultipleConditionalAccessExpressions() + { + var initialText = +@" public class C @@ -1006,7 +1005,7 @@ public static C Extn(this C obj) "; - var expectedText = + var expectedText = @" using Sample.Extensions; @@ -1018,14 +1017,14 @@ public T F(T x) } } "; - await TestInRegularAndScriptAsync(initialText, expectedText); - } + await TestInRegularAndScriptAsync(initialText, expectedText); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3818")] - public async Task InExtensionMethodUnderMultipleConditionalAccessExpressions2() - { - var initialText = - @" + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/3818")] + public async Task InExtensionMethodUnderMultipleConditionalAccessExpressions2() + { + var initialText = +@" public class C @@ -1051,7 +1050,7 @@ public static C Extn(this C obj) "; - var expectedText = + var expectedText = @" using Sample.Extensions; @@ -1063,13 +1062,13 @@ public T F(T x) } } "; - await TestInRegularAndScriptAsync(initialText, expectedText); - } + await TestInRegularAndScriptAsync(initialText, expectedText); + } - [Fact] - public async Task TestDeconstructExtension() - { - await TestAsync( + [Fact] + public async Task TestDeconstructExtension() + { + await TestAsync( @" class Program { @@ -1105,14 +1104,13 @@ public static void Deconstruct(this Program p, out int x, out int y) { } } }", parseOptions: null); - } + } - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/16547")] - public async Task TestAddUsingForAddExtensionMethodWithSameNameAsProperty(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/16547")] + public async Task TestAddUsingForAddExtensionMethodWithSameNameAsProperty(TestHost testHost) + { + await TestAsync( @" namespace A { @@ -1169,14 +1167,13 @@ public static Foo Self(this Foo foo) } } }", testHost); - } + } - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/39155")] - public async Task TestExtensionGetAwaiterOverload(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/39155")] + public async Task TestExtensionGetAwaiterOverload(TestHost testHost) + { + await TestAsync( @" using System; using System.Runtime.CompilerServices; @@ -1260,14 +1257,13 @@ public void GetResult() } } ", testHost); - } + } - [Theory] - [CombinatorialData] - [WorkItem("https://github.com/dotnet/roslyn/issues/39155")] - public async Task TestExtensionSelectOverload(TestHost testHost) - { - await TestAsync( + [Theory, CombinatorialData] + [WorkItem("https://github.com/dotnet/roslyn/issues/39155")] + public async Task TestExtensionSelectOverload(TestHost testHost) + { + await TestAsync( @" using System; using System.Collections.Generic; @@ -1325,12 +1321,12 @@ public static class FooExtensions } } ", testHost); - } + } - [Fact] - public async Task TestExtensionDeconstructOverload() - { - await TestAsync( + [Fact] + public async Task TestExtensionDeconstructOverload() + { + await TestAsync( @" using System; using System.Collections.Generic; @@ -1389,12 +1385,12 @@ public static class FooExtensions } ", parseOptions: null); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55117")] - public async Task TestMethodConflictWithGenericExtension() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55117")] + public async Task TestMethodConflictWithGenericExtension() + { + await TestInRegularAndScriptAsync( @"namespace A { public abstract class Goo @@ -1447,12 +1443,12 @@ public static T Bar( this Goo @this ) => (T)@this.Bar( typeof( T ) ); } }"); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55117")] - public async Task TestMethodConflictWithConditionalGenericExtension() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55117")] + public async Task TestMethodConflictWithConditionalGenericExtension() + { + await TestInRegularAndScriptAsync( @"namespace A { public abstract class Goo @@ -1505,6 +1501,5 @@ public static T Bar( this Goo @this ) => (T)@this.Bar( typeof( T ) ); } }"); - } } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Queries.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Queries.cs index db86d63d07acc..de9c5b76c5d92 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Queries.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Queries.cs @@ -6,18 +6,17 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] +public partial class AddUsingTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] - public partial class AddUsingTests + [Fact] + public async Task TestSimpleQuery() { - [Fact] - public async Task TestSimpleQuery() - { - await TestInRegularAndScriptAsync( + await TestInRegularAndScriptAsync( @"using System; using System.Collections.Generic; @@ -39,12 +38,12 @@ static void Main(string[] args) var q = from x in args select x} }"); - } + } - [Fact] - public async Task TestSimpleWhere() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestSimpleWhere() + { + await TestInRegularAndScriptAsync( @"class Test { public void SimpleWhere() @@ -75,6 +74,5 @@ where n < 5 select n; } }"); - } } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Razor.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Razor.cs index 9c7234d79258b..922e89eae40a6 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Razor.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/AddUsing/AddUsingTests_Razor.cs @@ -6,20 +6,18 @@ using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Remote.Testing; using Microsoft.CodeAnalysis.Test.Utilities; -using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing; + +[Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] +public partial class AddUsingTests_Razor : AbstractAddUsingTests { - [Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)] - public partial class AddUsingTests_Razor : AbstractAddUsingTests + [Theory, CombinatorialData] + public async Task TestAddIntoHiddenRegionWithModernSpanMapper(TestHost host) { - [Theory] - [CombinatorialData] - public async Task TestAddIntoHiddenRegionWithModernSpanMapper(TestHost host) - { - await TestAsync( - @"#line hidden + await TestAsync( +@"#line hidden using System.Collections.Generic; #line default @@ -30,7 +28,7 @@ void Main() [|DateTime|] d; } }", - @"#line hidden +@"#line hidden using System; using System.Collections.Generic; #line default @@ -42,11 +40,10 @@ void Main() DateTime d; } }", host); - } + } - private protected override IDocumentServiceProvider GetDocumentServiceProvider() - { - return new TestDocumentServiceProvider(supportsMappingImportDirectives: true); - } + private protected override IDocumentServiceProvider GetDocumentServiceProvider() + { + return new TestDocumentServiceProvider(supportsMappingImportDirectives: true); } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/ApplyChangesOperationTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/ApplyChangesOperationTests.cs index e9379b2d3db29..9990335dc705f 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/ApplyChangesOperationTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/ApplyChangesOperationTests.cs @@ -15,51 +15,51 @@ using Roslyn.Test.Utilities; using Xunit; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeActions; + +public class ApplyChangesOperationTests : AbstractCSharpCodeActionTest { - public class ApplyChangesOperationTests : AbstractCSharpCodeActionTest + protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) + => new MyCodeRefactoringProvider((Func)parameters.fixProviderData); + + private class MyCodeRefactoringProvider : CodeRefactoringProvider { - protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters) - => new MyCodeRefactoringProvider((Func)parameters.fixProviderData); + private readonly Func _changeSolution; - private class MyCodeRefactoringProvider : CodeRefactoringProvider + public MyCodeRefactoringProvider(Func changeSolution) { - private readonly Func _changeSolution; + _changeSolution = changeSolution; + } - public MyCodeRefactoringProvider(Func changeSolution) - { - _changeSolution = changeSolution; - } + public sealed override Task ComputeRefactoringsAsync(CodeRefactoringContext context) + { + var codeAction = new TestCodeAction(_changeSolution(context.Document.Project.Solution)); + context.RegisterRefactoring(codeAction); + return Task.CompletedTask; + } - public sealed override Task ComputeRefactoringsAsync(CodeRefactoringContext context) - { - var codeAction = new TestCodeAction(_changeSolution(context.Document.Project.Solution)); - context.RegisterRefactoring(codeAction); - return Task.CompletedTask; - } + private sealed class TestCodeAction : CodeAction + { + private readonly Solution _changedSolution; - private sealed class TestCodeAction : CodeAction + public TestCodeAction(Solution changedSolution) { - private readonly Solution _changedSolution; - - public TestCodeAction(Solution changedSolution) - { - _changedSolution = changedSolution; - } + _changedSolution = changedSolution; + } - public override string Title => "Title"; + public override string Title => "Title"; - protected override Task GetChangedSolutionAsync(IProgress progress, CancellationToken cancellationToken) - => Task.FromResult(_changedSolution); - } + protected override Task GetChangedSolutionAsync(IProgress progress, CancellationToken cancellationToken) + => Task.FromResult(_changedSolution); } + } - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] - public async Task TestMakeTextChangeWithInterveningEditToDifferentFile() - { - // This should succeed as the code action is trying to edit a file that is not touched by the actual - // workspace edit that already went in. - await TestSuccessfulApplicationAsync( + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] + public async Task TestMakeTextChangeWithInterveningEditToDifferentFile() + { + // This should succeed as the code action is trying to edit a file that is not touched by the actual + // workspace edit that already went in. + await TestSuccessfulApplicationAsync( @" @@ -74,24 +74,24 @@ class Program2 ", - codeActionTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content")); - }, - intermediaryTransform: solution => - { - var document2 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program2")); - return solution.WithDocumentText(document2.Id, SourceText.From("NewProgram2Content")); - }); - } + codeActionTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content")); + }, + intermediaryTransform: solution => + { + var document2 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program2")); + return solution.WithDocumentText(document2.Id, SourceText.From("NewProgram2Content")); + }); + } - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] - public async Task TestMakeTextChangeWithInterveningRemovalToDifferentFile() - { - // This should succeed as the code action is trying to edit a file that is not touched by the actual - // workspace edit that already went in. - await TestSuccessfulApplicationAsync( + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] + public async Task TestMakeTextChangeWithInterveningRemovalToDifferentFile() + { + // This should succeed as the code action is trying to edit a file that is not touched by the actual + // workspace edit that already went in. + await TestSuccessfulApplicationAsync( @" @@ -106,24 +106,24 @@ class Program2 ", - codeActionTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content")); - }, - intermediaryTransform: solution => - { - var document2 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program2")); - return solution.RemoveDocument(document2.Id); - }); - } + codeActionTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content")); + }, + intermediaryTransform: solution => + { + var document2 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program2")); + return solution.RemoveDocument(document2.Id); + }); + } - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] - public async Task TestMakeTextChangeWithInterveningEditToSameFile() - { - // This should fail as the code action is trying to edit a file that is was already edited by the actual - // workspace edit that already went in. - await TestFailureApplicationAsync( + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] + public async Task TestMakeTextChangeWithInterveningEditToSameFile() + { + // This should fail as the code action is trying to edit a file that is was already edited by the actual + // workspace edit that already went in. + await TestFailureApplicationAsync( @" @@ -138,23 +138,23 @@ class Program2 ", - codeActionTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content1")); - }, - intermediaryTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content2")); - }); - } + codeActionTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content1")); + }, + intermediaryTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content2")); + }); + } - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] - public async Task TestMakeTextChangeWithInterveningRemovalOfThatFile() - { - // This should fail as the code action is trying to edit a file that is subsequently removed. - await TestFailureApplicationAsync( + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] + public async Task TestMakeTextChangeWithInterveningRemovalOfThatFile() + { + // This should fail as the code action is trying to edit a file that is subsequently removed. + await TestFailureApplicationAsync( @" @@ -169,24 +169,24 @@ class Program2 ", - codeActionTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content1")); - }, - intermediaryTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.RemoveDocument(document1.Id); - }); - } + codeActionTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.WithDocumentText(document1.Id, SourceText.From("NewProgram1Content1")); + }, + intermediaryTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.RemoveDocument(document1.Id); + }); + } - [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] - public async Task TestMakeProjectChangeWithInterveningTextEdit() - { - // This should fail as we don't want to make non-text changes that may have undesirable results to the solution - // given the intervening edits. - await TestFailureApplicationAsync( + [Fact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_queries/edit/1419139")] + public async Task TestMakeProjectChangeWithInterveningTextEdit() + { + // This should fail as we don't want to make non-text changes that may have undesirable results to the solution + // given the intervening edits. + await TestFailureApplicationAsync( @" @@ -201,65 +201,64 @@ class Program2 ", - codeActionTransform: solution => - { - var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); - return solution.RemoveDocument(document1.Id); - }, - intermediaryTransform: solution => - { - var document2 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program2")); - return solution.WithDocumentText(document2.Id, SourceText.From("NewProgram1Content2")); - }); - } + codeActionTransform: solution => + { + var document1 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program1")); + return solution.RemoveDocument(document1.Id); + }, + intermediaryTransform: solution => + { + var document2 = solution.Projects.Single().Documents.Single(d => d.FilePath!.Contains("Program2")); + return solution.WithDocumentText(document2.Id, SourceText.From("NewProgram1Content2")); + }); + } - private async Task TestSuccessfulApplicationAsync( - string workspaceXml, - Func codeActionTransform, - Func intermediaryTransform) - { - await TestApplicationAsync(workspaceXml, codeActionTransform, intermediaryTransform, success: true); - } + private async Task TestSuccessfulApplicationAsync( + string workspaceXml, + Func codeActionTransform, + Func intermediaryTransform) + { + await TestApplicationAsync(workspaceXml, codeActionTransform, intermediaryTransform, success: true); + } - private async Task TestFailureApplicationAsync( - string workspaceXml, - Func codeActionTransform, - Func intermediaryTransform) - { - await TestApplicationAsync(workspaceXml, codeActionTransform, intermediaryTransform, success: false); - } + private async Task TestFailureApplicationAsync( + string workspaceXml, + Func codeActionTransform, + Func intermediaryTransform) + { + await TestApplicationAsync(workspaceXml, codeActionTransform, intermediaryTransform, success: false); + } - private async Task TestApplicationAsync( - string workspaceXml, - Func codeActionTransform, - Func intermediaryTransform, - bool success) - { - var parameters = new TestParameters(fixProviderData: codeActionTransform); - using var workspace = CreateWorkspaceFromOptions(workspaceXml, parameters); + private async Task TestApplicationAsync( + string workspaceXml, + Func codeActionTransform, + Func intermediaryTransform, + bool success) + { + var parameters = new TestParameters(fixProviderData: codeActionTransform); + using var workspace = CreateWorkspaceFromOptions(workspaceXml, parameters); - var originalSolution = workspace.CurrentSolution; + var originalSolution = workspace.CurrentSolution; - var document = GetDocument(workspace); - var provider = CreateCodeRefactoringProvider(workspace, parameters); + var document = GetDocument(workspace); + var provider = CreateCodeRefactoringProvider(workspace, parameters); - var refactorings = new List(); - var context = new CodeRefactoringContext(document, new TextSpan(), refactorings.Add, CancellationToken.None); + var refactorings = new List(); + var context = new CodeRefactoringContext(document, new TextSpan(), refactorings.Add, CancellationToken.None); - // Compute refactorings based on the original solution. - await provider.ComputeRefactoringsAsync(context); - var action = refactorings.Single(); - var operations = await action.GetOperationsAsync(CancellationToken.None); - var operation = operations.Single(); + // Compute refactorings based on the original solution. + await provider.ComputeRefactoringsAsync(context); + var action = refactorings.Single(); + var operations = await action.GetOperationsAsync(CancellationToken.None); + var operation = operations.Single(); - // Now make an intermediary edit to the workspace that is applied back in. - var changedSolution = intermediaryTransform(originalSolution); - Assert.True(workspace.TryApplyChanges(changedSolution)); + // Now make an intermediary edit to the workspace that is applied back in. + var changedSolution = intermediaryTransform(originalSolution); + Assert.True(workspace.TryApplyChanges(changedSolution)); - // Now try to apply the refactoring, even though an intervening edit happened. - var result = await operation.TryApplyAsync(workspace, originalSolution, CodeAnalysisProgress.None, CancellationToken.None); + // Now try to apply the refactoring, even though an intervening edit happened. + var result = await operation.TryApplyAsync(workspace, originalSolution, CodeAnalysisProgress.None, CancellationToken.None); - Assert.Equal(success, result); - } + Assert.Equal(success, result); } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs index ad045d21d1c9c..7254e15840547 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs @@ -23,4383 +23,4382 @@ using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeRefactoringVerifier< Microsoft.CodeAnalysis.GenerateEqualsAndGetHashCodeFromMembers.GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider>; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateEqualsAndGetHashCodeFromMembers +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateEqualsAndGetHashCodeFromMembers; + +[UseExportProvider] +[Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)] +public class GenerateEqualsAndGetHashCodeFromMembersTests { - [UseExportProvider] - [Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)] - public class GenerateEqualsAndGetHashCodeFromMembersTests + private class TestWithDialog : VerifyCS.Test { - private class TestWithDialog : VerifyCS.Test - { - private static readonly TestComposition s_composition = - EditorTestCompositions.EditorFeatures.AddParts(typeof(TestPickMembersService)); + private static readonly TestComposition s_composition = + EditorTestCompositions.EditorFeatures.AddParts(typeof(TestPickMembersService)); - public ImmutableArray MemberNames; - public Action> OptionsCallback; + public ImmutableArray MemberNames; + public Action> OptionsCallback; - protected override Task CreateWorkspaceImplAsync() - { - // If we're a dialog test, then mixin our mock and initialize its values to the ones the test asked for. - var workspace = new AdhocWorkspace(s_composition.GetHostServices()); + protected override Task CreateWorkspaceImplAsync() + { + // If we're a dialog test, then mixin our mock and initialize its values to the ones the test asked for. + var workspace = new AdhocWorkspace(s_composition.GetHostServices()); - var service = (TestPickMembersService)workspace.Services.GetService(); - service.MemberNames = MemberNames; - service.OptionsCallback = OptionsCallback; + var service = (TestPickMembersService)workspace.Services.GetService(); + service.MemberNames = MemberNames; + service.OptionsCallback = OptionsCallback; - return Task.FromResult(workspace); - } + return Task.FromResult(workspace); } + } - private static OptionsCollection PreferImplicitTypeWithInfo() - => new OptionsCollection(LanguageNames.CSharp) - { - { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Suggestion }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, true, NotificationOption2.Suggestion }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Suggestion }, - }; + private static OptionsCollection PreferImplicitTypeWithInfo() + => new OptionsCollection(LanguageNames.CSharp) + { + { CSharpCodeStyleOptions.VarElsewhere, true, NotificationOption2.Suggestion }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, true, NotificationOption2.Suggestion }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, true, NotificationOption2.Suggestion }, + }; - private static OptionsCollection PreferExplicitTypeWithInfo() - => new OptionsCollection(LanguageNames.CSharp) - { - { CSharpCodeStyleOptions.VarElsewhere, false, NotificationOption2.Suggestion }, - { CSharpCodeStyleOptions.VarWhenTypeIsApparent, false, NotificationOption2.Suggestion }, - { CSharpCodeStyleOptions.VarForBuiltInTypes, false, NotificationOption2.Suggestion }, - }; + private static OptionsCollection PreferExplicitTypeWithInfo() + => new OptionsCollection(LanguageNames.CSharp) + { + { CSharpCodeStyleOptions.VarElsewhere, false, NotificationOption2.Suggestion }, + { CSharpCodeStyleOptions.VarWhenTypeIsApparent, false, NotificationOption2.Suggestion }, + { CSharpCodeStyleOptions.VarForBuiltInTypes, false, NotificationOption2.Suggestion }, + }; - internal static void EnableOption(ImmutableArray options, string id) + internal static void EnableOption(ImmutableArray options, string id) + { + var option = options.FirstOrDefault(o => o.Id == id); + if (option != null) { - var option = options.FirstOrDefault(o => o.Id == id); - if (option != null) + option.Value = true; + } + } + + [Fact] + public async Task TestEqualsSingleField() + { + var code = + """ + using System.Collections.Generic; + + class Program { - option.Value = true; + [|int a;|] } - } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestEqualsSingleField() - { - var code = - """ - using System.Collections.Generic; + class Program + { + int a; - class Program + public override bool Equals(object obj) { - [|int a;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + a == program.a; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class Program - { - int a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - a == program.a; - } - } - """; + [Fact] + public async Task TestEqualsSingleField_CSharp7() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestEqualsSingleField_CSharp7() - { - var code = - """ - using System.Collections.Generic; + class Program + { + int a; - class Program + public override bool Equals(object obj) { - [|int a;|] + return obj is Program program && + a == program.a; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class Program - { - int a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp7, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - return obj is Program program && - a == program.a; - } - } - """; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] + public async Task TestEqualsSingleField_PreferExplicitType() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp7, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] - public async Task TestEqualsSingleField_PreferExplicitType() - { - var code = - """ - using System.Collections.Generic; + class Program + { + int a; - class Program + public override bool Equals(object obj) { - [|int a;|] + Program program = obj as Program; + return !ReferenceEquals(program, null) && + a == program.a; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class Program - { - int a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferExplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - Program program = obj as Program; - return !ReferenceEquals(program, null) && - a == program.a; - } - } - """; + [Fact] + public async Task TestReferenceIEquatable() + { + var code = + """ + using System; + using System.Collections.Generic; + + class S : {|CS0535:IEquatable|} { } - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferExplicitTypeWithInfo() }, - }.RunAsync(); - } + [|S a;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestReferenceIEquatable() - { - var code = - """ - using System; - using System.Collections.Generic; + class S : {|CS0535:IEquatable|} { } - class S : {|CS0535:IEquatable|} { } + class Program + { + S a; - class Program + public override bool Equals(object obj) { - [|S a;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + EqualityComparer.Default.Equals(a, program.a); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; + } + """; - class S : {|CS0535:IEquatable|} { } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - class Program - { - S a; + [Fact] + public async Task TestNullableReferenceIEquatable() + { + var code = + """ + #nullable enable - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - EqualityComparer.Default.Equals(a, program.a); - } - } - """; + using System; + using System.Collections.Generic; - await new VerifyCS.Test + class S : {|CS0535:IEquatable|} { } + + class Program { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|S? a;|] + } + """; + var fixedCode = + """ + #nullable enable - [Fact] - public async Task TestNullableReferenceIEquatable() - { - var code = - """ - #nullable enable + using System; + using System.Collections.Generic; - using System; - using System.Collections.Generic; + class S : {|CS0535:IEquatable|} { } - class S : {|CS0535:IEquatable|} { } + class Program + { + S? a; - class Program + public override bool Equals(object? obj) { - [|S? a;|] + return obj is Program program && + EqualityComparer.Default.Equals(a, program.a); } - """; - var fixedCode = - """ - #nullable enable - - using System; - using System.Collections.Generic; - class S : {|CS0535:IEquatable|} { } - - class Program + public override int GetHashCode() { - S? a; + return -1757793268 + EqualityComparer.Default.GetHashCode(a); + } + } + """; - public override bool Equals(object? obj) - { - return obj is Program program && - EqualityComparer.Default.Equals(a, program.a); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return -1757793268 + EqualityComparer.Default.GetHashCode(a); - } - } - """; + [Fact] + public async Task TestValueIEquatable() + { + var code = + """ + using System; + using System.Collections.Generic; - await new VerifyCS.Test + struct S : {|CS0535:IEquatable|} { } + + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|S a;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestValueIEquatable() - { - var code = - """ - using System; - using System.Collections.Generic; + struct S : {|CS0535:IEquatable|} { } - struct S : {|CS0535:IEquatable|} { } + class Program + { + S a; - class Program + public override bool Equals(object obj) { - [|S a;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + a.Equals(program.a); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - - struct S : {|CS0535:IEquatable|} { } + } + """; - class Program - { - S a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - a.Equals(program.a); - } - } - """; + [Fact] + public async Task TestEqualsLongName() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class ReallyLongName { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestEqualsLongName() - { - var code = - """ - using System.Collections.Generic; + class ReallyLongName + { + int a; - class ReallyLongName + public override bool Equals(object obj) { - [|int a;|] + var name = obj as ReallyLongName; + return !ReferenceEquals(name, null) && + a == name.a; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class ReallyLongName - { - int a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var name = obj as ReallyLongName; - return !ReferenceEquals(name, null) && - a == name.a; - } - } - """; + [Fact] + public async Task TestEqualsKeywordName() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class ReallyLongLong { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|long a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestEqualsKeywordName() - { - var code = - """ - using System.Collections.Generic; + class ReallyLongLong + { + long a; - class ReallyLongLong + public override bool Equals(object obj) { - [|long a;|] + var @long = obj as ReallyLongLong; + return !ReferenceEquals(@long, null) && + a == @long.a; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class ReallyLongLong - { - long a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var @long = obj as ReallyLongLong; - return !ReferenceEquals(@long, null) && - a == @long.a; - } - } - """; + [Fact] + public async Task TestEqualsProperty() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class ReallyLongName { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int a; - [Fact] - public async Task TestEqualsProperty() - { - var code = - """ - using System.Collections.Generic; + string B { get; }|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - class ReallyLongName - { - [|int a; + class ReallyLongName + { + int a; - string B { get; }|] - } - """; - var fixedCode = - """ - using System.Collections.Generic; + string B { get; } - class ReallyLongName + public override bool Equals(object obj) { - int a; + var name = obj as ReallyLongName; + return !ReferenceEquals(name, null) && + a == name.a && + B == name.B; + } + } + """; - string B { get; } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var name = obj as ReallyLongName; - return !ReferenceEquals(name, null) && - a == name.a && - B == name.B; - } - } - """; + [Fact] + public async Task TestEqualsBaseTypeWithNoEquals() + { + var code = + """ + class Base + { + } - await new VerifyCS.Test + class Program : Base { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int i;|] + } + """; + var fixedCode = + """ + class Base + { + } - [Fact] - public async Task TestEqualsBaseTypeWithNoEquals() - { - var code = - """ - class Base - { - } + class Program : Base + { + int i; - class Program : Base + public override bool Equals(object obj) { - [|int i;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + i == program.i; } - """; - var fixedCode = - """ - class Base + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } + + [Fact] + public async Task TestEqualsBaseWithOverriddenEquals() + { + var code = + """ + using System.Collections.Generic; + + class Base + { + public override bool Equals(object o) { + return false; } + } - class Program : Base - { - int i; + class Program : Base + { + [|int i; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - i == program.i; - } + string S { get; }|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; + + class Base + { + public override bool Equals(object o) + { + return false; } - """; + } - await new VerifyCS.Test + class Program : Base { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int i; - [Fact] - public async Task TestEqualsBaseWithOverriddenEquals() - { - var code = - """ - using System.Collections.Generic; + string S { get; } - class Base + public override bool Equals(object obj) { - public override bool Equals(object o) - { - return false; - } + var program = obj as Program; + return !ReferenceEquals(program, null) && + base.Equals(obj) && + i == program.i && + S == program.S; } + } + """; - class Program : Base - { - [|int i; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 0, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - string S { get; }|] - } - """; - var fixedCode = - """ - using System.Collections.Generic; + [Fact] + public async Task TestEqualsOverriddenDeepBase() + { + var code = + """ + using System.Collections.Generic; - class Base + class Base + { + public override bool Equals(object o) { - public override bool Equals(object o) - { - return false; - } + return false; } + } - class Program : Base - { - int i; + class Middle : Base + { + } - string S { get; } + class Program : Middle + { + [|int i; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - base.Equals(obj) && - i == program.i && - S == program.S; - } + string S { get; }|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; + + class Base + { + public override bool Equals(object o) + { + return false; } - """; + } - await new VerifyCS.Test + class Middle : Base { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 0, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + } - [Fact] - public async Task TestEqualsOverriddenDeepBase() - { - var code = - """ - using System.Collections.Generic; + class Program : Middle + { + int i; + + string S { get; } - class Base + public override bool Equals(object obj) { - public override bool Equals(object o) - { - return false; - } + var program = obj as Program; + return !ReferenceEquals(program, null) && + base.Equals(obj) && + i == program.i && + S == program.S; } + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } + + [Fact] + public async Task TestEqualsStruct() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System.Collections.Generic; + + struct ReallyLongName + { + [|int i; + + string S { get; }|] + } + """, + """ + using System; + using System.Collections.Generic; + + struct ReallyLongName : IEquatable + { + int i; + + string S { get; } - class Middle : Base + public override bool Equals(object obj) { + return obj is ReallyLongName name && Equals(name); } - class Program : Middle + public bool Equals(ReallyLongName other) { - [|int i; - - string S { get; }|] + return i == other.i && + S == other.S; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Base + public static bool operator ==(ReallyLongName left, ReallyLongName right) { - public override bool Equals(object o) - { - return false; - } + return left.Equals(right); } - class Middle : Base + public static bool operator !=(ReallyLongName left, ReallyLongName right) { + return !(left == right); } + } + """); + } - class Program : Middle - { - int i; + [Fact] + public async Task TestEqualsStructCSharpLatest() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System.Collections.Generic; - string S { get; } + struct ReallyLongName + { + [|int i; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - base.Equals(obj) && - i == program.i && - S == program.S; - } - } - """; + string S { get; }|] + } + """, + """ + using System; + using System.Collections.Generic; - await new VerifyCS.Test + struct ReallyLongName : IEquatable { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int i; - [Fact] - public async Task TestEqualsStruct() - { - await VerifyCS.VerifyRefactoringAsync( - """ - using System.Collections.Generic; + string S { get; } - struct ReallyLongName + public override bool Equals(object obj) { - [|int i; + return obj is ReallyLongName name && Equals(name); + } - string S { get; }|] + public bool Equals(ReallyLongName other) + { + return i == other.i && + S == other.S; } - """, - """ - using System; - using System.Collections.Generic; - struct ReallyLongName : IEquatable + public static bool operator ==(ReallyLongName left, ReallyLongName right) { - int i; + return left.Equals(right); + } - string S { get; } + public static bool operator !=(ReallyLongName left, ReallyLongName right) + { + return !(left == right); + } + } + """); + } - public override bool Equals(object obj) - { - return obj is ReallyLongName name && Equals(name); - } + [Fact] + public async Task TestEqualsStructAlreadyImplementsIEquatable() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System; + using System.Collections.Generic; - public bool Equals(ReallyLongName other) - { - return i == other.i && - S == other.S; - } + struct ReallyLongName : {|CS0535:IEquatable|} + { + [|int i; - public static bool operator ==(ReallyLongName left, ReallyLongName right) - { - return left.Equals(right); - } + string S { get; }|] + } + """, + """ + using System; + using System.Collections.Generic; - public static bool operator !=(ReallyLongName left, ReallyLongName right) - { - return !(left == right); - } - } - """); - } + struct ReallyLongName : {|CS0535:IEquatable|} + { + int i; - [Fact] - public async Task TestEqualsStructCSharpLatest() - { - await VerifyCS.VerifyRefactoringAsync( - """ - using System.Collections.Generic; + string S { get; } - struct ReallyLongName + public override bool Equals(object obj) { - [|int i; + return obj is ReallyLongName name && + i == name.i && + S == name.S; + } - string S { get; }|] + public static bool operator ==(ReallyLongName left, ReallyLongName right) + { + return left.Equals(right); } - """, - """ - using System; - using System.Collections.Generic; - struct ReallyLongName : IEquatable + public static bool operator !=(ReallyLongName left, ReallyLongName right) { - int i; + return !(left == right); + } + } + """); + } - string S { get; } + [Fact] + public async Task TestEqualsStructAlreadyHasOperators() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System; + using System.Collections.Generic; - public override bool Equals(object obj) - { - return obj is ReallyLongName name && Equals(name); - } + struct ReallyLongName + { + [|int i; - public bool Equals(ReallyLongName other) - { - return i == other.i && - S == other.S; - } + string S { get; }|] - public static bool operator ==(ReallyLongName left, ReallyLongName right) - { - return left.Equals(right); - } + public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; + public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; + } + """, + """ + using System; + using System.Collections.Generic; - public static bool operator !=(ReallyLongName left, ReallyLongName right) - { - return !(left == right); - } - } - """); - } + struct ReallyLongName : IEquatable + { + int i; - [Fact] - public async Task TestEqualsStructAlreadyImplementsIEquatable() - { - await VerifyCS.VerifyRefactoringAsync( - """ - using System; - using System.Collections.Generic; + string S { get; } - struct ReallyLongName : {|CS0535:IEquatable|} + public override bool Equals(object obj) { - [|int i; - - string S { get; }|] + return obj is ReallyLongName name && Equals(name); } - """, - """ - using System; - using System.Collections.Generic; - struct ReallyLongName : {|CS0535:IEquatable|} + public bool Equals(ReallyLongName other) { - int i; - - string S { get; } + return i == other.i && + S == other.S; + } - public override bool Equals(object obj) - { - return obj is ReallyLongName name && - i == name.i && - S == name.S; - } + public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; + public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; + } + """); + } - public static bool operator ==(ReallyLongName left, ReallyLongName right) - { - return left.Equals(right); - } + [Fact] + public async Task TestEqualsStructAlreadyImplementsIEquatableAndHasOperators() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System; + using System.Collections.Generic; - public static bool operator !=(ReallyLongName left, ReallyLongName right) - { - return !(left == right); - } - } - """); - } + struct ReallyLongName : {|CS0535:IEquatable|} + { + [|int i; - [Fact] - public async Task TestEqualsStructAlreadyHasOperators() - { - await VerifyCS.VerifyRefactoringAsync( - """ - using System; - using System.Collections.Generic; + string S { get; }|] - struct ReallyLongName - { - [|int i; + public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; + public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; + } + """, + """ + using System; + using System.Collections.Generic; - string S { get; }|] + struct ReallyLongName : {|CS0535:IEquatable|} + { + int i; - public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; - public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; - } - """, - """ - using System; - using System.Collections.Generic; + string S { get; } - struct ReallyLongName : IEquatable + public override bool Equals(object obj) { - int i; + return obj is ReallyLongName name && + i == name.i && + S == name.S; + } - string S { get; } + public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; + public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; + } + """); + } - public override bool Equals(object obj) - { - return obj is ReallyLongName name && Equals(name); - } + [Fact] + public async Task TestEqualsGenericType() + { + var code = """ + using System.Collections.Generic; + class Program + { + [|int i;|] + } + """; - public bool Equals(ReallyLongName other) - { - return i == other.i && - S == other.S; - } + var expected = """ + using System.Collections.Generic; + class Program + { + int i; - public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; - public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; + public override bool Equals(object obj) + { + var program = obj as Program; + return !ReferenceEquals(program, null) && + i == program.i; } - """); - } + } + """; - [Fact] - public async Task TestEqualsStructAlreadyImplementsIEquatableAndHasOperators() + await new VerifyCS.Test { - await VerifyCS.VerifyRefactoringAsync( - """ - using System; - using System.Collections.Generic; + TestCode = code, + FixedCode = expected, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - struct ReallyLongName : {|CS0535:IEquatable|} - { - [|int i; + [Fact] + public async Task TestEqualsNullableContext() + { + await VerifyCS.VerifyRefactoringAsync( + """ + #nullable enable - string S { get; }|] + class Program + { + [|int a;|] + } + """, + """ + #nullable enable - public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; - public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; - } - """, - """ - using System; - using System.Collections.Generic; + class Program + { + int a; - struct ReallyLongName : {|CS0535:IEquatable|} + public override bool Equals(object? obj) { - int i; + return obj is Program program && + a == program.a; + } + } + """); + } - string S { get; } + [Fact] + public async Task TestGetHashCodeSingleField1() + { + var code = + """ + using System.Collections.Generic; - public override bool Equals(object obj) - { - return obj is ReallyLongName name && - i == name.i && - S == name.S; - } + class Program + { + [|int i;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - public static bool operator ==(ReallyLongName left, ReallyLongName right) => false; - public static bool operator !=(ReallyLongName left, ReallyLongName right) => false; - } - """); - } + class Program + { + int i; - [Fact] - public async Task TestEqualsGenericType() - { - var code = """ - using System.Collections.Generic; - class Program + public override bool Equals(object obj) { - [|int i;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + i == program.i; } - """; - var expected = """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - int i; - - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - i == program.i; - } + return 165851236 + i.GetHashCode(); } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } + + [Fact] + public async Task TestGetHashCodeSingleField2() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = expected, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int j;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestEqualsNullableContext() - { - await VerifyCS.VerifyRefactoringAsync( - """ - #nullable enable + class Program + { + int j; - class Program + public override bool Equals(object obj) { - [|int a;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + j == program.j; } - """, - """ - #nullable enable - class Program + public override int GetHashCode() { - int a; - - public override bool Equals(object? obj) - { - return obj is Program program && - a == program.a; - } + return 1424088837 + j.GetHashCode(); } - """); - } + } + """; - [Fact] - public async Task TestGetHashCodeSingleField1() + await new VerifyCS.Test { - var code = - """ - using System.Collections.Generic; + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - class Program - { - [|int i;|] - } - """; - var fixedCode = - """ - using System.Collections.Generic; + [Fact] + public async Task TestGetHashCodeWithBaseHashCode1() + { + var code = + """ + using System.Collections.Generic; - class Program - { - int i; + class Base { + public override int GetHashCode() => 0; + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - i == program.i; - } + class Program : Base + { + [|int j;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - public override int GetHashCode() - { - return 165851236 + i.GetHashCode(); - } - } - """; + class Base { + public override int GetHashCode() => 0; + } - await new VerifyCS.Test + class Program : Base { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int j; - [Fact] - public async Task TestGetHashCodeSingleField2() - { - var code = - """ - using System.Collections.Generic; - - class Program + public override bool Equals(object obj) { - [|int j;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + j == program.j; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - int j; + var hashCode = 339610899; + hashCode = hashCode * -1521134295 + base.GetHashCode(); + hashCode = hashCode * -1521134295 + j.GetHashCode(); + return hashCode; + } + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - j == program.j; - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 1424088837 + j.GetHashCode(); - } - } - """; + [Fact] + public async Task TestGetHashCodeWithBaseHashCode2() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Base { + public override int GetHashCode() => 0; + } + + class Program : Base { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int j; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestGetHashCodeWithBaseHashCode1() - { - var code = - """ - using System.Collections.Generic; + class Base { + public override int GetHashCode() => 0; + } - class Base { - public override int GetHashCode() => 0; - } + class Program : Base + { + int j; - class Program : Base + public override bool Equals(object obj) { - [|int j;|] + var program = obj as Program; + return !ReferenceEquals(program, null); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Base { - public override int GetHashCode() => 0; - } - - class Program : Base + public override int GetHashCode() { - int j; + return 624022166 + base.GetHashCode(); + } + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - j == program.j; - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + MemberNames = ImmutableArray.Empty, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - var hashCode = 339610899; - hashCode = hashCode * -1521134295 + base.GetHashCode(); - hashCode = hashCode * -1521134295 + j.GetHashCode(); - return hashCode; - } - } - """; + [Fact] + public async Task TestGetHashCodeSingleField_CodeStyle1() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } - - [Fact] - public async Task TestGetHashCodeWithBaseHashCode2() - { - var code = - """ - using System.Collections.Generic; + [|int i;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - class Base { - public override int GetHashCode() => 0; - } + class Program + { + int i; - class Program : Base + public override bool Equals(object obj) { - int j; - [||] + Program program = obj as Program; + return !ReferenceEquals(program, null) && + i == program.i; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Base { - public override int GetHashCode() => 0; - } - - class Program : Base - { - int j; + public override int GetHashCode() => 165851236 + i.GetHashCode(); + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement }, + }, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + }.RunAsync(); + } - public override int GetHashCode() - { - return 624022166 + base.GetHashCode(); - } - } - """; + [Fact] + public async Task TestGetHashCodeTypeParameter() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - MemberNames = ImmutableArray.Empty, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|T i;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestGetHashCodeSingleField_CodeStyle1() - { - var code = - """ - using System.Collections.Generic; + class Program + { + T i; - class Program + public override bool Equals(object obj) { - [|int i;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + EqualityComparer.Default.Equals(i, program.i); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - int i; + return 165851236 + EqualityComparer.Default.GetHashCode(i); + } + } + """; - public override bool Equals(object obj) - { - Program program = obj as Program; - return !ReferenceEquals(program, null) && - i == program.i; - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() => 165851236 + i.GetHashCode(); - } - """; + [Fact] + public async Task TestGetHashCodeGenericType() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement }, - }, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - }.RunAsync(); - } + [|Program i;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestGetHashCodeTypeParameter() - { - var code = - """ - using System.Collections.Generic; + class Program + { + Program i; - class Program + public override bool Equals(object obj) { - [|T i;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + EqualityComparer>.Default.Equals(i, program.i); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - T i; + return 165851236 + EqualityComparer>.Default.GetHashCode(i); + } + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - EqualityComparer.Default.Equals(i, program.i); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 165851236 + EqualityComparer.Default.GetHashCode(i); - } - } - """; + [Fact] + public async Task TestGetHashCodeMultipleMembers() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|int i; - [Fact] - public async Task TestGetHashCodeGenericType() - { - var code = - """ - using System.Collections.Generic; + string S { get; }|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - class Program + class Program + { + int i; + + string S { get; } + + public override bool Equals(object obj) { - [|Program i;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + i == program.i && + S == program.S; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - Program i; + var hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; + } + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - EqualityComparer>.Default.Equals(i, program.i); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 165851236 + EqualityComparer>.Default.GetHashCode(i); - } - } - """; + [Fact] + public async Task TestSmartTagText1() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } - - [Fact] - public async Task TestGetHashCodeMultipleMembers() - { - var code = - """ - using System.Collections.Generic; + [|bool b; + HashSet s;|] - class Program + public Program(bool b) { - [|int i; + this.b = b; + } + } + """; + var fixedCode = + """ + using System.Collections.Generic; + + class Program + { + bool b; + HashSet s; - string S { get; }|] + public Program(bool b) + { + this.b = b; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override bool Equals(object obj) { - int i; + return obj is Program program && + b == program.b && + EqualityComparer>.Default.Equals(s, program.s); + } + } + """; - string S { get; } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 0, + CodeActionEquivalenceKey = FeaturesResources.Generate_Equals_object, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(FeaturesResources.Generate_Equals_object, codeAction.Title), + }.RunAsync(); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - i == program.i && - S == program.S; - } + [Fact] + public async Task TestSmartTagText2() + { + var code = + """ + using System.Collections.Generic; - public override int GetHashCode() - { - var hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } + class Program + { + [|bool b; + HashSet s;|] + + public Program(bool b) + { + this.b = b; } - """; + } + """; + var fixedCode = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } - - [Fact] - public async Task TestSmartTagText1() - { - var code = - """ - using System.Collections.Generic; + bool b; + HashSet s; - class Program + public Program(bool b) { - [|bool b; - HashSet s;|] + this.b = b; + } - public Program(bool b) - { - this.b = b; - } + public override bool Equals(object obj) + { + return obj is Program program && + b == program.b && + EqualityComparer>.Default.Equals(s, program.s); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - bool b; - HashSet s; + int hashCode = -666523601; + hashCode = hashCode * -1521134295 + b.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(s); + return hashCode; + } + } + """; - public Program(bool b) - { - this.b = b; - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + CodeActionEquivalenceKey = FeaturesResources.Generate_Equals_and_GetHashCode, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(FeaturesResources.Generate_Equals_and_GetHashCode, codeAction.Title), + }.RunAsync(); + } - public override bool Equals(object obj) - { - return obj is Program program && - b == program.b && - EqualityComparer>.Default.Equals(s, program.s); - } - } - """; + [Fact] + public async Task TestSmartTagText3() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 0, - CodeActionEquivalenceKey = FeaturesResources.Generate_Equals_object, - CodeActionVerifier = (codeAction, verifier) => verifier.Equal(FeaturesResources.Generate_Equals_object, codeAction.Title), - }.RunAsync(); - } + [|bool b; + HashSet s;|] - [Fact] - public async Task TestSmartTagText2() - { - var code = - """ - using System.Collections.Generic; + public Program(bool b) + { + this.b = b; + } + } + """; + var fixedCode = + """ + using System.Collections.Generic; + + class Program + { + bool b; + HashSet s; - class Program + public Program(bool b) { - [|bool b; - HashSet s;|] + this.b = b; + } - public Program(bool b) - { - this.b = b; - } + public override bool Equals(object obj) + { + return obj is Program program && + b == program.b && + EqualityComparer>.Default.Equals(s, program.s); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - bool b; - HashSet s; + int hashCode = -666523601; + hashCode = hashCode * -1521134295 + b.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(s); + return hashCode; + } + } + """; - public Program(bool b) - { - this.b = b; - } - - public override bool Equals(object obj) - { - return obj is Program program && - b == program.b && - EqualityComparer>.Default.Equals(s, program.s); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + CodeActionEquivalenceKey = FeaturesResources.Generate_Equals_and_GetHashCode, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(FeaturesResources.Generate_Equals_and_GetHashCode, codeAction.Title), + }.RunAsync(); + } - public override int GetHashCode() - { - int hashCode = -666523601; - hashCode = hashCode * -1521134295 + b.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(s); - return hashCode; - } - } - """; + [Fact] + public async Task Tuple_Disabled() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class C { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - CodeActionEquivalenceKey = FeaturesResources.Generate_Equals_and_GetHashCode, - CodeActionVerifier = (codeAction, verifier) => verifier.Equal(FeaturesResources.Generate_Equals_and_GetHashCode, codeAction.Title), - }.RunAsync(); - } + [|{|CS8059:(int, string)|} a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestSmartTagText3() - { - var code = - """ - using System.Collections.Generic; + class C + { + {|CS8059:(int, string)|} a; - class Program + public override bool Equals(object obj) { - [|bool b; - HashSet s;|] - - public Program(bool b) - { - this.b = b; - } + var c = obj as C; + return !ReferenceEquals(c, null) && + a.Equals(c.a); } - """; - var fixedCode = - """ - using System.Collections.Generic; - - class Program - { - bool b; - HashSet s; - - public Program(bool b) - { - this.b = b; - } + } + """; - public override bool Equals(object obj) - { - return obj is Program program && - b == program.b && - EqualityComparer>.Default.Equals(s, program.s); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 0, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - int hashCode = -666523601; - hashCode = hashCode * -1521134295 + b.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer>.Default.GetHashCode(s); - return hashCode; - } - } - """; + [Fact] + public async Task Tuples_Equals() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class C { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - CodeActionEquivalenceKey = FeaturesResources.Generate_Equals_and_GetHashCode, - CodeActionVerifier = (codeAction, verifier) => verifier.Equal(FeaturesResources.Generate_Equals_and_GetHashCode, codeAction.Title), - }.RunAsync(); - } + [|{|CS8059:(int, string)|} a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task Tuple_Disabled() - { - var code = - """ - using System.Collections.Generic; + class C + { + {|CS8059:(int, string)|} a; - class C + public override bool Equals(object obj) { - [|{|CS8059:(int, string)|} a;|] + var c = obj as C; + return !ReferenceEquals(c, null) && + a.Equals(c.a); } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class C - { - {|CS8059:(int, string)|} a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var c = obj as C; - return !ReferenceEquals(c, null) && - a.Equals(c.a); - } - } - """; + [Fact] + public async Task TupleWithNames_Equals() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class C { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 0, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|{|CS8059:(int x, string y)|} a;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task Tuples_Equals() - { - var code = - """ - using System.Collections.Generic; + class C + { + {|CS8059:(int x, string y)|} a; - class C + public override bool Equals(object obj) { - [|{|CS8059:(int, string)|} a;|] + var c = obj as C; + return !ReferenceEquals(c, null) && + a.Equals(c.a); } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class C - { - {|CS8059:(int, string)|} a; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var c = obj as C; - return !ReferenceEquals(c, null) && - a.Equals(c.a); - } - } - """; + [Fact] + public async Task Tuple_HashCode() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|{|CS8059:(int, string)|} i;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TupleWithNames_Equals() - { - var code = - """ - using System.Collections.Generic; + class Program + { + {|CS8059:(int, string)|} i; - class C + public override bool Equals(object obj) { - [|{|CS8059:(int x, string y)|} a;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + i.Equals(program.i); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class C + public override int GetHashCode() { - {|CS8059:(int x, string y)|} a; - - public override bool Equals(object obj) - { - var c = obj as C; - return !ReferenceEquals(c, null) && - a.Equals(c.a); - } + return 165851236 + i.GetHashCode(); } - """; - - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + } + """; - [Fact] - public async Task Tuple_HashCode() + await new VerifyCS.Test { - var code = - """ - using System.Collections.Generic; - - class Program - { - [|{|CS8059:(int, string)|} i;|] - } - """; - var fixedCode = - """ - using System.Collections.Generic; - - class Program - { - {|CS8059:(int, string)|} i; - - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - i.Equals(program.i); - } + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 165851236 + i.GetHashCode(); - } - } - """; + [Fact] + public async Task TupleWithNames_HashCode() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|{|CS8059:(int x, string y)|} i;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TupleWithNames_HashCode() - { - var code = - """ - using System.Collections.Generic; + class Program + { + {|CS8059:(int x, string y)|} i; - class Program + public override bool Equals(object obj) { - [|{|CS8059:(int x, string y)|} i;|] + var program = obj as Program; + return !ReferenceEquals(program, null) && + i.Equals(program.i); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public override int GetHashCode() { - {|CS8059:(int x, string y)|} i; + return 165851236 + i.GetHashCode(); + } + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - i.Equals(program.i); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 165851236 + i.GetHashCode(); - } - } - """; + [Fact] + public async Task StructWithoutGetHashCodeOverride_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Foo { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|Bar bar;|] + } - [Fact] - public async Task StructWithoutGetHashCodeOverride_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + struct Bar + { + } + """; + var fixedCode = + """ + using System.Collections.Generic; - class Foo + class Foo + { + Bar bar; + + public override bool Equals(object obj) { - [|Bar bar;|] + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + EqualityComparer.Default.Equals(bar, foo.bar); } - struct Bar + public override int GetHashCode() { + return 999205674 + bar.GetHashCode(); } - """; - var fixedCode = - """ - using System.Collections.Generic; + } - class Foo - { - Bar bar; + struct Bar + { + } + """; - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - EqualityComparer.Default.Equals(bar, foo.bar); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } + [Fact] + public async Task StructWithGetHashCodeOverride_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - struct Bar - { - } - """; + class Foo + { + [|Bar bar;|] + } - await new VerifyCS.Test + struct Bar { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public override int GetHashCode() => 0; + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task StructWithGetHashCodeOverride_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + class Foo + { + Bar bar; - class Foo + public override bool Equals(object obj) { - [|Bar bar;|] + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + EqualityComparer.Default.Equals(bar, foo.bar); } - struct Bar + public override int GetHashCode() { - public override int GetHashCode() => 0; + return 999205674 + bar.GetHashCode(); } - """; - var fixedCode = - """ - using System.Collections.Generic; + } - class Foo - { - Bar bar; + struct Bar + { + public override int GetHashCode() => 0; + } + """; - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - EqualityComparer.Default.Equals(bar, foo.bar); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } + [Fact] + public async Task NullableStructWithoutGetHashCodeOverride_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - struct Bar - { - public override int GetHashCode() => 0; - } - """; + class Foo + { + [|Bar? bar;|] + } - await new VerifyCS.Test + struct Bar { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task NullableStructWithoutGetHashCodeOverride_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + class Foo + { + Bar? bar; - class Foo + public override bool Equals(object obj) { - [|Bar? bar;|] + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + EqualityComparer.Default.Equals(bar, foo.bar); } - struct Bar + public override int GetHashCode() { + return 999205674 + bar.GetHashCode(); } - """; - var fixedCode = - """ - using System.Collections.Generic; - - class Foo - { - Bar? bar; + } - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - EqualityComparer.Default.Equals(bar, foo.bar); - } + struct Bar + { + } + """; - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - struct Bar - { - } - """; + [Fact] + public async Task StructTypeParameter_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Foo where TBar : struct { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|TBar bar;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task StructTypeParameter_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + class Foo where TBar : struct + { + TBar bar; - class Foo where TBar : struct + public override bool Equals(object obj) { - [|TBar bar;|] + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + EqualityComparer.Default.Equals(bar, foo.bar); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Foo where TBar : struct + public override int GetHashCode() { - TBar bar; + return 999205674 + bar.GetHashCode(); + } + } + """; - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - EqualityComparer.Default.Equals(bar, foo.bar); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } - """; + [Fact] + public async Task NullableStructTypeParameter_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Foo where TBar : struct { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|TBar? bar;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task NullableStructTypeParameter_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + class Foo where TBar : struct + { + TBar? bar; - class Foo where TBar : struct + public override bool Equals(object obj) { - [|TBar? bar;|] + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + EqualityComparer.Default.Equals(bar, foo.bar); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Foo where TBar : struct + public override int GetHashCode() { - TBar? bar; + return 999205674 + bar.GetHashCode(); + } + } + """; - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - EqualityComparer.Default.Equals(bar, foo.bar); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } - """; + [Fact] + public async Task Enum_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Foo { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|Bar bar;|] + } - [Fact] - public async Task Enum_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + enum Bar + { + } + """; + var fixedCode = + """ + using System.Collections.Generic; - class Foo - { - [|Bar bar;|] - } + class Foo + { + Bar bar; - enum Bar + public override bool Equals(object obj) { + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + bar == foo.bar; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Foo + public override int GetHashCode() { - Bar bar; + return 999205674 + bar.GetHashCode(); + } + } - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - bar == foo.bar; - } + enum Bar + { + } + """; - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - enum Bar - { - } - """; + [Fact] + public async Task PrimitiveValueType_ShouldCallGetHashCodeDirectly() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Foo { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + [|ulong bar;|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task PrimitiveValueType_ShouldCallGetHashCodeDirectly() - { - var code = - """ - using System.Collections.Generic; + class Foo + { + ulong bar; - class Foo + public override bool Equals(object obj) { - [|ulong bar;|] + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + bar == foo.bar; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Foo + public override int GetHashCode() { - ulong bar; + return 999205674 + bar.GetHashCode(); + } + } + """; - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - bar == foo.bar; - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } - } - """; + [Fact] + public async Task TestWithDialog1() + { + var code = + """ + using System.Collections.Generic; - await new VerifyCS.Test + class Program { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int a; + string b; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestWithDialog1() - { - var code = - """ - using System.Collections.Generic; + class Program + { + int a; + string b; - class Program + public override bool Equals(object obj) { - int a; - string b; - [||] + var program = obj as Program; + return !ReferenceEquals(program, null) && + a == program.a && + b == program.b; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class Program - { - int a; - string b; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = ImmutableArray.Create("a", "b"), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - a == program.a && - b == program.b; - } - } - """; + [Fact] + public async Task TestWithDialog2() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = ImmutableArray.Create("a", "b"), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int a; + string b; + bool c; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestWithDialog2() - { - var code = - """ - using System.Collections.Generic; + class Program + { + int a; + string b; + bool c; - class Program + public override bool Equals(object obj) { - int a; - string b; - bool c; - [||] + var program = obj as Program; + return !ReferenceEquals(program, null) && + c == program.c && + b == program.b; } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class Program - { - int a; - string b; - bool c; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = ImmutableArray.Create("c", "b"), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - c == program.c && - b == program.b; - } - } - """; + [Fact] + public async Task TestWithDialog3() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = ImmutableArray.Create("c", "b"), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + int a; + string b; + bool c; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestWithDialog3() - { - var code = - """ - using System.Collections.Generic; + class Program + { + int a; + string b; + bool c; - class Program + public override bool Equals(object obj) { - int a; - string b; - bool c; - [||] + var program = obj as Program; + return !ReferenceEquals(program, null); } - """; - var fixedCode = - """ - using System.Collections.Generic; + } + """; - class Program - { - int a; - string b; - bool c; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = ImmutableArray.Empty, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null); - } - } - """; - - await new TestWithDialog + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17643")] + public async Task TestWithDialogNoBackingField() + { + var code = + """ + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = ImmutableArray.Empty, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public int F { get; set; } + [||] + } + """; + var fixedCode = + """ + class Program + { + public int F { get; set; } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17643")] - public async Task TestWithDialogNoBackingField() - { - var code = - """ - class Program + public override bool Equals(object obj) { - public int F { get; set; } - [||] + var program = obj as Program; + return !ReferenceEquals(program, null) && + F == program.F; } - """; - var fixedCode = - """ - class Program - { - public int F { get; set; } + } + """; - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - F == program.F; - } - } - """; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - await new TestWithDialog + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25690")] + public async Task TestWithDialogNoIndexer() + { + var code = + """ + class Program { - TestCode = code, - FixedCode = fixedCode, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public int P => 0; + public int this[int index] => 0; + [||] + } + """; + var fixedCode = + """ + class Program + { + public int P => 0; + public int this[int index] => 0; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25690")] - public async Task TestWithDialogNoIndexer() - { - var code = - """ - class Program + public override bool Equals(object obj) { - public int P => 0; - public int this[int index] => 0; - [||] + return obj is Program program && + P == program.P; } - """; - var fixedCode = - """ - class Program - { - public int P => 0; - public int this[int index] => 0; + } + """; - public override bool Equals(object obj) - { - return obj is Program program && - P == program.P; - } - } - """; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + }.RunAsync(); + } - await new TestWithDialog + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25707")] + public async Task TestWithDialogNoSetterOnlyProperty() + { + var code = + """ + class Program { - TestCode = code, - FixedCode = fixedCode, - }.RunAsync(); - } + public int P => 0; + public int S { set { } } + [||] + } + """; + var fixedCode = + """ + class Program + { + public int P => 0; + public int S { set { } } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25707")] - public async Task TestWithDialogNoSetterOnlyProperty() - { - var code = - """ - class Program + public override bool Equals(object obj) { - public int P => 0; - public int S { set { } } - [||] + return obj is Program program && + P == program.P; } - """; - var fixedCode = - """ - class Program - { - public int P => 0; - public int S { set { } } + } + """; - public override bool Equals(object obj) - { - return obj is Program program && - P == program.P; - } - } - """; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + }.RunAsync(); + } - await new TestWithDialog + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41958")] + public async Task TestWithDialogInheritedMembers() + { + var code = + """ + class Base { - TestCode = code, - FixedCode = fixedCode, - }.RunAsync(); - } + public int C { get; set; } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41958")] - public async Task TestWithDialogInheritedMembers() - { - var code = - """ - class Base - { - public int C { get; set; } - } + class Middle : Base + { + public int B { get; set; } + } - class Middle : Base - { - public int B { get; set; } - } + class Derived : Middle + { + public int A { get; set; } + [||] + } + """; + var fixedCode = + """ + class Base + { + public int C { get; set; } + } - class Derived : Middle - { - public int A { get; set; } - [||] - } - """; - var fixedCode = - """ - class Base - { - public int C { get; set; } - } + class Middle : Base + { + public int B { get; set; } + } - class Middle : Base + class Derived : Middle + { + public int A { get; set; } + + public override bool Equals(object obj) { - public int B { get; set; } + return obj is Derived derived && + C == derived.C && + B == derived.B && + A == derived.A; } + } + """; - class Derived : Middle - { - public int A { get; set; } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + }.RunAsync(); + } - public override bool Equals(object obj) - { - return obj is Derived derived && - C == derived.C && - B == derived.B && - A == derived.A; - } - } - """; + [Fact] + public async Task TestGenerateOperators1() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestGenerateOperators1() - { - var code = - """ - using System.Collections.Generic; + class Program + { + public string s; - class Program + public override bool Equals(object obj) { - public string s; - [||] + var program = obj as Program; + return !ReferenceEquals(program, null) && + s == program.s; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program + public static bool operator ==(Program left, Program right) { - public string s; + return EqualityComparer.Default.Equals(left, right); + } - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - s == program.s; - } + public static bool operator !=(Program left, Program right) + { + return !(left == right); + } + } + """; - public static bool operator ==(Program left, Program right) - { - return EqualityComparer.Default.Equals(left, right); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public static bool operator !=(Program left, Program right) - { - return !(left == right); - } - } - """; + [Fact] + public async Task TestGenerateOperators2() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - [Fact] - public async Task TestGenerateOperators2() - { - var code = - """ - using System.Collections.Generic; + class Program + { + public string s; - class Program + public override bool Equals(object obj) { - public string s; - [||] + Program program = obj as Program; + return !ReferenceEquals(program, null) && + s == program.s; } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program - { - public string s; + public static bool operator ==(Program left, Program right) => EqualityComparer.Default.Equals(left, right); + public static bool operator !=(Program left, Program right) => !(left == right); + } + """; - public override bool Equals(object obj) - { - Program program = obj as Program; - return !ReferenceEquals(program, null) && - s == program.s; - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), + LanguageVersion = LanguageVersion.CSharp6, + Options = + { + { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement }, + }, + }.RunAsync(); + } - public static bool operator ==(Program left, Program right) => EqualityComparer.Default.Equals(left, right); - public static bool operator !=(Program left, Program right) => !(left == right); - } - """; + [Fact] + public async Task TestGenerateOperators3() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), - LanguageVersion = LanguageVersion.CSharp6, - Options = - { - { CSharpCodeStyleOptions.PreferExpressionBodiedOperators, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement }, - }, - }.RunAsync(); - } - - [Fact] - public async Task TestGenerateOperators3() - { - var code = - """ - using System.Collections.Generic; + public string s; + [||] - class Program - { - public string s; - [||] + public static bool operator {|CS0216:==|}(Program left, Program right) => true; + } + """; + var fixedCode = + """ + using System.Collections.Generic; - public static bool operator {|CS0216:==|}(Program left, Program right) => true; - } - """; - var fixedCode = - """ - using System.Collections.Generic; + class Program + { + public string s; - class Program + public override bool Equals(object obj) { - public string s; - - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - s == program.s; - } - - public static bool operator {|CS0216:==|}(Program left, Program right) => true; + var program = obj as Program; + return !ReferenceEquals(program, null) && + s == program.s; } - """; - await new TestWithDialog - { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => Assert.Null(options.FirstOrDefault(i => i.Id == GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId)), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public static bool operator {|CS0216:==|}(Program left, Program right) => true; + } + """; - [Fact] - public async Task TestGenerateOperators4() + await new TestWithDialog { - var code = - """ - using System.Collections.Generic; - - struct Program - { - public string s; - [||] - } - """; - var fixedCode = - """ - using System.Collections.Generic; + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => Assert.Null(options.FirstOrDefault(i => i.Id == GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId)), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - struct Program - { - public string s; + [Fact] + public async Task TestGenerateOperators4() + { + var code = + """ + using System.Collections.Generic; - public override bool Equals(object obj) - { - if (!(obj is Program)) - { - return false; - } + struct Program + { + public string s; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - var program = (Program)obj; - return s == program.s; - } + struct Program + { + public string s; - public static bool operator ==(Program left, Program right) + public override bool Equals(object obj) + { + if (!(obj is Program)) { - return left.Equals(right); + return false; } - public static bool operator !=(Program left, Program right) - { - return !(left == right); - } + var program = (Program)obj; + return s == program.s; } - """; - - await new TestWithDialog - { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } - [Fact] - public async Task TestGenerateLiftedOperators() - { - var code = - """ - using System; - using System.Collections.Generic; - - class Foo + public static bool operator ==(Program left, Program right) { - [|public bool? BooleanValue { get; } - public decimal? DecimalValue { get; } - public Bar? EnumValue { get; } - public DateTime? DateTimeValue { get; }|] + return left.Equals(right); } - enum Bar + public static bool operator !=(Program left, Program right) { + return !(left == right); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; + } + """; - class Foo - { - public bool? BooleanValue { get; } - public decimal? DecimalValue { get; } - public Bar? EnumValue { get; } - public DateTime? DateTimeValue { get; } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - BooleanValue == foo.BooleanValue && - DecimalValue == foo.DecimalValue && - EnumValue == foo.EnumValue && - DateTimeValue == foo.DateTimeValue; - } - } + [Fact] + public async Task TestGenerateLiftedOperators() + { + var code = + """ + using System; + using System.Collections.Generic; + + class Foo + { + [|public bool? BooleanValue { get; } + public decimal? DecimalValue { get; } + public Bar? EnumValue { get; } + public DateTime? DateTimeValue { get; }|] + } + + enum Bar + { + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - enum Bar + class Foo + { + public bool? BooleanValue { get; } + public decimal? DecimalValue { get; } + public Bar? EnumValue { get; } + public DateTime? DateTimeValue { get; } + + public override bool Equals(object obj) { + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + BooleanValue == foo.BooleanValue && + DecimalValue == foo.DecimalValue && + EnumValue == foo.EnumValue && + DateTimeValue == foo.DateTimeValue; } - """; + } - await new VerifyCS.Test + enum Bar { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 0, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + } + """; - [Fact] - public async Task LiftedOperatorIsNotUsedWhenDirectOperatorWouldNotBeUsed() + await new VerifyCS.Test { - var code = - """ - using System; - using System.Collections.Generic; + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 0, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - class Foo - { - [|public Bar Value { get; } - public Bar? NullableValue { get; }|] - } + [Fact] + public async Task LiftedOperatorIsNotUsedWhenDirectOperatorWouldNotBeUsed() + { + var code = + """ + using System; + using System.Collections.Generic; - struct Bar : IEquatable - { - private readonly int value; + class Foo + { + [|public Bar Value { get; } + public Bar? NullableValue { get; }|] + } - public override bool Equals(object obj) => false; + struct Bar : IEquatable + { + private readonly int value; - public bool Equals(Bar other) => value == other.value; + public override bool Equals(object obj) => false; - public override int GetHashCode() => -1584136870 + value.GetHashCode(); + public bool Equals(Bar other) => value == other.value; - public static bool operator ==(Bar left, Bar right) => left.Equals(right); + public override int GetHashCode() => -1584136870 + value.GetHashCode(); - public static bool operator !=(Bar left, Bar right) => !(left == right); - } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; + public static bool operator ==(Bar left, Bar right) => left.Equals(right); - class Foo - { - public Bar Value { get; } - public Bar? NullableValue { get; } + public static bool operator !=(Bar left, Bar right) => !(left == right); + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - public override bool Equals(object obj) - { - var foo = obj as Foo; - return !ReferenceEquals(foo, null) && - Value.Equals(foo.Value) && - EqualityComparer.Default.Equals(NullableValue, foo.NullableValue); - } - } + class Foo + { + public Bar Value { get; } + public Bar? NullableValue { get; } - struct Bar : IEquatable + public override bool Equals(object obj) { - private readonly int value; + var foo = obj as Foo; + return !ReferenceEquals(foo, null) && + Value.Equals(foo.Value) && + EqualityComparer.Default.Equals(NullableValue, foo.NullableValue); + } + } - public override bool Equals(object obj) => false; + struct Bar : IEquatable + { + private readonly int value; - public bool Equals(Bar other) => value == other.value; + public override bool Equals(object obj) => false; - public override int GetHashCode() => -1584136870 + value.GetHashCode(); + public bool Equals(Bar other) => value == other.value; - public static bool operator ==(Bar left, Bar right) => left.Equals(right); + public override int GetHashCode() => -1584136870 + value.GetHashCode(); - public static bool operator !=(Bar left, Bar right) => !(left == right); - } - """; + public static bool operator ==(Bar left, Bar right) => left.Equals(right); - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 0, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public static bool operator !=(Bar left, Bar right) => !(left == right); + } + """; - [Fact] - public async Task TestImplementIEquatableOnStruct() + await new VerifyCS.Test { - var code = - """ - using System.Collections.Generic; - - struct Program - { - public string s; - [||] - } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - - struct Program : IEquatable - { - public string s; + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 0, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public override bool Equals(object obj) - { - return obj is Program && Equals((Program)obj); - } + [Fact] + public async Task TestImplementIEquatableOnStruct() + { + var code = + """ + using System.Collections.Generic; - public bool Equals(Program other) - { - return s == other.s; - } - } - """; + struct Program + { + public string s; + [||] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - await new TestWithDialog + struct Program : IEquatable { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25708")] - public async Task TestOverrideEqualsOnRefStructReturnsFalse() - { - var code = - """ - ref struct Program + public override bool Equals(object obj) { - public string s; - [||] + return obj is Program && Equals((Program)obj); } - """; - var fixedCode = - """ - ref struct Program - { - public string s; - public override bool Equals(object obj) - { - return false; - } + public bool Equals(Program other) + { + return s == other.s; } - """; + } + """; + + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - await new TestWithDialog + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25708")] + public async Task TestOverrideEqualsOnRefStructReturnsFalse() + { + var code = + """ + ref struct Program { - TestCode = code, - FixedCode = fixedCode, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + ref struct Program + { + public string s; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25708")] - public async Task TestImplementIEquatableOnRefStructSkipsIEquatable() - { - var code = - """ - ref struct Program + public override bool Equals(object obj) { - public string s; - [||] + return false; } - """; - var fixedCode = - """ - ref struct Program - { - public string s; + } + """; - public override bool Equals(object obj) - { - return false; - } - } - """; + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + }.RunAsync(); + } - await new TestWithDialog + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25708")] + public async Task TestImplementIEquatableOnRefStructSkipsIEquatable() + { + var code = + """ + ref struct Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - // We are forcefully enabling the ImplementIEquatable option, as that is our way - // to test that the option does nothing. The VS mode will ensure if the option - // is not available it will not be shown. - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - }.RunAsync(); - } - - [Fact] - public async Task TestImplementIEquatableOnStructInNullableContextWithUnannotatedMetadata() - { - var code = - """ - #nullable enable + public string s; + [||] + } + """; + var fixedCode = + """ + ref struct Program + { + public string s; - struct Foo + public override bool Equals(object obj) { - public int Bar { get; } - [||] + return false; } - """; - var fixedCode = - """ - #nullable enable - - using System; - - struct Foo : IEquatable - { - public int Bar { get; } + } + """; - public override bool Equals(object? obj) - { - return obj is Foo foo && Equals(foo); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + // We are forcefully enabling the ImplementIEquatable option, as that is our way + // to test that the option does nothing. The VS mode will ensure if the option + // is not available it will not be shown. + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + }.RunAsync(); + } - public bool Equals(Foo other) - { - return Bar == other.Bar; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnStructInNullableContextWithUnannotatedMetadata() + { + var code = + """ + #nullable enable - await new TestWithDialog + struct Foo { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + public int Bar { get; } + [||] + } + """; + var fixedCode = + """ + #nullable enable - [Fact] - public async Task TestImplementIEquatableOnStructInNullableContextWithAnnotatedMetadata() - { - var code = - """ - #nullable enable + using System; - using System; - using System.Diagnostics.CodeAnalysis; + struct Foo : IEquatable + { + public int Bar { get; } - struct Foo + public override bool Equals(object? obj) { - public bool Bar { get; } - [||] + return obj is Foo foo && Equals(foo); } - """; - var fixedCode = - """ - #nullable enable - - using System; - using System.Diagnostics.CodeAnalysis; - struct Foo : IEquatable + public bool Equals(Foo other) { - public bool Bar { get; } + return Bar == other.Bar; + } + } + """; - public override bool Equals(object? obj) - { - return obj is Foo foo && Equals(foo); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - public bool Equals(Foo other) - { - return Bar == other.Bar; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnStructInNullableContextWithAnnotatedMetadata() + { + var code = + """ + #nullable enable - await new TestWithDialog + using System; + using System.Diagnostics.CodeAnalysis; + + struct Foo { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + public bool Bar { get; } + [||] + } + """; + var fixedCode = + """ + #nullable enable - [Fact] - public async Task TestImplementIEquatableOnClass_CSharp6() - { - var code = - """ - using System.Collections.Generic; + using System; + using System.Diagnostics.CodeAnalysis; + + struct Foo : IEquatable + { + public bool Bar { get; } - class Program + public override bool Equals(object? obj) { - public string s; - [||] + return obj is Foo foo && Equals(foo); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - class Program : IEquatable + public bool Equals(Foo other) { - public string s; + return Bar == other.Bar; + } + } + """; - public override bool Equals(object obj) - { - return Equals(obj as Program); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - public bool Equals(Program other) - { - return !ReferenceEquals(other, null) && - s == other.s; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnClass_CSharp6() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestImplementIEquatableOnClass_CSharp7() - { - var code = - """ - using System.Collections.Generic; + class Program : IEquatable + { + public string s; - class Program + public override bool Equals(object obj) { - public string s; - [||] + return Equals(obj as Program); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - class Program : IEquatable + public bool Equals(Program other) { - public string s; + return !ReferenceEquals(other, null) && + s == other.s; + } + } + """; - public override bool Equals(object obj) - { - return Equals(obj as Program); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public bool Equals(Program other) - { - return !(other is null) && - s == other.s; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnClass_CSharp7() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp7, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestImplementIEquatableOnClass_CSharp8() - { - var code = - """ - using System.Collections.Generic; + class Program : IEquatable + { + public string s; - class Program + public override bool Equals(object obj) { - public string s; - [||] + return Equals(obj as Program); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - class Program : IEquatable + public bool Equals(Program other) { - public string s; + return !(other is null) && + s == other.s; + } + } + """; - public override bool Equals(object obj) - { - return Equals(obj as Program); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp7, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public bool Equals(Program other) - { - return !(other is null) && - s == other.s; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnClass_CSharp8() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp8, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestImplementIEquatableOnClass_CSharp9() - { - var code = - """ - using System.Collections.Generic; + class Program : IEquatable + { + public string s; - class Program + public override bool Equals(object obj) { - public string s; - [||] + return Equals(obj as Program); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - class Program : IEquatable + public bool Equals(Program other) { - public string s; + return !(other is null) && + s == other.s; + } + } + """; - public override bool Equals(object obj) - { - return Equals(obj as Program); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp8, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public bool Equals(Program other) - { - return other is not null && - s == other.s; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnClass_CSharp9() + { + var code = + """ + using System.Collections.Generic; - await new TestWithDialog + class Program { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp9, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; - [Fact] - public async Task TestImplementIEquatableOnClassInNullableContextWithUnannotatedMetadata() - { - var code = - """ - #nullable enable + class Program : IEquatable + { + public string s; - class Foo + public override bool Equals(object obj) { - public int Bar { get; } - [||] + return Equals(obj as Program); } - """; - var fixedCode = - """ - #nullable enable - - using System; - class Foo : IEquatable + public bool Equals(Program other) { - public int Bar { get; } + return other is not null && + s == other.s; + } + } + """; - public override bool Equals(object? obj) - { - return Equals(obj as Foo); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp9, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public bool Equals(Foo? other) - { - return !(other is null) && - Bar == other.Bar; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnClassInNullableContextWithUnannotatedMetadata() + { + var code = + """ + #nullable enable - await new TestWithDialog + class Foo { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + public int Bar { get; } + [||] + } + """; + var fixedCode = + """ + #nullable enable - [Fact] - public async Task TestImplementIEquatableOnClassInNullableContextWithAnnotatedMetadata() - { - var code = - """ - #nullable enable + using System; - using System; - using System.Diagnostics.CodeAnalysis; + class Foo : IEquatable + { + public int Bar { get; } - class Foo + public override bool Equals(object? obj) { - public bool Bar { get; } - [||] + return Equals(obj as Foo); } - """; - var fixedCode = - """ - #nullable enable - using System; - using System.Diagnostics.CodeAnalysis; - - class Foo : IEquatable + public bool Equals(Foo? other) { - public bool Bar { get; } + return !(other is null) && + Bar == other.Bar; + } + } + """; - public override bool Equals(object? obj) - { - return Equals(obj as Foo); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } - public bool Equals(Foo? other) - { - return !(other is null) && - Bar == other.Bar; - } - } - """; + [Fact] + public async Task TestImplementIEquatableOnClassInNullableContextWithAnnotatedMetadata() + { + var code = + """ + #nullable enable + + using System; + using System.Diagnostics.CodeAnalysis; - await new TestWithDialog + class Foo { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), - LanguageVersion = LanguageVersion.CSharp8, - }.RunAsync(); - } + public bool Bar { get; } + [||] + } + """; + var fixedCode = + """ + #nullable enable - [Fact] - public async Task TestDoNotOfferIEquatableIfTypeAlreadyImplementsIt() - { - var code = - """ - using System.Collections.Generic; + using System; + using System.Diagnostics.CodeAnalysis; - class Program : {|CS0535:System.IEquatable|} + class Foo : IEquatable + { + public bool Bar { get; } + + public override bool Equals(object? obj) { - public string s; - [||] + return Equals(obj as Foo); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Program : {|CS0535:System.IEquatable|} + public bool Equals(Foo? other) { - public string s; - - public override bool Equals(object obj) - { - var program = obj as Program; - return !ReferenceEquals(program, null) && - s == program.s; - } + return !(other is null) && + Bar == other.Bar; } - """; + } + """; - await new TestWithDialog + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId), + LanguageVersion = LanguageVersion.CSharp8, + }.RunAsync(); + } + + [Fact] + public async Task TestDoNotOfferIEquatableIfTypeAlreadyImplementsIt() + { + var code = + """ + using System.Collections.Generic; + + class Program : {|CS0535:System.IEquatable|} { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => Assert.Null(options.FirstOrDefault(i => i.Id == GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId)), - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + public string s; + [||] + } + """; + var fixedCode = + """ + using System.Collections.Generic; + + class Program : {|CS0535:System.IEquatable|} + { + public string s; + + public override bool Equals(object obj) + { + var program = obj as Program; + return !ReferenceEquals(program, null) && + s == program.s; + } + } + """; + + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => Assert.Null(options.FirstOrDefault(i => i.Id == GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId)), + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact] - public async Task TestMissingReferences1() + [Fact] + public async Task TestMissingReferences1() + { + await new VerifyCS.Test { - await new VerifyCS.Test + LanguageVersion = LanguageVersion.CSharp6, + CodeActionIndex = 1, + TestState = { - LanguageVersion = LanguageVersion.CSharp6, - CodeActionIndex = 1, - TestState = + Sources = { - Sources = + """ + public class Class1 { - """ - public class Class1 - { - [|int i;|] + [|int i;|] - public void F() - { - } + public void F() + { } - """, - }, - ExpectedDiagnostics = - { - // /0/Test0.cs(1,14): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(1, 14, 1, 20).WithArguments("System.Object"), - // /0/Test0.cs(1,14): error CS1729: 'object' does not contain a constructor that takes 0 arguments - DiagnosticResult.CompilerError("CS1729").WithSpan(1, 14, 1, 20).WithArguments("object", "0"), - // /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Int32' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(3, 5, 3, 8).WithArguments("System.Int32"), - // /0/Test0.cs(5,12): error CS0518: Predefined type 'System.Void' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(5, 12, 5, 16).WithArguments("System.Void"), - }, + } + """, }, - FixedState = - { - Sources = { - """ - public class Class1 + ExpectedDiagnostics = + { +// /0/Test0.cs(1,14): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(1, 14, 1, 20).WithArguments("System.Object"), +// /0/Test0.cs(1,14): error CS1729: 'object' does not contain a constructor that takes 0 arguments +DiagnosticResult.CompilerError("CS1729").WithSpan(1, 14, 1, 20).WithArguments("object", "0"), +// /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Int32' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(3, 5, 3, 8).WithArguments("System.Int32"), +// /0/Test0.cs(5,12): error CS0518: Predefined type 'System.Void' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(5, 12, 5, 16).WithArguments("System.Void"), + }, + }, + FixedState = + { + Sources = { + """ + public class Class1 + { + int i; + + public override System.Boolean Equals(System.Object obj) { - int i; - - public override System.Boolean Equals(System.Object obj) - { - Class1 @class = obj as Class1; - return !ReferenceEquals(@class, null) && - i == @class.i; - } - - public void F() - { - } - - public override System.Int32 GetHashCode() - { - return 165851236 + EqualityComparer.Default.GetHashCode(i); - } + Class1 @class = obj as Class1; + return !ReferenceEquals(@class, null) && + i == @class.i; } - """, - }, - ExpectedDiagnostics = - { - // /0/Test0.cs(1,14): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(1, 14, 1, 20).WithArguments("System.Object"), - // /0/Test0.cs(1,14): error CS1729: 'object' does not contain a constructor that takes 0 arguments - DiagnosticResult.CompilerError("CS1729").WithSpan(1, 14, 1, 20).WithArguments("object", "0"), - // /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Int32' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(3, 5, 3, 8).WithArguments("System.Int32"), - // /0/Test0.cs(5,21): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(5, 21, 5, 27).WithArguments("System.Object"), - // /0/Test0.cs(5,28): error CS1069: The type name 'Boolean' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. - DiagnosticResult.CompilerError("CS1069").WithSpan(5, 28, 5, 35).WithArguments("Boolean", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), - // /0/Test0.cs(5,43): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(5, 43, 5, 49).WithArguments("System.Object"), - // /0/Test0.cs(5,50): error CS1069: The type name 'Object' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. - DiagnosticResult.CompilerError("CS1069").WithSpan(5, 50, 5, 56).WithArguments("Object", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), - // /0/Test0.cs(7,9): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(7, 9, 7, 15).WithArguments("System.Object"), - // /0/Test0.cs(7,32): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(7, 32, 7, 38).WithArguments("System.Object"), - // /0/Test0.cs(8,17): error CS0103: The name 'ReferenceEquals' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(8, 17, 8, 32).WithArguments("ReferenceEquals"), - // /0/Test0.cs(8,17): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(8, 17, 8, 32).WithArguments("System.Object"), - // /0/Test0.cs(9,16): error CS0518: Predefined type 'System.Boolean' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(9, 16, 9, 29).WithArguments("System.Boolean"), - // /0/Test0.cs(12,12): error CS0518: Predefined type 'System.Void' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(12, 12, 12, 16).WithArguments("System.Void"), - // /0/Test0.cs(16,21): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(16, 21, 16, 27).WithArguments("System.Object"), - // /0/Test0.cs(16,28): error CS1069: The type name 'Int32' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. - DiagnosticResult.CompilerError("CS1069").WithSpan(16, 28, 16, 33).WithArguments("Int32", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), - // /0/Test0.cs(18,16): error CS0518: Predefined type 'System.Int32' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(18, 16, 18, 25).WithArguments("System.Int32"), - // /0/Test0.cs(18,28): error CS0103: The name 'EqualityComparer' does not exist in the current context - DiagnosticResult.CompilerError("CS0103").WithSpan(18, 28, 18, 58).WithArguments("EqualityComparer"), - // /0/Test0.cs(18,28): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(18, 28, 18, 58).WithArguments("System.Object"), - // /0/Test0.cs(18,45): error CS0518: Predefined type 'System.Object' is not defined or imported - DiagnosticResult.CompilerError("CS0518").WithSpan(18, 45, 18, 51).WithArguments("System.Object"), - // /0/Test0.cs(18,52): error CS1069: The type name 'Int32' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. - DiagnosticResult.CompilerError("CS1069").WithSpan(18, 52, 18, 57).WithArguments("Int32", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), - }, + + public void F() + { + } + + public override System.Int32 GetHashCode() + { + return 165851236 + EqualityComparer.Default.GetHashCode(i); + } + } + """, }, - ReferenceAssemblies = ReferenceAssemblies.Default.WithAssemblies(ImmutableArray.Empty), - }.RunAsync(); - } + ExpectedDiagnostics = + { +// /0/Test0.cs(1,14): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(1, 14, 1, 20).WithArguments("System.Object"), +// /0/Test0.cs(1,14): error CS1729: 'object' does not contain a constructor that takes 0 arguments +DiagnosticResult.CompilerError("CS1729").WithSpan(1, 14, 1, 20).WithArguments("object", "0"), +// /0/Test0.cs(3,5): error CS0518: Predefined type 'System.Int32' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(3, 5, 3, 8).WithArguments("System.Int32"), +// /0/Test0.cs(5,21): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(5, 21, 5, 27).WithArguments("System.Object"), +// /0/Test0.cs(5,28): error CS1069: The type name 'Boolean' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. +DiagnosticResult.CompilerError("CS1069").WithSpan(5, 28, 5, 35).WithArguments("Boolean", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), +// /0/Test0.cs(5,43): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(5, 43, 5, 49).WithArguments("System.Object"), +// /0/Test0.cs(5,50): error CS1069: The type name 'Object' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. +DiagnosticResult.CompilerError("CS1069").WithSpan(5, 50, 5, 56).WithArguments("Object", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), +// /0/Test0.cs(7,9): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(7, 9, 7, 15).WithArguments("System.Object"), +// /0/Test0.cs(7,32): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(7, 32, 7, 38).WithArguments("System.Object"), +// /0/Test0.cs(8,17): error CS0103: The name 'ReferenceEquals' does not exist in the current context +DiagnosticResult.CompilerError("CS0103").WithSpan(8, 17, 8, 32).WithArguments("ReferenceEquals"), +// /0/Test0.cs(8,17): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(8, 17, 8, 32).WithArguments("System.Object"), +// /0/Test0.cs(9,16): error CS0518: Predefined type 'System.Boolean' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(9, 16, 9, 29).WithArguments("System.Boolean"), +// /0/Test0.cs(12,12): error CS0518: Predefined type 'System.Void' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(12, 12, 12, 16).WithArguments("System.Void"), +// /0/Test0.cs(16,21): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(16, 21, 16, 27).WithArguments("System.Object"), +// /0/Test0.cs(16,28): error CS1069: The type name 'Int32' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. +DiagnosticResult.CompilerError("CS1069").WithSpan(16, 28, 16, 33).WithArguments("Int32", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), +// /0/Test0.cs(18,16): error CS0518: Predefined type 'System.Int32' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(18, 16, 18, 25).WithArguments("System.Int32"), +// /0/Test0.cs(18,28): error CS0103: The name 'EqualityComparer' does not exist in the current context +DiagnosticResult.CompilerError("CS0103").WithSpan(18, 28, 18, 58).WithArguments("EqualityComparer"), +// /0/Test0.cs(18,28): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(18, 28, 18, 58).WithArguments("System.Object"), +// /0/Test0.cs(18,45): error CS0518: Predefined type 'System.Object' is not defined or imported +DiagnosticResult.CompilerError("CS0518").WithSpan(18, 45, 18, 51).WithArguments("System.Object"), +// /0/Test0.cs(18,52): error CS1069: The type name 'Int32' could not be found in the namespace 'System'. This type has been forwarded to assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' Consider adding a reference to that assembly. +DiagnosticResult.CompilerError("CS1069").WithSpan(18, 52, 18, 57).WithArguments("Int32", "System", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), + }, + }, + ReferenceAssemblies = ReferenceAssemblies.Default.WithAssemblies(ImmutableArray.Empty), + }.RunAsync(); + } - [Fact] - public async Task TestGetHashCodeInCheckedContext() - { - var code = - """ - using System.Collections.Generic; + [Fact] + public async Task TestGetHashCodeInCheckedContext() + { + var code = + """ + using System.Collections.Generic; - class Program - { - [|int i; + class Program + { + [|int i; - string S { get; }|] - } - """; - var fixedCode = - """ - using System.Collections.Generic; + string S { get; }|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; - class Program - { - int i; + class Program + { + int i; - string S { get; } + string S { get; } - public override bool Equals(object obj) - { - Program program = obj as Program; - return !ReferenceEquals(program, null) && - i == program.i && - S == program.S; - } + public override bool Equals(object obj) + { + Program program = obj as Program; + return !ReferenceEquals(program, null) && + i == program.i && + S == program.S; + } - public override int GetHashCode() + public override int GetHashCode() + { + unchecked { - unchecked - { - int hashCode = -538000506; - hashCode = hashCode * -1521134295 + i.GetHashCode(); - hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); - return hashCode; - } + int hashCode = -538000506; + hashCode = hashCode * -1521134295 + i.GetHashCode(); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(S); + return hashCode; } } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + SolutionTransforms = { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - SolutionTransforms = + (solution, projectId) => { - (solution, projectId) => - { - var compilationOptions = solution.GetRequiredProject(projectId).CompilationOptions; - return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithOverflowChecks(true)); - }, + var compilationOptions = solution.GetRequiredProject(projectId).CompilationOptions; + return solution.WithProjectCompilationOptions(projectId, compilationOptions.WithOverflowChecks(true)); }, - }.RunAsync(); - } + }, + }.RunAsync(); + } - [Fact] - public async Task TestGetHashCodeStruct() - { - var code = - """ - using System.Collections.Generic; + [Fact] + public async Task TestGetHashCodeStruct() + { + var code = + """ + using System.Collections.Generic; + + struct S + { + [|int j;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; + + struct S : IEquatable + { + int j; - struct S + public override bool Equals(object obj) { - [|int j;|] + return obj is S && Equals((S)obj); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - struct S : IEquatable + public bool Equals(S other) { - int j; + return j == other.j; + } - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } + public override int GetHashCode() + { + return 1424088837 + j.GetHashCode(); + } - public bool Equals(S other) - { - return j == other.j; - } + public static bool operator ==(S left, S right) + { + return left.Equals(right); + } - public override int GetHashCode() - { - return 1424088837 + j.GetHashCode(); - } + public static bool operator !=(S left, S right) + { + return !(left == right); + } + } + """; - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - public static bool operator !=(S left, S right) - { - return !(left == right); - } - } - """; + [Fact] + public async Task TestGetHashCodeSystemHashCodeOneMember() + { + var code = + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } - await new VerifyCS.Test + struct S { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } - - [Fact] - public async Task TestGetHashCodeSystemHashCodeOneMember() - { - var code = - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + [|int j;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + struct S : IEquatable + { + int j; - struct S + public override bool Equals(object obj) { - [|int j;|] + return obj is S && Equals((S)obj); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - namespace System { public struct HashCode { } } - struct S : IEquatable + public bool Equals(S other) { - int j; - - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } - - public bool Equals(S other) - { - return j == other.j; - } + return j == other.j; + } - public override int GetHashCode() - { - return HashCode.Combine(j); - } + public override int GetHashCode() + { + return HashCode.Combine(j); + } - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } + public static bool operator ==(S left, S right) + { + return left.Equals(right); + } - public static bool operator !=(S left, S right) - { - return !(left == right); - } + public static bool operator !=(S left, S right) + { + return !(left == right); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = code, + FixedState = { - TestCode = code, - FixedState = + Sources = { fixedCode }, + ExpectedDiagnostics = { - Sources = { fixedCode }, - ExpectedDiagnostics = - { - // /0/Test0.cs(21,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' - DiagnosticResult.CompilerError("CS0117").WithSpan(21, 25, 21, 32).WithArguments("System.HashCode", "Combine"), - }, + // /0/Test0.cs(21,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' + DiagnosticResult.CompilerError("CS0117").WithSpan(21, 25, 21, 32).WithArguments("System.HashCode", "Combine"), }, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + }, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37297")] - public async Task TestPublicSystemHashCodeOtherProject() - { - var publicHashCode = - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } - """; - var code = - """ - struct S + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37297")] + public async Task TestPublicSystemHashCodeOtherProject() + { + var publicHashCode = + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + """; + var code = + """ + struct S + { + [|int j;|] + } + """; + var fixedCode = + """ + using System; + + struct S : IEquatable + { + int j; + + public override bool Equals(object obj) { - [|int j;|] + return obj is S && Equals((S)obj); } - """; - var fixedCode = - """ - using System; - struct S : IEquatable + public bool Equals(S other) { - int j; - - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } - - public bool Equals(S other) - { - return j == other.j; - } + return j == other.j; + } - public override int GetHashCode() - { - return HashCode.Combine(j); - } + public override int GetHashCode() + { + return HashCode.Combine(j); + } - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } + public static bool operator ==(S left, S right) + { + return left.Equals(right); + } - public static bool operator !=(S left, S right) - { - return !(left == right); - } + public static bool operator !=(S left, S right) + { + return !(left == right); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestState = { - TestState = + AdditionalProjects = { - AdditionalProjects = + ["P1"] = { - ["P1"] = - { - Sources = { ("HashCode.cs", publicHashCode) }, - }, + Sources = { ("HashCode.cs", publicHashCode) }, }, - Sources = { code }, - AdditionalProjectReferences = { "P1" }, }, - FixedState = + Sources = { code }, + AdditionalProjectReferences = { "P1" }, + }, + FixedState = + { + Sources = { fixedCode }, + ExpectedDiagnostics = { - Sources = { fixedCode }, - ExpectedDiagnostics = - { - // /0/Test0.cs(19,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' - DiagnosticResult.CompilerError("CS0117").WithSpan(19, 25, 19, 32).WithArguments("System.HashCode", "Combine"), - }, + // /0/Test0.cs(19,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' + DiagnosticResult.CompilerError("CS0117").WithSpan(19, 25, 19, 32).WithArguments("System.HashCode", "Combine"), }, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + }, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37297")] - public async Task TestInternalSystemHashCode() - { - var internalHashCode = - """ - using System.Collections.Generic; - namespace System { internal struct HashCode { } } - """; - var code = - """ - struct S + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37297")] + public async Task TestInternalSystemHashCode() + { + var internalHashCode = + """ + using System.Collections.Generic; + namespace System { internal struct HashCode { } } + """; + var code = + """ + struct S + { + [|int j;|] + } + """; + var fixedCode = + """ + using System; + + struct S : IEquatable + { + int j; + + public override bool Equals(object obj) { - [|int j;|] + return obj is S && Equals((S)obj); } - """; - var fixedCode = - """ - using System; - struct S : IEquatable + public bool Equals(S other) { - int j; - - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } - - public bool Equals(S other) - { - return j == other.j; - } - - public override int GetHashCode() - { - return 1424088837 + j.GetHashCode(); - } - - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } - - public static bool operator !=(S left, S right) - { - return !(left == right); - } + return j == other.j; } - """; - await new VerifyCS.Test - { - TestState = + public override int GetHashCode() { - AdditionalProjects = - { - ["P1"] = - { - Sources = { ("HashCode.cs", internalHashCode) }, - }, - }, - Sources = { code }, - AdditionalProjectReferences = { "P1" }, - }, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } - - [Fact] - public async Task TestGetHashCodeSystemHashCodeEightMembers() - { - var code = - """ - using System.Collections.Generic; - namespace System { public struct HashCode { } } + return 1424088837 + j.GetHashCode(); + } - struct S + public static bool operator ==(S left, S right) { - [|int j, k, l, m, n, o, p, q;|] + return left.Equals(right); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - namespace System { public struct HashCode { } } - struct S : IEquatable + public static bool operator !=(S left, S right) { - int j, k, l, m, n, o, p, q; - - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } - - public bool Equals(S other) - { - return j == other.j && - k == other.k && - l == other.l && - m == other.m && - n == other.n && - o == other.o && - p == other.p && - q == other.q; - } - - public override int GetHashCode() - { - return HashCode.Combine(j, k, l, m, n, o, p, q); - } - - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } - - public static bool operator !=(S left, S right) - { - return !(left == right); - } + return !(left == right); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestState = { - TestCode = code, - FixedState = + AdditionalProjects = { - Sources = { fixedCode }, - ExpectedDiagnostics = + ["P1"] = { - // /0/Test0.cs(28,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' - DiagnosticResult.CompilerError("CS0117").WithSpan(28, 25, 28, 32).WithArguments("System.HashCode", "Combine"), + Sources = { ("HashCode.cs", internalHashCode) }, }, }, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + Sources = { code }, + AdditionalProjectReferences = { "P1" }, + }, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact] - public async Task TestGetHashCodeSystemHashCodeNineMembers() - { - var code = - """ - using System.Collections.Generic; - namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } + [Fact] + public async Task TestGetHashCodeSystemHashCodeEightMembers() + { + var code = + """ + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + struct S + { + [|int j, k, l, m, n, o, p, q;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; + namespace System { public struct HashCode { } } + + struct S : IEquatable + { + int j, k, l, m, n, o, p, q; - struct S + public override bool Equals(object obj) { - [|int j, k, l, m, n, o, p, q, r;|] + return obj is S && Equals((S)obj); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } - struct S : IEquatable + public bool Equals(S other) { - int j, k, l, m, n, o, p, q, r; - - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } - - public bool Equals(S other) - { - return j == other.j && - k == other.k && - l == other.l && - m == other.m && - n == other.n && - o == other.o && - p == other.p && - q == other.q && - r == other.r; - } + return j == other.j && + k == other.k && + l == other.l && + m == other.m && + n == other.n && + o == other.o && + p == other.p && + q == other.q; + } - public override int GetHashCode() - { - var hash = new HashCode(); - hash.Add(j); - hash.Add(k); - hash.Add(l); - hash.Add(m); - hash.Add(n); - hash.Add(o); - hash.Add(p); - hash.Add(q); - hash.Add(r); - return hash.ToHashCode(); - } + public override int GetHashCode() + { + return HashCode.Combine(j, k, l, m, n, o, p, q); + } - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } + public static bool operator ==(S left, S right) + { + return left.Equals(right); + } - public static bool operator !=(S left, S right) - { - return !(left == right); - } + public static bool operator !=(S left, S right) + { + return !(left == right); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = code, + FixedState = { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + Sources = { fixedCode }, + ExpectedDiagnostics = + { + // /0/Test0.cs(28,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' + DiagnosticResult.CompilerError("CS0117").WithSpan(28, 25, 28, 32).WithArguments("System.HashCode", "Combine"), + }, + }, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] - public async Task TestGetHashCodeSystemHashCodeNineMembers_Explicit() - { - var code = - """ - using System.Collections.Generic; - namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } + [Fact] + public async Task TestGetHashCodeSystemHashCodeNineMembers() + { + var code = + """ + using System.Collections.Generic; + namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } + + struct S + { + [|int j, k, l, m, n, o, p, q, r;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; + namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } + + struct S : IEquatable + { + int j, k, l, m, n, o, p, q, r; - struct S + public override bool Equals(object obj) { - [|int j, k, l, m, n, o, p, q, r;|] + return obj is S && Equals((S)obj); } - """; - var fixedCode = - """ - using System; - using System.Collections.Generic; - namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } - struct S : IEquatable + public bool Equals(S other) { - int j, k, l, m, n, o, p, q, r; - - public override bool Equals(object obj) - { - return obj is S && Equals((S)obj); - } - - public bool Equals(S other) - { - return j == other.j && - k == other.k && - l == other.l && - m == other.m && - n == other.n && - o == other.o && - p == other.p && - q == other.q && - r == other.r; - } - - public override int GetHashCode() - { - HashCode hash = new HashCode(); - hash.Add(j); - hash.Add(k); - hash.Add(l); - hash.Add(m); - hash.Add(n); - hash.Add(o); - hash.Add(p); - hash.Add(q); - hash.Add(r); - return hash.ToHashCode(); - } + return j == other.j && + k == other.k && + l == other.l && + m == other.m && + n == other.n && + o == other.o && + p == other.p && + q == other.q && + r == other.r; + } - public static bool operator ==(S left, S right) - { - return left.Equals(right); - } + public override int GetHashCode() + { + var hash = new HashCode(); + hash.Add(j); + hash.Add(k); + hash.Add(l); + hash.Add(m); + hash.Add(n); + hash.Add(o); + hash.Add(p); + hash.Add(q); + hash.Add(r); + return hash.ToHashCode(); + } - public static bool operator !=(S left, S right) - { - return !(left == right); - } + public static bool operator ==(S left, S right) + { + return left.Equals(right); } - """; - await new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.CSharp6, - Options = { PreferExplicitTypeWithInfo() }, - }.RunAsync(); - } + public static bool operator !=(S left, S right) + { + return !(left == right); + } + } + """; - [Fact] - public async Task TestEqualsSingleField_Patterns() + await new VerifyCS.Test { - await VerifyCS.VerifyRefactoringAsync( - """ - using System.Collections.Generic; + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39916")] + public async Task TestGetHashCodeSystemHashCodeNineMembers_Explicit() + { + var code = + """ + using System.Collections.Generic; + namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } + + struct S + { + [|int j, k, l, m, n, o, p, q, r;|] + } + """; + var fixedCode = + """ + using System; + using System.Collections.Generic; + namespace System { public struct HashCode { public void Add(T value) { } public int ToHashCode() => 0; } } + + struct S : IEquatable + { + int j, k, l, m, n, o, p, q, r; - class Program + public override bool Equals(object obj) { - [|int a;|] + return obj is S && Equals((S)obj); } - """, - """ - using System.Collections.Generic; - class Program + public bool Equals(S other) { - int a; - - public override bool Equals(object obj) - { - return obj is Program program && - a == program.a; - } + return j == other.j && + k == other.k && + l == other.l && + m == other.m && + n == other.n && + o == other.o && + p == other.p && + q == other.q && + r == other.r; } - """); - } - [Fact] - public async Task TestEqualsSingleFieldInStruct_Patterns() - { - await VerifyCS.VerifyRefactoringAsync( - """ - using System.Collections.Generic; + public override int GetHashCode() + { + HashCode hash = new HashCode(); + hash.Add(j); + hash.Add(k); + hash.Add(l); + hash.Add(m); + hash.Add(n); + hash.Add(o); + hash.Add(p); + hash.Add(q); + hash.Add(r); + return hash.ToHashCode(); + } - struct Program + public static bool operator ==(S left, S right) { - [|int a;|] + return left.Equals(right); } - """, - """ - using System; - using System.Collections.Generic; - struct Program : IEquatable + public static bool operator !=(S left, S right) { - int a; + return !(left == right); + } + } + """; - public override bool Equals(object obj) - { - return obj is Program program && Equals(program); - } + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp6, + Options = { PreferExplicitTypeWithInfo() }, + }.RunAsync(); + } - public bool Equals(Program other) - { - return a == other.a; - } + [Fact] + public async Task TestEqualsSingleField_Patterns() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System.Collections.Generic; - public static bool operator ==(Program left, Program right) - { - return left.Equals(right); - } + class Program + { + [|int a;|] + } + """, + """ + using System.Collections.Generic; - public static bool operator !=(Program left, Program right) - { - return !(left == right); - } + class Program + { + int a; + + public override bool Equals(object obj) + { + return obj is Program program && + a == program.a; } - """); - } + } + """); + } - [Fact] - public async Task TestEqualsBaseWithOverriddenEquals_Patterns() - { - var code = - """ - using System.Collections.Generic; + [Fact] + public async Task TestEqualsSingleFieldInStruct_Patterns() + { + await VerifyCS.VerifyRefactoringAsync( + """ + using System.Collections.Generic; + + struct Program + { + [|int a;|] + } + """, + """ + using System; + using System.Collections.Generic; + + struct Program : IEquatable + { + int a; - class Base + public override bool Equals(object obj) { - public override bool Equals(object o) - { - return false; - } + return obj is Program program && Equals(program); } - class Program : Base + public bool Equals(Program other) { - [|int i; + return a == other.a; + } - string S { get; }|] + public static bool operator ==(Program left, Program right) + { + return left.Equals(right); } - """; - var fixedCode = - """ - using System.Collections.Generic; - class Base + public static bool operator !=(Program left, Program right) { - public override bool Equals(object o) - { - return false; - } + return !(left == right); } + } + """); + } + + [Fact] + public async Task TestEqualsBaseWithOverriddenEquals_Patterns() + { + var code = + """ + using System.Collections.Generic; - class Program : Base + class Base + { + public override bool Equals(object o) { - int i; + return false; + } + } - string S { get; } + class Program : Base + { + [|int i; - public override bool Equals(object obj) - { - return obj is Program program && - base.Equals(obj) && - i == program.i && - S == program.S; - } + string S { get; }|] + } + """; + var fixedCode = + """ + using System.Collections.Generic; + + class Base + { + public override bool Equals(object o) + { + return false; } - """; + } - await new VerifyCS.Test + class Program : Base { - TestCode = code, - FixedCode = fixedCode, - CodeActionIndex = 0, - }.RunAsync(); - } + int i; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")] - public async Task TestPartialSelection() - { - var code = - """ - using System.Collections.Generic; + string S { get; } - class Program + public override bool Equals(object obj) { - int [|a|]; + return obj is Program program && + base.Equals(obj) && + i == program.i && + S == program.S; } - """; + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + CodeActionIndex = 0, + }.RunAsync(); + } - await new VerifyCS.Test + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33601")] + public async Task TestPartialSelection() + { + var code = + """ + using System.Collections.Generic; + + class Program { - TestCode = code, - FixedCode = code, - }.RunAsync(); - } + int [|a|]; + } + """; - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40053")] - public async Task TestEqualityOperatorsNullableAnnotationWithReferenceType() + await new VerifyCS.Test { - var code = - """ - #nullable enable - using System; + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40053")] + public async Task TestEqualityOperatorsNullableAnnotationWithReferenceType() + { + var code = + """ + #nullable enable + using System; - namespace N + namespace N + { + public class C[||] { - public class C[||] - { - public int X; - } + public int X; } - """; - var fixedCode = - """ - #nullable enable - using System; - using System.Collections.Generic; - - namespace N + } + """; + var fixedCode = + """ + #nullable enable + using System; + using System.Collections.Generic; + + namespace N + { + public class C { - public class C - { - public int X; + public int X; - public override bool Equals(object? obj) - { - return obj is C c && - X == c.X; - } + public override bool Equals(object? obj) + { + return obj is C c && + X == c.X; + } - public static bool operator ==(C? left, C? right) - { - return EqualityComparer.Default.Equals(left, right); - } + public static bool operator ==(C? left, C? right) + { + return EqualityComparer.Default.Equals(left, right); + } - public static bool operator !=(C? left, C? right) - { - return !(left == right); - } + public static bool operator !=(C? left, C? right) + { + return !(left == right); } } - """; + } + """; - await new TestWithDialog + await new TestWithDialog + { + TestCode = code, + FixedState = { - TestCode = code, - FixedState = + Sources = { fixedCode }, + ExpectedDiagnostics = { - Sources = { fixedCode }, - ExpectedDiagnostics = - { - // /0/Test0.cs(20,55): error CS8604: Possible null reference argument for parameter 'x' in 'bool EqualityComparer.Equals(C x, C y)'. - DiagnosticResult.CompilerError("CS8604").WithSpan(19, 55, 19, 59).WithArguments("x", "bool EqualityComparer.Equals(C x, C y)"), - // /0/Test0.cs(20,61): error CS8604: Possible null reference argument for parameter 'y' in 'bool EqualityComparer.Equals(C x, C y)'. - DiagnosticResult.CompilerError("CS8604").WithSpan(19, 61, 19, 66).WithArguments("y", "bool EqualityComparer.Equals(C x, C y)"), - }, + // /0/Test0.cs(20,55): error CS8604: Possible null reference argument for parameter 'x' in 'bool EqualityComparer.Equals(C x, C y)'. + DiagnosticResult.CompilerError("CS8604").WithSpan(19, 55, 19, 59).WithArguments("x", "bool EqualityComparer.Equals(C x, C y)"), + // /0/Test0.cs(20,61): error CS8604: Possible null reference argument for parameter 'y' in 'bool EqualityComparer.Equals(C x, C y)'. + DiagnosticResult.CompilerError("CS8604").WithSpan(19, 61, 19, 66).WithArguments("y", "bool EqualityComparer.Equals(C x, C y)"), }, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), - LanguageVersion = LanguageVersion.Default, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + }, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), + LanguageVersion = LanguageVersion.Default, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40053")] - public async Task TestEqualityOperatorsNullableAnnotationWithValueType() - { - var code = - """ - #nullable enable - using System; + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40053")] + public async Task TestEqualityOperatorsNullableAnnotationWithValueType() + { + var code = + """ + #nullable enable + using System; - namespace N + namespace N + { + public struct C[||] { - public struct C[||] - { - public int X; - } + public int X; } - """; - var fixedCode = - """ - #nullable enable - using System; + } + """; + var fixedCode = + """ + #nullable enable + using System; - namespace N + namespace N + { + public struct C { - public struct C - { - public int X; + public int X; - public override bool Equals(object? obj) - { - return obj is C c && - X == c.X; - } + public override bool Equals(object? obj) + { + return obj is C c && + X == c.X; + } - public static bool operator ==(C left, C right) - { - return left.Equals(right); - } + public static bool operator ==(C left, C right) + { + return left.Equals(right); + } - public static bool operator !=(C left, C right) - { - return !(left == right); - } + public static bool operator !=(C left, C right) + { + return !(left == right); } } - """; + } + """; - await new TestWithDialog - { - TestCode = code, - FixedCode = fixedCode, - MemberNames = default, - OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), - LanguageVersion = LanguageVersion.Default, - Options = { PreferImplicitTypeWithInfo() }, - }.RunAsync(); - } + await new TestWithDialog + { + TestCode = code, + FixedCode = fixedCode, + MemberNames = default, + OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId), + LanguageVersion = LanguageVersion.Default, + Options = { PreferImplicitTypeWithInfo() }, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] - public async Task TestPartialTypes1() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] + public async Task TestPartialTypes1() + { + await new TestWithDialog { - await new TestWithDialog + TestState = { - TestState = + Sources = { - Sources = + """ + partial class Goo + { + int bar; + [||] + } + """, + """ + partial class Goo { - """ - partial class Goo - { - int bar; - [||] - } - """, - """ - partial class Goo - { - } - """, - }, + } + """, }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo + int bar; + + public override bool Equals(object obj) { - int bar; - - public override bool Equals(object obj) - { - return obj is Goo goo && - bar == goo.bar; - } - - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } + return obj is Goo goo && + bar == goo.bar; } - """, - """ - partial class Goo + + public override int GetHashCode() { + return 999205674 + bar.GetHashCode(); + } + } + """, + """ + partial class Goo + { - } - """, - }, + } + """, }, - MemberNames = ImmutableArray.Create("bar"), - CodeActionIndex = 1, - }.RunAsync(); - } + }, + MemberNames = ImmutableArray.Create("bar"), + CodeActionIndex = 1, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] - public async Task TestPartialTypes2() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] + public async Task TestPartialTypes2() + { + await new TestWithDialog { - await new TestWithDialog + TestState = { - TestState = + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo - { - int bar; + int bar; - } - """, - """ - partial class Goo - { + } + """, + """ + partial class Goo + { - [||] - } - """, - }, + [||] + } + """, }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo - { - int bar; + int bar; + } + """, + """ + partial class Goo + { + public override bool Equals(object obj) + { + return obj is Goo goo && + bar == goo.bar; } - """, - """ - partial class Goo + + public override int GetHashCode() { - public override bool Equals(object obj) - { - return obj is Goo goo && - bar == goo.bar; - } - - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } + return 999205674 + bar.GetHashCode(); } - """, - }, + } + """, }, - MemberNames = ImmutableArray.Create("bar"), - CodeActionIndex = 1, - }.RunAsync(); - } + }, + MemberNames = ImmutableArray.Create("bar"), + CodeActionIndex = 1, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] - public async Task TestPartialTypes3() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] + public async Task TestPartialTypes3() + { + await new TestWithDialog { - await new TestWithDialog + TestState = { - TestState = + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo - { - [||] - } - """, - """ - partial class Goo - { - int bar; + [||] + } + """, + """ + partial class Goo + { + int bar; - } - """, - }, + } + """, }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo + public override bool Equals(object obj) { - public override bool Equals(object obj) - { - return obj is Goo goo && - bar == goo.bar; - } - - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } + return obj is Goo goo && + bar == goo.bar; } - """, - """ - partial class Goo - { - int bar; + public override int GetHashCode() + { + return 999205674 + bar.GetHashCode(); } - """, - }, + } + """, + """ + partial class Goo + { + int bar; + + } + """, }, - MemberNames = ImmutableArray.Create("bar"), - CodeActionIndex = 1, - }.RunAsync(); - } + }, + MemberNames = ImmutableArray.Create("bar"), + CodeActionIndex = 1, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] - public async Task TestPartialTypes4() + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/42574")] + public async Task TestPartialTypes4() + { + await new TestWithDialog { - await new TestWithDialog + TestState = { - TestState = + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo - { - } - """, - """ - partial class Goo - { - int bar; - [||] - } - """, - }, + } + """, + """ + partial class Goo + { + int bar; + [||] + } + """, }, - FixedState = + }, + FixedState = + { + Sources = { - Sources = + """ + partial class Goo { - """ - partial class Goo - { + } + """, + """ + partial class Goo + { + int bar; + + public override bool Equals(object obj) + { + return obj is Goo goo && + bar == goo.bar; } - """, - """ - partial class Goo + + public override int GetHashCode() { - int bar; - - public override bool Equals(object obj) - { - return obj is Goo goo && - bar == goo.bar; - } - - public override int GetHashCode() - { - return 999205674 + bar.GetHashCode(); - } + return 999205674 + bar.GetHashCode(); } - """, - }, + } + """, }, - MemberNames = ImmutableArray.Create("bar"), - CodeActionIndex = 1, - }.RunAsync(); - } + }, + MemberNames = ImmutableArray.Create("bar"), + CodeActionIndex = 1, + }.RunAsync(); + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43290")] - public async Task TestAbstractBase() - { - var code = - """ - #nullable enable + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/43290")] + public async Task TestAbstractBase() + { + var code = + """ + #nullable enable - namespace System { public struct HashCode { } } + namespace System { public struct HashCode { } } - abstract class Base - { - public abstract override bool Equals(object? obj); - public abstract override int GetHashCode(); - } + abstract class Base + { + public abstract override bool Equals(object? obj); + public abstract override int GetHashCode(); + } - class {|CS0534:{|CS0534:Derived|}|} : Base - { - [|public int P { get; }|] - } - """; - var fixedCode = - """ - #nullable enable + class {|CS0534:{|CS0534:Derived|}|} : Base + { + [|public int P { get; }|] + } + """; + var fixedCode = + """ + #nullable enable + + using System; - using System; + namespace System { public struct HashCode { } } - namespace System { public struct HashCode { } } + abstract class Base + { + public abstract override bool Equals(object? obj); + public abstract override int GetHashCode(); + } + + class Derived : Base + { + public int P { get; } - abstract class Base + public override bool Equals(object? obj) { - public abstract override bool Equals(object? obj); - public abstract override int GetHashCode(); + return obj is Derived derived && + P == derived.P; } - class Derived : Base + public override int GetHashCode() { - public int P { get; } - - public override bool Equals(object? obj) - { - return obj is Derived derived && - P == derived.P; - } - - public override int GetHashCode() - { - return HashCode.Combine(P); - } + return HashCode.Combine(P); } - """; + } + """; - await new VerifyCS.Test + await new VerifyCS.Test + { + TestCode = code, + FixedState = { - TestCode = code, - FixedState = + Sources = { fixedCode }, + ExpectedDiagnostics = { - Sources = { fixedCode }, - ExpectedDiagnostics = - { - // /0/Test0.cs(23,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' - DiagnosticResult.CompilerError("CS0117").WithSpan(25, 25, 25, 32).WithArguments("System.HashCode", "Combine"), - }, + // /0/Test0.cs(23,25): error CS0117: 'HashCode' does not contain a definition for 'Combine' + DiagnosticResult.CompilerError("CS0117").WithSpan(25, 25, 25, 32).WithArguments("System.HashCode", "Combine"), }, - CodeActionIndex = 1, - LanguageVersion = LanguageVersion.Default, - }.RunAsync(); - } + }, + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.Default, + }.RunAsync(); } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs index f85aa3e51ee17..04d8bec81e4ea 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/GenerateType/GenerateTypeTests.cs @@ -14,41 +14,40 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests; -using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.NamingStyles; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; -namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.GenerateTypeTests +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.GenerateTypeTests; + +[Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] +public partial class GenerateTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest { - [Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)] - public partial class GenerateTypeTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + public GenerateTypeTests(ITestOutputHelper logger) + : base(logger) { - public GenerateTypeTests(ITestOutputHelper logger) - : base(logger) - { - } + } - internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) - => (null, new GenerateTypeCodeFixProvider()); + internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new GenerateTypeCodeFixProvider()); - protected override ImmutableArray MassageActions(ImmutableArray codeActions) - => FlattenActions(codeActions); + protected override ImmutableArray MassageActions(ImmutableArray codeActions) + => FlattenActions(codeActions); - // TODO: Requires WPF due to IInlineRenameService dependency (https://github.com/dotnet/roslyn/issues/46153) - protected override TestComposition GetComposition() - => EditorTestCompositions.EditorFeaturesWpf; + // TODO: Requires WPF due to IInlineRenameService dependency (https://github.com/dotnet/roslyn/issues/46153) + protected override TestComposition GetComposition() + => EditorTestCompositions.EditorFeaturesWpf; - #region Generate Class + #region Generate Class - #region Generics + #region Generics - [Fact] - public async Task TestGenerateTypeParameterFromArgumentInferT() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateTypeParameterFromArgumentInferT() + { + await TestInRegularAndScriptAsync( @"class Program { void Main() @@ -68,12 +67,12 @@ internal class Goo { }", index: 1); - } + } - [Fact] - public async Task TestGenerateClassFromTypeParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromTypeParameter() + { + await TestInRegularAndScriptAsync( @"class Class { System.Action<[|Employee|]> employees; @@ -87,12 +86,12 @@ private class Employee } }", index: 2); - } + } - [Fact] - public async Task TestGenerateInternalClassFromASingleConstraintClause() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInternalClassFromASingleConstraintClause() + { + await TestInRegularAndScriptAsync( @"class EmployeeList where T : [|Employee|], new() { }", @@ -104,12 +103,12 @@ internal class Employee { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGeneratePublicClassFromASingleConstraintClause() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGeneratePublicClassFromASingleConstraintClause() + { + await TestInRegularAndScriptAsync( @"public class EmployeeList where T : [|Employee|], new() { }", @@ -121,21 +120,21 @@ public class Employee { }", index: 1); - } + } - [Fact] - public async Task NegativeTestGenerateClassFromConstructorConstraint() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task NegativeTestGenerateClassFromConstructorConstraint() + { + await TestMissingInRegularAndScriptAsync( @"class EmployeeList where T : Employee, [|new()|] { }"); - } + } - [Fact] - public async Task TestGenerateInternalClassFromMultipleTypeConstraintClauses() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInternalClassFromMultipleTypeConstraintClauses() + { + await TestInRegularAndScriptAsync( @"class Derived where U : struct where T : [|Base|], new() @@ -151,12 +150,12 @@ internal class Base { }", index: 1); - } + } - [Fact] - public async Task TestGeneratePublicClassFromMultipleTypeConstraintClauses() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGeneratePublicClassFromMultipleTypeConstraintClauses() + { + await TestInRegularAndScriptAsync( @"public class Derived where U : struct where T : [|Base|], new() @@ -172,34 +171,34 @@ public class Base { }", index: 1); - } + } - [Fact] - public async Task NegativeTestGenerateClassFromClassOrStructConstraint() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task NegativeTestGenerateClassFromClassOrStructConstraint() + { + await TestMissingInRegularAndScriptAsync( @"class Derived where U : [|struct|] where T : Base, new() { }"); - } + } - [Fact] - public async Task TestAbsenceOfGenerateIntoInvokingTypeForConstraintList() - { - await TestActionCountAsync( + [Fact] + public async Task TestAbsenceOfGenerateIntoInvokingTypeForConstraintList() + { + await TestActionCountAsync( @"class EmployeeList where T : [|Employee|] { }", count: 3, parameters: new TestParameters(Options.Regular)); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClauseInterface() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClauseInterface() + { + await TestInRegularAndScriptAsync( @"interface IEmployeeList where T : [|Employee|], new() { }", @@ -211,12 +210,12 @@ internal class Employee { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGeneratePublicClassFromASingleConstraintClausePublicInterface() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGeneratePublicClassFromASingleConstraintClausePublicInterface() + { + await TestInRegularAndScriptAsync( @"public interface IEmployeeList where T : [|Employee|], new() { }", @@ -228,12 +227,12 @@ public class Employee { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClauseInternalDelegate() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClauseInternalDelegate() + { + await TestInRegularAndScriptAsync( @"class Employee { internal delegate void Action() where T : [|Command|]; @@ -247,12 +246,12 @@ internal class Command { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClausePublicDelegate() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClausePublicDelegate() + { + await TestInRegularAndScriptAsync( @"class Employee { public delegate void Action() where T : [|Command|]; @@ -266,12 +265,12 @@ internal class Command { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClauseInternalMethod() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClauseInternalMethod() + { + await TestInRegularAndScriptAsync( @"class Employee { internal void Action() where T : [|Command|] {} @@ -285,12 +284,12 @@ internal class Command { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClausePublicMethod() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClausePublicMethod() + { + await TestInRegularAndScriptAsync( @"class Employee { public void Action() where T : [|Command|] {} @@ -304,12 +303,12 @@ internal class Command { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClauseMethod() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClauseMethod() + { + await TestInRegularAndScriptAsync( @"class Employee { void Action() where T : [|Command|] {} @@ -323,12 +322,12 @@ internal class Command { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - public async Task TestGenerateInternalClassFromASingleConstraintClauseMethodInInterface() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + public async Task TestGenerateInternalClassFromASingleConstraintClauseMethodInInterface() + { + await TestInRegularAndScriptAsync( @"interface Employee { void Action() where T : [|Command|] {} @@ -342,20 +341,20 @@ internal class Command { }", index: 1); - } + } - [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] - [InlineData("public", "internal", "internal")] - [InlineData("public", "private", "internal")] - [InlineData("internal", "protected", "internal")] - [InlineData("public", "protected internal", "public")] - [InlineData("protected", "protected", "public")] - [InlineData("protected internal", "protected", "public")] - [InlineData("protected", "protected private", "internal")] - [InlineData("protected private", "protected", "internal")] - public async Task TestGenerateInternalClassFromASingleConstraintClauseNestedClass(string middleAccessibility, string accessibility, string generatedAccessibility) - { - await TestInRegularAndScriptAsync( + [Theory, WorkItem("https://github.com/dotnet/roslyn/issues/18240")] + [InlineData("public", "internal", "internal")] + [InlineData("public", "private", "internal")] + [InlineData("internal", "protected", "internal")] + [InlineData("public", "protected internal", "public")] + [InlineData("protected", "protected", "public")] + [InlineData("protected internal", "protected", "public")] + [InlineData("protected", "protected private", "internal")] + [InlineData("protected private", "protected", "internal")] + public async Task TestGenerateInternalClassFromASingleConstraintClauseNestedClass(string middleAccessibility, string accessibility, string generatedAccessibility) + { + await TestInRegularAndScriptAsync( $@"public class A {{ {middleAccessibility} class B @@ -381,16 +380,16 @@ await TestInRegularAndScriptAsync( {{ }}", index: 1); - } + } - #endregion + #endregion - #region Lambdas + #region Lambdas - [Fact] - public async Task TestGenerateClassFromParenthesizedLambdaExpressionsParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromParenthesizedLambdaExpressionsParameter() + { + await TestInRegularAndScriptAsync( @"class Class { Func l = ([|Employee|] e, int age) => e.Age > age; @@ -404,12 +403,12 @@ private class Employee } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromParenthesizedLambdaExpressionsBody() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromParenthesizedLambdaExpressionsBody() + { + await TestInRegularAndScriptAsync( @"class Class { System.Action l = (Class e, int age) => { @@ -427,14 +426,14 @@ private class Wage } }", index: 2); - } + } - #endregion + #endregion - [Fact] - public async Task TestGenerateClassFromFieldDeclarationIntoSameType() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromFieldDeclarationIntoSameType() + { + await TestInRegularAndScriptAsync( @"class Class { [|Goo|] f; @@ -448,12 +447,12 @@ private class Goo } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromNullableFieldDeclarationIntoSameType() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromNullableFieldDeclarationIntoSameType() + { + await TestInRegularAndScriptAsync( @"#nullable enable class Class { @@ -469,24 +468,24 @@ private class Goo } }", index: 2); - } + } - [WpfFact] - public async Task TestGenerateClassFromFieldDeclarationIntoGlobalNamespace() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact] + public async Task TestGenerateClassFromFieldDeclarationIntoGlobalNamespace() + { + await TestAddDocumentInRegularAndScriptAsync( @"class Program { void Main ( ) { [|Goo|] f ; } } ", @"internal class Goo { }", expectedContainers: ImmutableArray.Empty, expectedDocumentName: "Goo.cs"); - } + } - [WpfFact] - public async Task TestGenerateClassFromFieldDeclarationIntoCustomNamespace() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact] + public async Task TestGenerateClassFromFieldDeclarationIntoCustomNamespace() + { + await TestAddDocumentInRegularAndScriptAsync( @"class Class { [|TestNamespace|].Goo f; }", @"namespace TestNamespace { @@ -496,12 +495,12 @@ internal class Goo }", expectedContainers: ImmutableArray.Create("TestNamespace"), expectedDocumentName: "Goo.cs"); - } + } - [Fact] - public async Task TestGenerateClassFromFieldDeclarationIntoSameNamespace() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromFieldDeclarationIntoSameNamespace() + { + await TestInRegularAndScriptAsync( @"class Class { [|Goo|] f; @@ -515,12 +514,12 @@ internal class Goo { }", index: 1); - } + } - [Fact] - public async Task TestGenerateClassWithCtorFromObjectCreation() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassWithCtorFromObjectCreation() + { + await TestInRegularAndScriptAsync( @"class Class { Goo f = new [|Goo|](); @@ -537,12 +536,12 @@ public Goo() } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassWithCtorFromObjectCreationWithTuple() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassWithCtorFromObjectCreationWithTuple() + { + await TestInRegularAndScriptAsync( @"class Class { var f = new [|Generated|]((1, 2)); @@ -562,12 +561,12 @@ public Generated((int, int) value) } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassWithCtorFromObjectCreationWithTupleWithNames() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassWithCtorFromObjectCreationWithTupleWithNames() + { + await TestInRegularAndScriptAsync( @"class Class { var f = new [|Generated|]((a: 1, b: 2, 3)); @@ -587,12 +586,12 @@ public Generated((int a, int b, int) value) } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromBaseList() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromBaseList() + { + await TestInRegularAndScriptAsync( @"class Class : [|BaseClass|] { }", @@ -604,12 +603,12 @@ internal class BaseClass { }", index: 1); - } + } - [Fact] - public async Task TestGenerateClassFromMethodParameters() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromMethodParameters() + { + await TestInRegularAndScriptAsync( @"class Class { void Method([|Goo|] f) @@ -627,12 +626,12 @@ private class Goo } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromMethodReturnType() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromMethodReturnType() + { + await TestInRegularAndScriptAsync( @"class Class { [|Goo|] Method() @@ -650,12 +649,12 @@ private class Goo } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromAttribute() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromAttribute() + { + await TestInRegularAndScriptAsync( @"class Class { [[|Obsolete|]] @@ -677,12 +676,12 @@ private class ObsoleteAttribute : Attribute } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromExpandedAttribute() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromExpandedAttribute() + { + await TestInRegularAndScriptAsync( @"class Class { [[|ObsoleteAttribute|]] @@ -704,12 +703,12 @@ private class ObsoleteAttribute : Attribute } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromCatchClause() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromCatchClause() + { + await TestInRegularAndScriptAsync( @"class Class { void Method() @@ -758,12 +757,12 @@ protected ExType(SerializationInfo info, StreamingContext context) : base(info, } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromThrowStatement() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromThrowStatement() + { + await TestInRegularAndScriptAsync( @"class Class { void Method() @@ -802,12 +801,12 @@ protected ExType(SerializationInfo info, StreamingContext context) : base(info, } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromThrowStatementWithDifferentArg() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromThrowStatementWithDifferentArg() + { + await TestInRegularAndScriptAsync( @"class Class { void Method() @@ -853,12 +852,12 @@ protected ExType(SerializationInfo info, StreamingContext context) : base(info, } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromThrowStatementWithMatchingArg() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromThrowStatementWithMatchingArg() + { + await TestInRegularAndScriptAsync( @"class Class { void Method() @@ -897,71 +896,71 @@ protected ExType(SerializationInfo info, StreamingContext context) : base(info, } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromThrowStatementOnModernDotNet_NoObsoleteConstructor() - { - var source = """ - class Class + [Fact] + public async Task TestGenerateClassFromThrowStatementOnModernDotNet_NoObsoleteConstructor() + { + var source = """ + class Class + { + void Method() { - void Method() - { - throw new [|ExType|](); - } + throw new [|ExType|](); + } + } + """; + + await TestInRegularAndScriptAsync($""" + + + {source} + + + """, """ + using System; + + class Class + { + void Method() + { + throw new ExType(); } - """; - - await TestInRegularAndScriptAsync($""" - - - {source} - - - """, """ - using System; - class Class + [Serializable] + private class ExType : Exception { - void Method() + public ExType() { - throw new ExType(); } - [Serializable] - private class ExType : Exception + public ExType(string message) : base(message) { - public ExType() - { - } - - public ExType(string message) : base(message) - { - } + } - public ExType(string message, Exception innerException) : base(message, innerException) - { - } + public ExType(string message, Exception innerException) : base(message, innerException) + { } } - """, index: 2); - } + } + """, index: 2); + } - [Fact] - public async Task TestAbsenceOfGenerateIntoInvokingTypeForBaseList() - { - await TestActionCountAsync( + [Fact] + public async Task TestAbsenceOfGenerateIntoInvokingTypeForBaseList() + { + await TestActionCountAsync( @"class Class : [|BaseClass|] { }", count: 3, parameters: new TestParameters(Options.Regular)); - } + } - [Fact] - public async Task TestGenerateClassFromUsingStatement() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromUsingStatement() + { + await TestInRegularAndScriptAsync( @"class Class { void Method() @@ -985,12 +984,12 @@ private class Goo } }", index: 2); - } + } - [Fact] - public async Task TestGenerateClassFromForeachStatement() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateClassFromForeachStatement() + { + await TestInRegularAndScriptAsync( @"class Class { void Method() @@ -1014,12 +1013,12 @@ private class Employee } }", index: 2); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538346")] - public async Task TestGenerateClassWhereKeywordBecomesTypeName() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538346")] + public async Task TestGenerateClassWhereKeywordBecomesTypeName() + { + await TestInRegularAndScriptAsync( @"class Class { [|@class|] c; @@ -1033,12 +1032,12 @@ private class @class } }", index: 2); - } + } - [Fact] - public async Task NegativeTestGenerateClassOnContextualKeyword() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task NegativeTestGenerateClassOnContextualKeyword() + { + await TestInRegularAndScriptAsync( @"class Class { [|@Goo|] c; @@ -1052,12 +1051,12 @@ private class Goo } }", index: 2); - } + } - [Fact] - public async Task NegativeTestGenerateClassOnFrameworkTypes() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task NegativeTestGenerateClassOnFrameworkTypes() + { + await TestMissingInRegularAndScriptAsync( @"class Class { void Method() @@ -1066,7 +1065,7 @@ void Method() } }"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"class Class { void Method() @@ -1075,7 +1074,7 @@ void Method() } }"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"class Class { void Method() @@ -1083,12 +1082,12 @@ void Method() System.Console.[|Write|](5); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538409")] - public async Task GenerateIntoRightPart() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538409")] + public async Task GenerateIntoRightPart() + { + await TestInRegularAndScriptAsync( @"partial class Class { } @@ -1110,12 +1109,12 @@ private class C } }", index: 2); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538408")] - public async Task GenerateTypeIntoCompilationUnit() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538408")] + public async Task GenerateTypeIntoCompilationUnit() + { + await TestInRegularAndScriptAsync( @"class Class { [|C|] c; @@ -1137,12 +1136,12 @@ internal class C { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538408")] - public async Task GenerateTypeIntoNamespace() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538408")] + public async Task GenerateTypeIntoNamespace() + { + await TestInRegularAndScriptAsync( @"namespace N { class Class @@ -1170,12 +1169,12 @@ internal class C } }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538115")] - public async Task GenerateTypeWithPreprocessor() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538115")] + public async Task GenerateTypeWithPreprocessor() + { + await TestInRegularAndScriptAsync( @"class C { #if true @@ -1195,12 +1194,12 @@ private class A #endif }", index: 2); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538495")] - public async Task GenerateTypeIntoContainingNamespace() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538495")] + public async Task GenerateTypeIntoContainingNamespace() + { + await TestInRegularAndScriptAsync( @"namespace N { class Class @@ -1220,12 +1219,12 @@ internal class C } }", index: 1); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538516")] - public async Task TestGenerateClassFromIntoNewNamespace() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538516")] + public async Task TestGenerateClassFromIntoNewNamespace() + { + await TestAddDocumentInRegularAndScriptAsync( @"class Class { static void Main(string[] args) { [|N|].C c; } }", @"namespace N { @@ -1235,12 +1234,12 @@ internal class C }", expectedContainers: ImmutableArray.Create("N"), expectedDocumentName: "C.cs"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538558")] - public async Task NegativeTestGlobalAlias() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538558")] + public async Task NegativeTestGlobalAlias() + { + await TestMissingInRegularAndScriptAsync( @"class Class { void Method() @@ -1249,7 +1248,7 @@ void Method() } }"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"class Class { void Method() @@ -1257,12 +1256,12 @@ void Method() global::[|System|].String s; } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538069")] - public async Task GenerateTypeFromArrayCreation1() - { - await TestAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538069")] + public async Task GenerateTypeFromArrayCreation1() + { + await TestAsync( @"class A { void Goo() @@ -1283,12 +1282,12 @@ internal class C : A }", index: 1, parseOptions: null); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538069")] - public async Task GenerateTypeFromArrayCreation2() - { - await TestAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538069")] + public async Task GenerateTypeFromArrayCreation2() + { + await TestAsync( @"class A { void Goo() @@ -1309,12 +1308,12 @@ internal class C : A }", index: 1, parseOptions: null); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538069")] - public async Task GenerateTypeFromArrayCreation3() - { - await TestAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538069")] + public async Task GenerateTypeFromArrayCreation3() + { + await TestAsync( @"class A { void Goo() @@ -1335,31 +1334,31 @@ internal class C }", index: 1, parseOptions: null); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539329")] - public async Task NegativeTestNotInUsingDirective() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539329")] + public async Task NegativeTestNotInUsingDirective() + { + await TestMissingInRegularAndScriptAsync( @"using [|A|];"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"using [|A.B|];"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"using [|A|].B;"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"using A.[|B|];"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"using X = [|A|];"); - } + } - [Fact] - public async Task GenerateSimpleConstructor() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateSimpleConstructor() + { + await TestInRegularAndScriptAsync( @"class Class { void M() @@ -1382,12 +1381,12 @@ public T() } }", index: 1); - } + } - [Fact] - public async Task GenerateWithValueParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithValueParameter() + { + await TestInRegularAndScriptAsync( @"class Class { void M() @@ -1413,12 +1412,12 @@ public T(int v) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithTwoValueParameters() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithTwoValueParameters() + { + await TestInRegularAndScriptAsync( @"class Class { void M() @@ -1446,12 +1445,12 @@ public T(int v1, string v2) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithNullableParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNullableParameter() + { + await TestInRegularAndScriptAsync( @"#nullable enable class Class { @@ -1481,12 +1480,12 @@ public T(string? s) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithNullableParameterThatIsNotNull() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNullableParameterThatIsNotNull() + { + await TestInRegularAndScriptAsync( @"#nullable enable class Class { @@ -1516,12 +1515,12 @@ public T(string s) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithNamedParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNamedParameter() + { + await TestInRegularAndScriptAsync( @"class Class { void M() @@ -1547,12 +1546,12 @@ public T(int arg) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithRefParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithRefParameter() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -1578,12 +1577,12 @@ public T(ref int i) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameter() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameter() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i, bool b) @@ -1612,12 +1611,12 @@ public T(out int i, ref bool b, object value) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters1() + { + await TestInRegularAndScriptAsync( @"class Class { void M(string s) @@ -1641,12 +1640,12 @@ public T(out string s) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters2_CSharp7() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters2_CSharp7() + { + await TestInRegularAndScriptAsync( @"using System; class Class @@ -1675,12 +1674,12 @@ public T(out DateTime d) }", index: 1, parseOptions: TestOptions.Regular7); - } + } - [Fact] - public async Task GenerateWithOutParameters2() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters2() + { + await TestInRegularAndScriptAsync( @"using System; class Class @@ -1708,12 +1707,12 @@ public T(out DateTime d) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters3() + { + await TestInRegularAndScriptAsync( @"using System.Collections.Generic; class Class @@ -1741,12 +1740,12 @@ public T(out IList d) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters4() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters4() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int? d) @@ -1770,12 +1769,12 @@ public T(out int? d) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters5() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters5() + { + await TestInRegularAndScriptAsync( @"class Class { void M(X d) @@ -1799,12 +1798,12 @@ public T(out object d) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters6_CSharp7() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters6_CSharp7() + { + await TestInRegularAndScriptAsync( @"class Class { void M(X d) @@ -1829,12 +1828,12 @@ public T(out X d) }", index: 2, parseOptions: TestOptions.Regular7); - } + } - [Fact] - public async Task GenerateWithOutParameters6() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters6() + { + await TestInRegularAndScriptAsync( @"class Class { void M(X d) @@ -1858,12 +1857,12 @@ public T(out X d) } }", index: 2); - } + } - [Fact] - public async Task GenerateWithOutParameters7() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters7() + { + await TestInRegularAndScriptAsync( @"class Class where X : class { void M(X d) @@ -1887,12 +1886,12 @@ public T(out object d) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithOutParameters8() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithOutParameters8() + { + await TestInRegularAndScriptAsync( @"class Class where X : class { void M(X d) @@ -1916,12 +1915,12 @@ public T(out X d) } }", index: 2); - } + } - [Fact] - public async Task GenerateWithMethod() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithMethod() + { + await TestInRegularAndScriptAsync( @"class Class { string M(int i) @@ -1949,12 +1948,12 @@ public T(Func m) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithLambda() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithLambda() + { + await TestInRegularAndScriptAsync( @"class Class { string M(int i) @@ -1982,12 +1981,12 @@ public T(Func value) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructor1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructor1() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2024,12 +2023,12 @@ protected Base(int i) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructor2() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructor2() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2066,12 +2065,12 @@ protected Base(object i) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructor3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructor3() + { + await TestInRegularAndScriptAsync( @"using System.Collections.Generic; class Class @@ -2112,12 +2111,12 @@ protected Base(IEnumerable values) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructor4() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructor4() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2154,12 +2153,12 @@ protected Base(ref int o) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructor5() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructor5() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2198,12 +2197,12 @@ protected Base(System.Func f) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructor6() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructor6() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2240,12 +2239,12 @@ protected Base(out int o) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithDelegatingConstructorAssigningToNullableField() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithDelegatingConstructorAssigningToNullableField() + { + await TestInRegularAndScriptAsync( @"#nullable enable class Class { @@ -2275,12 +2274,12 @@ class Base { }", index: 1); - } + } - [Fact] - public async Task GenerateWithNonDelegatingConstructor1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNonDelegatingConstructor1() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2320,12 +2319,12 @@ protected Base(string i) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithNonDelegatingConstructor2() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNonDelegatingConstructor2() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2365,12 +2364,12 @@ protected Base(out int o) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithNonDelegatingConstructor3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNonDelegatingConstructor3() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i, bool f) @@ -2409,12 +2408,12 @@ protected Base(ref int o, out bool b) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithNonDelegatingConstructor4() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithNonDelegatingConstructor4() + { + await TestInRegularAndScriptAsync( @"class Class { void M() @@ -2454,12 +2453,12 @@ private Base(int i) } }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField1() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2493,12 +2492,12 @@ class Base protected int i; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField2() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField2() + { + await TestInRegularAndScriptAsync( @"class Class { void M(string i) @@ -2532,12 +2531,12 @@ class Base protected object i; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField3() + { + await TestInRegularAndScriptAsync( @"class Class { void M(string i) @@ -2573,12 +2572,12 @@ class Base protected bool i; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField4() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField4() + { + await TestInRegularAndScriptAsync( @"class Class { void M(bool i) @@ -2614,12 +2613,12 @@ class Base protected bool ii; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField5() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField5() + { + await TestInRegularAndScriptAsync( @"class Class { void M(bool i) @@ -2655,12 +2654,12 @@ class Base private bool i; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField6() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField6() + { + await TestInRegularAndScriptAsync( @"class Class { void M(bool i) @@ -2696,12 +2695,12 @@ class Base protected readonly bool i; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField7() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField7() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2735,12 +2734,12 @@ class Base protected int I; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField7WithQualification() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField7WithQualification() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2775,12 +2774,12 @@ class Base }", index: 1, options: Option(CodeStyleOptions2.QualifyFieldAccess, true, NotificationOption2.Error)); - } + } - [Fact] - public async Task GenerateWithCallToField8() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField8() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2816,12 +2815,12 @@ class Base private int I; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField9() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField9() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2857,12 +2856,12 @@ class Base public static int i; }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToField10() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToField10() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2904,22 +2903,22 @@ class B { protected int i }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49924")] - public async Task GenerateCorrectFieldNaming() - { - var options = new NamingStylesTestOptionSets(LanguageNames.CSharp); + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/49924")] + public async Task GenerateCorrectFieldNaming() + { + var options = new NamingStylesTestOptionSets(LanguageNames.CSharp); - await TestInRegularAndScriptAsync( - @"class Class + await TestInRegularAndScriptAsync( +@"class Class { void M(int i) { D d = new [|D|](i); } }", - @"class Class +@"class Class { void M(int i) { @@ -2936,13 +2935,13 @@ public D(int i) _i = i; } }", - index: 1, options: options.FieldNamesAreCamelCaseWithUnderscorePrefix); - } +index: 1, options: options.FieldNamesAreCamelCaseWithUnderscorePrefix); + } - [Fact] - public async Task GenerateWithCallToProperty1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToProperty1() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -2978,12 +2977,12 @@ class Base public int I { get; private set; } }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToProperty2() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToProperty2() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3017,12 +3016,12 @@ class Base public int I { get; protected set; } }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToProperty2WithQualification() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToProperty2WithQualification() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3057,12 +3056,12 @@ class Base }", index: 1, options: Option(CodeStyleOptions2.QualifyPropertyAccess, true, NotificationOption2.Error)); - } + } - [Fact] - public async Task GenerateWithCallToProperty3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToProperty3() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3096,12 +3095,12 @@ class Base protected int I { get; set; } }", index: 1); - } + } - [Fact] - public async Task GenerateWithCallToProperty3WithQualification() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task GenerateWithCallToProperty3WithQualification() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3136,12 +3135,12 @@ class Base }", index: 1, options: Option(CodeStyleOptions2.QualifyPropertyAccess, true, NotificationOption2.Error)); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/942568")] - public async Task GenerateTypeWithPreferIntrinsicPredefinedKeywordFalse() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/942568")] + public async Task GenerateTypeWithPreferIntrinsicPredefinedKeywordFalse() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) { @@ -3166,16 +3165,16 @@ public T(System.Int32 i) }", index: 1, options: Option(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInDeclaration, false, NotificationOption2.Error)); - } + } - #endregion + #endregion - #region Generate Interface + #region Generate Interface - [Fact] - public async Task TestGenerateInterfaceFromTypeConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInterfaceFromTypeConstraint() + { + await TestInRegularAndScriptAsync( @"class EmployeeList where T : Employee, [|IEmployee|], new() { }", @@ -3187,12 +3186,12 @@ internal interface IEmployee { }", index: 1); - } + } - [Fact] - public async Task TestGenerateInterfaceFromTypeConstraints() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInterfaceFromTypeConstraints() + { + await TestInRegularAndScriptAsync( @"class EmployeeList where T : Employee, IEmployee, [|IComparable|], new() { }", @@ -3204,23 +3203,23 @@ await TestInRegularAndScriptAsync( { }", index: 1); - } + } - [Fact] - public async Task NegativeTestGenerateInterfaceFromTypeConstraint() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task NegativeTestGenerateInterfaceFromTypeConstraint() + { + await TestMissingInRegularAndScriptAsync( @"using System; class EmployeeList where T : Employee, IEmployee, [|IComparable|], new() { }"); - } + } - [Fact] - public async Task TestGenerateInterfaceFromBaseList1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInterfaceFromBaseList1() + { + await TestInRegularAndScriptAsync( @"interface A : [|B|] { }", @@ -3232,12 +3231,12 @@ internal interface B { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538519")] - public async Task TestGenerateInterfaceFromBaseList2() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538519")] + public async Task TestGenerateInterfaceFromBaseList2() + { + await TestInRegularAndScriptAsync( @"class Test : [|ITest|] { }", @@ -3249,12 +3248,12 @@ internal interface ITest { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538519")] - public async Task TestGenerateInterfaceFromTypeConstraints2() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538519")] + public async Task TestGenerateInterfaceFromTypeConstraints2() + { + await TestInRegularAndScriptAsync( @"class Test where T : [|ITest|] { }", @@ -3266,12 +3265,12 @@ internal interface ITest { }", index: 1); - } + } - [Fact] - public async Task TestGenerateInterfaceFromBaseList3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInterfaceFromBaseList3() + { + await TestInRegularAndScriptAsync( @"class A : object, [|B|] { }", @@ -3283,14 +3282,14 @@ internal interface B { }", index: 1); - } + } - #endregion + #endregion - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] - public async Task NotInLeftSideOfAssignment() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] + public async Task NotInLeftSideOfAssignment() + { + await TestMissingInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3298,12 +3297,12 @@ void M(int i) [|Goo|] = 2; } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] - public async Task InLeftSideOfAssignment() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] + public async Task InLeftSideOfAssignment() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3323,12 +3322,12 @@ internal class Goo { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] - public async Task NotInRightSideOfAssignment() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] + public async Task NotInRightSideOfAssignment() + { + await TestMissingInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3336,12 +3335,12 @@ void M(int i) x = [|Goo|]; } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] - public async Task InRightSideOfAssignment() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539339")] + public async Task InRightSideOfAssignment() + { + await TestInRegularAndScriptAsync( @"class Class { void M(int i) @@ -3361,12 +3360,12 @@ internal class Goo { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539489")] - public async Task TestEscapedName() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539489")] + public async Task TestEscapedName() + { + await TestInRegularAndScriptAsync( @"class Class { [|@Goo|] f; @@ -3380,12 +3379,12 @@ internal class Goo { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539489")] - public async Task TestEscapedKeyword() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539489")] + public async Task TestEscapedKeyword() + { + await TestInRegularAndScriptAsync( @"class Class { [|@int|] f; @@ -3399,12 +3398,12 @@ internal class @int { }", index: 1); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539535")] - public async Task TestGenerateIntoNewFile() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539535")] + public async Task TestGenerateIntoNewFile() + { + await TestAddDocumentInRegularAndScriptAsync( @"class Class { void F() { new [|Goo|].Bar(); } }", @"namespace Goo { @@ -3417,12 +3416,12 @@ public Bar() }", expectedContainers: ImmutableArray.Create("Goo"), expectedDocumentName: "Bar.cs"); - } + } - [WpfFact] - public async Task TestGenerateIntoNewFileWithUsings1() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact] + public async Task TestGenerateIntoNewFileWithUsings1() + { + await TestAddDocumentInRegularAndScriptAsync( @"class Class { void F() { new [|Goo|].Bar(new System.Collections.Generic.List()); } }", @"using System.Collections.Generic; @@ -3440,12 +3439,12 @@ public Bar(List list) }", expectedContainers: ImmutableArray.Create("Goo"), expectedDocumentName: "Bar.cs"); - } + } - [WpfFact] - public async Task TestGenerateIntoNewFileWithUsings2() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact] + public async Task TestGenerateIntoNewFileWithUsings2() + { + await TestAddDocumentInRegularAndScriptAsync( @"class Class { void F() { new [|Goo|].Bar(new System.Collections.Generic.List()); } }", @"namespace Goo { @@ -3464,12 +3463,12 @@ public Bar(List list) expectedContainers: ImmutableArray.Create("Goo"), expectedDocumentName: "Bar.cs", parameters: new TestParameters(options: Option(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, AddImportPlacement.InsideNamespace, NotificationOption2.Error))); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539620")] - public async Task TestDeclarationSpan() - { - await TestSpansAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539620")] + public async Task TestDeclarationSpan() + { + await TestSpansAsync( @"class Class { void Goo() @@ -3477,21 +3476,21 @@ void Goo() [|Bar|] b; } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539674")] - public async Task TestNotInEnumBaseList() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539674")] + public async Task TestNotInEnumBaseList() + { + await TestMissingInRegularAndScriptAsync( @"enum E : [|A|] { }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539681")] - public async Task TestNotInConditional() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539681")] + public async Task TestNotInConditional() + { + await TestMissingInRegularAndScriptAsync( @"class Program { static void Main(string[] args) @@ -3501,12 +3500,12 @@ static void Main(string[] args) } } }"); - } + } - [Fact] - public async Task TestInUsing() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestInUsing() + { + await TestInRegularAndScriptAsync( @"using System; using System.Collections.Generic; using System.Linq; @@ -3538,12 +3537,12 @@ internal class Goo { }", index: 1); - } + } - [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/54493")] - public async Task TestInLocalFunction() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("https://github.com/dotnet/roslyn/pull/54493")] + public async Task TestInLocalFunction() + { + await TestInRegularAndScriptAsync( @"using System; class Program @@ -3567,12 +3566,12 @@ internal class Goo { }", index: 1); - } + } - [Fact] - public async Task TestNotInDelegateConstructor() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestNotInDelegateConstructor() + { + await TestMissingInRegularAndScriptAsync( @"delegate void D(int x); class C @@ -3582,12 +3581,12 @@ void M() D d = new D([|Test|]); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539754")] - public async Task TestMissingOnVar() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539754")] + public async Task TestMissingOnVar() + { + await TestMissingInRegularAndScriptAsync( @"using System; using System.Collections.Generic; using System.Linq; @@ -3599,12 +3598,12 @@ static void Main(string[] args) [|var|] x = new Program(); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539765")] - public async Task TestElideDefaultConstructor() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539765")] + public async Task TestElideDefaultConstructor() + { + await TestInRegularAndScriptAsync( @"class A { void M() @@ -3632,20 +3631,20 @@ internal class C { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539783")] - public async Task RegressionFor5867ErrorToleranceTopLevel() - { - await TestMissingAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539783")] + public async Task RegressionFor5867ErrorToleranceTopLevel() + { + await TestMissingAsync( @"[|this|] . f = f ; ", new TestParameters(GetScriptOptions())); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539799")] - public async Task TestOnInaccessibleType() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539799")] + public async Task TestOnInaccessibleType() + { + await TestMissingInRegularAndScriptAsync( @"class C { private class D @@ -3660,12 +3659,12 @@ void M() C.[|D|] d = new C.D(); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539794")] - public async Task TestDefaultConstructorInTypeDerivingFromInterface() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539794")] + public async Task TestDefaultConstructorInTypeDerivingFromInterface() + { + await TestInRegularAndScriptAsync( @"class Program { static void Main(string[] args) @@ -3693,12 +3692,12 @@ interface I { }", index: 1); - } + } - [Fact] - public async Task TestGenerateWithThrow() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateWithThrow() + { + await TestInRegularAndScriptAsync( @"using System; class C @@ -3739,12 +3738,12 @@ protected NotFoundException(SerializationInfo info, StreamingContext context) : } }", index: 1); - } + } - [Fact] - public async Task TestGenerateInTryCatch() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestGenerateInTryCatch() + { + await TestInRegularAndScriptAsync( @"using System; class C @@ -3795,13 +3794,13 @@ protected NotFoundException(SerializationInfo info, StreamingContext context) : } }", index: 1); - } + } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] - [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539739")] - public async Task TestNotGenerateInDelegateConstructor() - { - await TestMissingInRegularAndScriptAsync( + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] + [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539739")] + public async Task TestNotGenerateInDelegateConstructor() + { + await TestMissingInRegularAndScriptAsync( @"using System; delegate void D(int x); @@ -3813,12 +3812,12 @@ void M() D d = new D([|Test|]); } }"); - } + } - [Fact] - public async Task TestInStructBaseList() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestInStructBaseList() + { + await TestInRegularAndScriptAsync( @"struct S : [|A|] { }", @@ -3830,12 +3829,12 @@ internal interface A { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539870")] - public async Task TestGenericWhenNonGenericExists() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539870")] + public async Task TestGenericWhenNonGenericExists() + { + await TestInRegularAndScriptAsync( @"class C { void Goo() @@ -3863,12 +3862,12 @@ class A { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539930")] - public async Task TestInheritedTypeParameters() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539930")] + public async Task TestInheritedTypeParameters() + { + await TestInRegularAndScriptAsync( @"class C { void M() @@ -3896,12 +3895,12 @@ interface I { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539971")] - public async Task TestDoNotUseOuterTypeParameters() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539971")] + public async Task TestDoNotUseOuterTypeParameters() + { + await TestInRegularAndScriptAsync( @"class C { public void Goo() @@ -3921,12 +3920,12 @@ private class D } }", index: 2); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539970")] - public async Task TestReferencingTypeParameters1() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539970")] + public async Task TestReferencingTypeParameters1() + { + await TestInRegularAndScriptAsync( @"class M { public void Goo() @@ -3954,12 +3953,12 @@ interface I { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539970")] - public async Task TestReferencingTypeParameters2() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539970")] + public async Task TestReferencingTypeParameters2() + { + await TestInRegularAndScriptAsync( @"class M { public void Goo() @@ -3987,12 +3986,12 @@ interface I { }", index: 2); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539972")] - public async Task TestReferencingTypeParameters3() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539972")] + public async Task TestReferencingTypeParameters3() + { + await TestInRegularAndScriptAsync( @"class C { public void Goo(T1 t1, T2 t2) @@ -4020,12 +4019,12 @@ public A(object t1, object t2) } }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539972")] - public async Task TestReferencingTypeParameters4() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539972")] + public async Task TestReferencingTypeParameters4() + { + await TestInRegularAndScriptAsync( @"class C { public void Goo(T1 t1, T2 t2) @@ -4053,12 +4052,12 @@ public A(T1 t1, T2 t2) } }", index: 2); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539992")] - public async Task TestNotPassingEmptyIssueListToCtor() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539992")] + public async Task TestNotPassingEmptyIssueListToCtor() + { + await TestMissingInRegularAndScriptAsync( @"using System.Linq; class Program @@ -4067,12 +4066,12 @@ void Main() { Enumerable.[|T|] Enumerable . Select(Enumerable.Range(0, 9), i => char.Parse(i.ToString())) } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540644")] - public async Task TestGenerateWithVoidArg() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540644")] + public async Task TestGenerateWithVoidArg() + { + await TestInRegularAndScriptAsync( @"class Program { void M() @@ -4098,12 +4097,12 @@ public C(object v) } }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540989")] - public async Task TestMissingOnInaccessibleType() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540989")] + public async Task TestMissingOnInaccessibleType() + { + await TestMissingInRegularAndScriptAsync( @"class Outer { class Inner @@ -4115,23 +4114,23 @@ class A { Outer.[|Inner|] inner; }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540766")] - public async Task TestOnInvalidGlobalCode() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540766")] + public async Task TestOnInvalidGlobalCode() + { + await TestInRegularAndScriptAsync( @"[|a|] test ", @"[|a|] test internal class a { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539985")] - public async Task TestDoNotInferTypeWithWrongArity() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539985")] + public async Task TestDoNotInferTypeWithWrongArity() + { + await TestInRegularAndScriptAsync( @"class C { public void Test() @@ -4154,12 +4153,12 @@ public C() } }", index: 1); - } + } - [Fact] - public async Task TestMissingOnInvalidConstructorToExistingType() - { - await TestMissingInRegularAndScriptAsync( + [Fact] + public async Task TestMissingOnInvalidConstructorToExistingType() + { + await TestMissingInRegularAndScriptAsync( @"class Program { static void Main() @@ -4167,12 +4166,12 @@ static void Main() new [|Program|](1); } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541263")] - public async Task TestAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541263")] + public async Task TestAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public static class MyExtension { public static int ExtensionMethod(this String s, [|D|] d) @@ -4192,12 +4191,12 @@ public class D { }", index: 1); - } + } - [Fact] - public async Task TestBaseTypeAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestBaseTypeAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public class C : [|D|] { }", @@ -4209,12 +4208,12 @@ public class D { }", index: 1); - } + } - [Fact] - public async Task TestBaseInterfaceAccessibilityConstraint1() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestBaseInterfaceAccessibilityConstraint1() + { + await TestInRegularAndScriptAsync( @"public class C : X, [|IGoo|] { }", @@ -4226,12 +4225,12 @@ internal interface IGoo { }", index: 1); - } + } - [Fact] - public async Task TestAccessibilityConstraint2() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestAccessibilityConstraint2() + { + await TestInRegularAndScriptAsync( @"public interface C : [|IBar|], IGoo { }", @@ -4243,12 +4242,12 @@ public interface IBar { }", index: 1); - } + } - [Fact] - public async Task TestAccessibilityConstraint3() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestAccessibilityConstraint3() + { + await TestInRegularAndScriptAsync( @"public interface C : IBar, [|IGoo|] { }", @@ -4260,12 +4259,12 @@ public interface IGoo { }", index: 1); - } + } - [Fact] - public async Task TestDelegateReturnTypeAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestDelegateReturnTypeAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public delegate [|D|] Goo();", @"public delegate D Goo(); @@ -4273,12 +4272,12 @@ public class D { }", index: 1); - } + } - [Fact] - public async Task TestDelegateParameterAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestDelegateParameterAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public delegate D Goo([|S|] d);", @"public delegate D Goo(S d); @@ -4286,12 +4285,12 @@ public class S { }", index: 1); - } + } - [Fact] - public async Task TestMethodParameterAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestMethodParameterAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public class C { public void Goo([|F|] f); @@ -4305,12 +4304,12 @@ public class F { }", index: 1); - } + } - [Fact] - public async Task TestMethodReturnTypeAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestMethodReturnTypeAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public class C { public [|F|] Goo(Bar f); @@ -4324,12 +4323,12 @@ public class F } }", index: 2); - } + } - [Fact] - public async Task TestPropertyTypeAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestPropertyTypeAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public class C { public [|F|] Goo { get; } @@ -4343,12 +4342,12 @@ public class F } }", index: 2); - } + } - [Fact] - public async Task TestFieldEventTypeAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestFieldEventTypeAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public class C { public event [|F|] E; @@ -4362,12 +4361,12 @@ public class F } }", index: 2); - } + } - [Fact] - public async Task TestEventTypeAccessibilityConstraint() - { - await TestInRegularAndScriptAsync( + [Fact] + public async Task TestEventTypeAccessibilityConstraint() + { + await TestInRegularAndScriptAsync( @"public class C { public event [|F|] E @@ -4399,12 +4398,12 @@ public class F { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541654")] - public async Task TestGenerateVarType() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541654")] + public async Task TestGenerateVarType() + { + await TestInRegularAndScriptAsync( @"class C { public static void Main() @@ -4424,12 +4423,12 @@ internal class var { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541641")] - public async Task TestOnBadAttribute() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541641")] + public async Task TestOnBadAttribute() + { + await TestInRegularAndScriptAsync( @"[[|AttClass|]()] class C { @@ -4453,12 +4452,12 @@ internal class AttClassAttribute { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542528")] - public async Task TestGenerateStruct1() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542528")] + public async Task TestGenerateStruct1() + { + await TestInRegularAndScriptAsync( @"using System; class A where T : struct @@ -4490,12 +4489,12 @@ internal struct S { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542480")] - public async Task TestCopyConstraints1() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542480")] + public async Task TestCopyConstraints1() + { + await TestInRegularAndScriptAsync( @"class A where T : class { } @@ -4523,12 +4522,12 @@ internal class B : A where T : class { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542528")] - public async Task TestGenerateStruct2() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542528")] + public async Task TestGenerateStruct2() + { + await TestInRegularAndScriptAsync( @"using System; class A where T : struct @@ -4559,12 +4558,12 @@ private struct S { } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542528")] - public async Task TestGenerateStruct3() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542528")] + public async Task TestGenerateStruct3() + { + await TestInRegularAndScriptAsync( @"using System; class Program @@ -4595,12 +4594,12 @@ private struct S { } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542761")] - public async Task TestGenerateOpenType1() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542761")] + public async Task TestGenerateOpenType1() + { + await TestInRegularAndScriptAsync( @"class Program { static void Main() @@ -4620,12 +4619,12 @@ internal class C { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542766")] - public async Task TestGenerateAttributeInGenericType() - { - await TestActionCountAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542766")] + public async Task TestGenerateAttributeInGenericType() + { + await TestActionCountAsync( @"using System; class A @@ -4636,12 +4635,12 @@ void Goo() } }", count: 6); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543061")] - public async Task TestNestedGenericAccessibility() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543061")] + public async Task TestNestedGenericAccessibility() + { + await TestInRegularAndScriptAsync( @"using System.Collections.Generic; public class C @@ -4663,38 +4662,38 @@ public class NewClass { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543493")] - public async Task MissingIfNotInTypeStatementOrExpressionContext() - { - await TestMissingInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543493")] + public async Task MissingIfNotInTypeStatementOrExpressionContext() + { + await TestMissingInRegularAndScriptAsync( @"class C { void M() { a [|b|] c d } }"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"class C { void M() { a b [|c|] d } }"); - await TestMissingInRegularAndScriptAsync( + await TestMissingInRegularAndScriptAsync( @"class C { void M() { a b c [|d|] } }"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542641")] - public async Task TestAttributeSuffixOnAttributeSubclasses() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542641")] + public async Task TestAttributeSuffixOnAttributeSubclasses() + { + await TestInRegularAndScriptAsync( @"using System.Runtime.CompilerServices; class Program @@ -4718,32 +4717,32 @@ internal class GooAttribute : CustomConstantAttribute { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543853")] - public async Task TestDisplayStringForGlobalNamespace() - { - await TestSmartTagTextAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543853")] + public async Task TestDisplayStringForGlobalNamespace() + { + await TestSmartTagTextAsync( @"class C : [|Goo|]", string.Format(FeaturesResources.Generate_0_1_in_new_file, "class", "Goo")); - } + } - [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543853")] - public async Task TestAddDocumentForGlobalNamespace() - { - await TestAddDocumentInRegularAndScriptAsync( + [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543853")] + public async Task TestAddDocumentForGlobalNamespace() + { + await TestAddDocumentInRegularAndScriptAsync( @"class C : [|Goo|]", @"internal class Goo { }", ImmutableArray.Empty, "Goo.cs"); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543886")] - public async Task TestVerbatimAttribute() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543886")] + public async Task TestVerbatimAttribute() + { + await TestInRegularAndScriptAsync( @"[[|@X|]] class Class3 { @@ -4759,12 +4758,12 @@ internal class X : Attribute { }", index: 1); - } + } - [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531220")] - public async Task CompareIncompleteMembersToEqual() - { - await TestInRegularAndScriptAsync( + [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531220")] + public async Task CompareIncompleteMembersToEqual() + { + await TestInRegularAndScriptAsync( @"class C { X.X,X class X @@ -4788,12 +4787,12 @@ X void X